mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-10-04 19:56:30 +00:00
Add OpenMW commits up to 1 Sep 2018
# Conflicts: # apps/openmw/mwbase/world.hpp # apps/openmw/mwclass/creature.cpp # apps/openmw/mwclass/npc.cpp # apps/openmw/mwgui/jailscreen.cpp # apps/openmw/mwmechanics/actors.cpp # apps/openmw/mwmechanics/difficultyscaling.cpp # apps/openmw/mwscript/transformationextensions.cpp # apps/openmw/mwworld/worldimp.hpp
This commit is contained in:
commit
889bcec7f8
88 changed files with 873 additions and 670 deletions
|
@ -153,6 +153,7 @@ Programmers
|
||||||
Siimacore
|
Siimacore
|
||||||
sir_herrbatka
|
sir_herrbatka
|
||||||
smbas
|
smbas
|
||||||
|
Sophie Kirschner (pineapplemachine)
|
||||||
spycrab
|
spycrab
|
||||||
Stefan Galowicz (bogglez)
|
Stefan Galowicz (bogglez)
|
||||||
Stanislav Bobrov (Jiub)
|
Stanislav Bobrov (Jiub)
|
||||||
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -4,6 +4,8 @@
|
||||||
Bug #1990: Sunrise/sunset not set correct
|
Bug #1990: Sunrise/sunset not set correct
|
||||||
Bug #2131: Lustidrike's spell misses the player every time
|
Bug #2131: Lustidrike's spell misses the player every time
|
||||||
Bug #2222: Fatigue's effect on selling price is backwards
|
Bug #2222: Fatigue's effect on selling price is backwards
|
||||||
|
Bug #2256: Landing sound not playing when jumping immediately after landing
|
||||||
|
Bug #2274: Thin platform clips through player character instead of lifting
|
||||||
Bug #2326: After a bound item expires the last equipped item of that type is not automatically re-equipped
|
Bug #2326: After a bound item expires the last equipped item of that type is not automatically re-equipped
|
||||||
Bug #2455: Creatures attacks degrade armor
|
Bug #2455: Creatures attacks degrade armor
|
||||||
Bug #2562: Forcing AI to activate a teleport door sometimes causes a crash
|
Bug #2562: Forcing AI to activate a teleport door sometimes causes a crash
|
||||||
|
@ -15,6 +17,7 @@
|
||||||
Bug #2872: Tab completion in console doesn't work with explicit reference
|
Bug #2872: Tab completion in console doesn't work with explicit reference
|
||||||
Bug #2971: Compiler did not reject lines with naked expressions beginning with x.y
|
Bug #2971: Compiler did not reject lines with naked expressions beginning with x.y
|
||||||
Bug #3049: Drain and Fortify effects are not properly applied on health, magicka and fatigue
|
Bug #3049: Drain and Fortify effects are not properly applied on health, magicka and fatigue
|
||||||
|
Bug #3059: Unable to hit with marksman weapons when too close to an enemy
|
||||||
Bug #3072: Fatal error on AddItem <item> that has a script containing Equip <item>
|
Bug #3072: Fatal error on AddItem <item> that has a script containing Equip <item>
|
||||||
Bug #3249: Fixed revert function not updating views properly
|
Bug #3249: Fixed revert function not updating views properly
|
||||||
Bug #3374: Touch spells not hitting kwama foragers
|
Bug #3374: Touch spells not hitting kwama foragers
|
||||||
|
@ -22,10 +25,13 @@
|
||||||
Bug #3533: GetSpellEffects should detect effects with zero duration
|
Bug #3533: GetSpellEffects should detect effects with zero duration
|
||||||
Bug #3591: Angled hit distance too low
|
Bug #3591: Angled hit distance too low
|
||||||
Bug #3629: DB assassin attack never triggers creature spawning
|
Bug #3629: DB assassin attack never triggers creature spawning
|
||||||
|
Bug #3681: OpenMW-CS: Clicking Scripts in Preferences spawns many color pickers
|
||||||
Bug #3788: GetPCInJail and GetPCTraveling do not work as in vanilla
|
Bug #3788: GetPCInJail and GetPCTraveling do not work as in vanilla
|
||||||
|
Bug #3836: Script fails to compile when command argument contains "\n"
|
||||||
Bug #3876: Landscape texture painting is misaligned
|
Bug #3876: Landscape texture painting is misaligned
|
||||||
Bug #3897: Have Goodbye give all choices the effects of Goodbye
|
Bug #3897: Have Goodbye give all choices the effects of Goodbye
|
||||||
Bug #3911: [macOS] Typing in the "Content List name" dialog box produces double characters
|
Bug #3911: [macOS] Typing in the "Content List name" dialog box produces double characters
|
||||||
|
Bug #3920: RemoveSpellEffects doesn't remove constant effects
|
||||||
Bug #3948: AiCombat moving target aiming uses incorrect speed for magic projectiles
|
Bug #3948: AiCombat moving target aiming uses incorrect speed for magic projectiles
|
||||||
Bug #3950: FLATTEN_STATIC_TRANSFORMS optimization breaks animated collision shapes
|
Bug #3950: FLATTEN_STATIC_TRANSFORMS optimization breaks animated collision shapes
|
||||||
Bug #3993: Terrain texture blending map is not upscaled
|
Bug #3993: Terrain texture blending map is not upscaled
|
||||||
|
@ -91,6 +97,7 @@
|
||||||
Bug #4553: Forcegreeting on non-actor opens a dialogue window which cannot be closed
|
Bug #4553: Forcegreeting on non-actor opens a dialogue window which cannot be closed
|
||||||
Bug #4557: Topics with reserved names are handled differently from vanilla
|
Bug #4557: Topics with reserved names are handled differently from vanilla
|
||||||
Bug #4558: Mesh optimizer: check for reserved node name is case-sensitive
|
Bug #4558: Mesh optimizer: check for reserved node name is case-sensitive
|
||||||
|
Bug #4560: OpenMW does not update pinned windows properly
|
||||||
Bug #4563: Fast travel price logic checks destination cell instead of service actor cell
|
Bug #4563: Fast travel price logic checks destination cell instead of service actor cell
|
||||||
Bug #4565: Underwater view distance should be limited
|
Bug #4565: Underwater view distance should be limited
|
||||||
Bug #4573: Player uses headtracking in the 1st-person mode
|
Bug #4573: Player uses headtracking in the 1st-person mode
|
||||||
|
@ -98,6 +105,14 @@
|
||||||
Bug #4575: Weird result of attack animation blending with movement animations
|
Bug #4575: Weird result of attack animation blending with movement animations
|
||||||
Bug #4576: Reset of idle animations when attack can not be started
|
Bug #4576: Reset of idle animations when attack can not be started
|
||||||
Bug #4591: Attack strength should be 0 if player did not hold the attack button
|
Bug #4591: Attack strength should be 0 if player did not hold the attack button
|
||||||
|
Bug #4597: <> operator causes a compile error
|
||||||
|
Bug #4604: Picking up gold from the ground only makes 1 grabbed
|
||||||
|
Bug #4607: Scaling for animated collision shapes is applied twice
|
||||||
|
Bug #4608: Falling damage is applied twice
|
||||||
|
Bug #4615: Flicker effects for light sources are handled incorrectly
|
||||||
|
Bug #4617: First person sneaking offset is not applied while the character is in air
|
||||||
|
Bug #4618: Sneaking is possible while the character is flying
|
||||||
|
Bug #4622: Recharging enchanted items with Soul Gems does not award experience if it fails
|
||||||
Feature #1645: Casting effects from objects
|
Feature #1645: Casting effects from objects
|
||||||
Feature #2606: Editor: Implemented (optional) case sensitive global search
|
Feature #2606: Editor: Implemented (optional) case sensitive global search
|
||||||
Feature #3083: Play animation when NPC is casting spell via script
|
Feature #3083: Play animation when NPC is casting spell via script
|
||||||
|
@ -123,6 +138,10 @@
|
||||||
Feature #4581: Use proper logging system
|
Feature #4581: Use proper logging system
|
||||||
Task #2490: Don't open command prompt window on Release-mode builds automatically
|
Task #2490: Don't open command prompt window on Release-mode builds automatically
|
||||||
Task #4545: Enable is_pod string test
|
Task #4545: Enable is_pod string test
|
||||||
|
Task #4605: Optimize skinning
|
||||||
|
Task #4606: Support Rapture3D's OpenAL driver
|
||||||
|
Task #4613: Incomplete type errors when compiling with g++ on OSX 10.9
|
||||||
|
Task #4621: Optimize combat AI
|
||||||
|
|
||||||
0.44.0
|
0.44.0
|
||||||
------
|
------
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#include "coloreditor.hpp"
|
#include "coloreditor.hpp"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QColor>
|
|
||||||
#include <QColorDialog>
|
#include <QColorDialog>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QRect>
|
|
||||||
#include <QShowEvent>
|
#include <QShowEvent>
|
||||||
|
|
||||||
#include "colorpickerpopup.hpp"
|
#include "colorpickerpopup.hpp"
|
||||||
|
@ -27,9 +25,7 @@ CSVWidget::ColorEditor::ColorEditor(QWidget *parent, const bool popupOnStart)
|
||||||
mColorPicker(new ColorPickerPopup(this)),
|
mColorPicker(new ColorPickerPopup(this)),
|
||||||
mPopupOnStart(popupOnStart)
|
mPopupOnStart(popupOnStart)
|
||||||
{
|
{
|
||||||
setCheckable(true);
|
|
||||||
connect(this, SIGNAL(clicked()), this, SLOT(showPicker()));
|
connect(this, SIGNAL(clicked()), this, SLOT(showPicker()));
|
||||||
connect(mColorPicker, SIGNAL(hid()), this, SLOT(pickerHid()));
|
|
||||||
connect(mColorPicker, SIGNAL(colorChanged(const QColor &)), this, SLOT(pickerColorChanged(const QColor &)));
|
connect(mColorPicker, SIGNAL(colorChanged(const QColor &)), this, SLOT(pickerColorChanged(const QColor &)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,20 +81,7 @@ void CSVWidget::ColorEditor::setColor(const int colorInt)
|
||||||
|
|
||||||
void CSVWidget::ColorEditor::showPicker()
|
void CSVWidget::ColorEditor::showPicker()
|
||||||
{
|
{
|
||||||
if (isChecked())
|
mColorPicker->showPicker(calculatePopupPosition(), mColor);
|
||||||
{
|
|
||||||
mColorPicker->showPicker(calculatePopupPosition(), mColor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mColorPicker->hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVWidget::ColorEditor::pickerHid()
|
|
||||||
{
|
|
||||||
setChecked(false);
|
|
||||||
emit pickingFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWidget::ColorEditor::pickerColorChanged(const QColor &color)
|
void CSVWidget::ColorEditor::pickerColorChanged(const QColor &color)
|
||||||
|
|
|
@ -45,7 +45,6 @@ namespace CSVWidget
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void showPicker();
|
void showPicker();
|
||||||
void pickerHid();
|
|
||||||
void pickerColorChanged(const QColor &color);
|
void pickerColorChanged(const QColor &color);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QStyleOption>
|
#include <QStyleOption>
|
||||||
|
|
||||||
|
@ -19,7 +18,6 @@ CSVWidget::ColorPickerPopup::ColorPickerPopup(QWidget *parent)
|
||||||
mColorPicker->setWindowFlags(Qt::Widget);
|
mColorPicker->setWindowFlags(Qt::Widget);
|
||||||
mColorPicker->setOptions(QColorDialog::NoButtons | QColorDialog::DontUseNativeDialog);
|
mColorPicker->setOptions(QColorDialog::NoButtons | QColorDialog::DontUseNativeDialog);
|
||||||
mColorPicker->installEventFilter(this);
|
mColorPicker->installEventFilter(this);
|
||||||
mColorPicker->open();
|
|
||||||
connect(mColorPicker,
|
connect(mColorPicker,
|
||||||
SIGNAL(currentColorChanged(const QColor &)),
|
SIGNAL(currentColorChanged(const QColor &)),
|
||||||
this,
|
this,
|
||||||
|
@ -39,8 +37,9 @@ void CSVWidget::ColorPickerPopup::showPicker(const QPoint &position, const QColo
|
||||||
geometry.moveTo(position);
|
geometry.moveTo(position);
|
||||||
setGeometry(geometry);
|
setGeometry(geometry);
|
||||||
|
|
||||||
mColorPicker->setCurrentColor(initialColor);
|
// Calling getColor() creates a blocking dialog that will continue execution once the user chooses OK or Cancel
|
||||||
show();
|
QColor color = mColorPicker->getColor(initialColor);
|
||||||
|
mColorPicker->setCurrentColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent *event)
|
void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent *event)
|
||||||
|
@ -63,12 +62,6 @@ void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent *event)
|
||||||
QFrame::mousePressEvent(event);
|
QFrame::mousePressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWidget::ColorPickerPopup::hideEvent(QHideEvent *event)
|
|
||||||
{
|
|
||||||
QFrame::hideEvent(event);
|
|
||||||
emit hid();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSVWidget::ColorPickerPopup::eventFilter(QObject *object, QEvent *event)
|
bool CSVWidget::ColorPickerPopup::eventFilter(QObject *object, QEvent *event)
|
||||||
{
|
{
|
||||||
if (object == mColorPicker && event->type() == QEvent::KeyPress)
|
if (object == mColorPicker && event->type() == QEvent::KeyPress)
|
||||||
|
|
|
@ -20,11 +20,9 @@ namespace CSVWidget
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void mousePressEvent(QMouseEvent *event);
|
virtual void mousePressEvent(QMouseEvent *event);
|
||||||
virtual void hideEvent(QHideEvent *event);
|
|
||||||
virtual bool eventFilter(QObject *object, QEvent *event);
|
virtual bool eventFilter(QObject *object, QEvent *event);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void hid();
|
|
||||||
void colorChanged(const QColor &color);
|
void colorChanged(const QColor &color);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -584,6 +584,7 @@ namespace MWBase
|
||||||
End of tes3mp addition
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
virtual void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector<MWWorld::Ptr> &actors) = 0; ///< get a list of actors standing on \a object
|
||||||
virtual bool getPlayerStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is standing on \a object
|
virtual bool getPlayerStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is standing on \a object
|
||||||
virtual bool getActorStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if any actor is standing on \a object
|
virtual bool getActorStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if any actor is standing on \a object
|
||||||
virtual bool getPlayerCollidingWith(const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is colliding with \a object
|
virtual bool getPlayerCollidingWith(const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is colliding with \a object
|
||||||
|
@ -662,8 +663,8 @@ namespace MWBase
|
||||||
virtual void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) = 0;
|
virtual void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) = 0;
|
||||||
|
|
||||||
virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0;
|
virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0;
|
||||||
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
virtual void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) = 0;
|
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) = 0;
|
||||||
|
|
||||||
virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) = 0;
|
virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) = 0;
|
||||||
|
|
||||||
|
|
|
@ -176,14 +176,14 @@ namespace MWClass
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
float iWeight = floor(gmst.find(typeGmst)->getFloat());
|
float iWeight = floor(gmst.find(typeGmst)->mValue.getFloat());
|
||||||
|
|
||||||
float epsilon = 0.0005f;
|
float epsilon = 0.0005f;
|
||||||
|
|
||||||
if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fLightMaxMod")->getFloat() + epsilon)
|
if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fLightMaxMod")->mValue.getFloat() + epsilon)
|
||||||
return ESM::Skill::LightArmor;
|
return ESM::Skill::LightArmor;
|
||||||
|
|
||||||
if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fMedMaxMod")->getFloat() + epsilon)
|
if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fMedMaxMod")->mValue.getFloat() + epsilon)
|
||||||
return ESM::Skill::MediumArmor;
|
return ESM::Skill::MediumArmor;
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -331,7 +331,7 @@ namespace MWClass
|
||||||
int armorSkill = actor.getClass().getSkill(actor, armorSkillType);
|
int armorSkill = actor.getClass().getSkill(actor, armorSkillType);
|
||||||
|
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
int iBaseArmorSkill = world->getStore().get<ESM::GameSetting>().find("iBaseArmorSkill")->getInt();
|
int iBaseArmorSkill = world->getStore().get<ESM::GameSetting>().find("iBaseArmorSkill")->mValue.getInteger();
|
||||||
|
|
||||||
if(ref->mBase->mData.mWeight == 0)
|
if(ref->mBase->mData.mWeight == 0)
|
||||||
return ref->mBase->mData.mArmor;
|
return ref->mBase->mData.mArmor;
|
||||||
|
|
|
@ -275,13 +275,13 @@ namespace MWClass
|
||||||
|
|
||||||
MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength);
|
MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength);
|
||||||
|
|
||||||
float dist = gmst.find("fCombatDistance")->getFloat();
|
float dist = gmst.find("fCombatDistance")->mValue.getFloat();
|
||||||
if (!weapon.isEmpty())
|
if (!weapon.isEmpty())
|
||||||
dist *= weapon.get<ESM::Weapon>()->mBase->mData.mReach;
|
dist *= weapon.get<ESM::Weapon>()->mBase->mData.mReach;
|
||||||
|
|
||||||
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result.
|
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result.
|
||||||
std::vector<MWWorld::Ptr> targetActors;
|
std::vector<MWWorld::Ptr> targetActors;
|
||||||
if (!ptr.isEmpty() && ptr.getClass().isActor() && ptr != MWMechanics::getPlayer())
|
if (!ptr.isEmpty() && ptr.getClass().isActor())
|
||||||
ptr.getClass().getCreatureStats(ptr).getAiSequence().getCombatTargets(targetActors);
|
ptr.getClass().getCreatureStats(ptr).getAiSequence().getCombatTargets(targetActors);
|
||||||
|
|
||||||
std::pair<MWWorld::Ptr, osg::Vec3f> result = MWBase::Environment::get().getWorld()->getHitContact(ptr, dist, targetActors);
|
std::pair<MWWorld::Ptr, osg::Vec3f> result = MWBase::Environment::get().getWorld()->getHitContact(ptr, dist, targetActors);
|
||||||
|
@ -401,9 +401,6 @@ namespace MWClass
|
||||||
if (MWMechanics::blockMeleeAttack(ptr, victim, weapon, damage, attackStrength))
|
if (MWMechanics::blockMeleeAttack(ptr, victim, weapon, damage, attackStrength))
|
||||||
damage = 0;
|
damage = 0;
|
||||||
|
|
||||||
if (victim == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState())
|
|
||||||
damage = 0;
|
|
||||||
|
|
||||||
MWMechanics::diseaseContact(victim, ptr);
|
MWMechanics::diseaseContact(victim, ptr);
|
||||||
|
|
||||||
victim.getClass().onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true);
|
victim.getClass().onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true);
|
||||||
|
@ -466,11 +463,6 @@ namespace MWClass
|
||||||
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
|
ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool godmode = object == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
|
|
||||||
|
|
||||||
if (godmode)
|
|
||||||
damage = 0;
|
|
||||||
|
|
||||||
if (!successful)
|
if (!successful)
|
||||||
{
|
{
|
||||||
// Missed
|
// Missed
|
||||||
|
@ -492,9 +484,9 @@ namespace MWClass
|
||||||
if (!attacker.isEmpty())
|
if (!attacker.isEmpty())
|
||||||
{
|
{
|
||||||
// Check for knockdown
|
// Check for knockdown
|
||||||
float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * getGmst().fKnockDownMult->getFloat();
|
float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * getGmst().fKnockDownMult->mValue.getFloat();
|
||||||
float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified()
|
float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified()
|
||||||
* getGmst().iKnockDownOddsMult->getInt() * 0.01f + getGmst().iKnockDownOddsBase->getInt();
|
* getGmst().iKnockDownOddsMult->mValue.getInteger() * 0.01f + getGmst().iKnockDownOddsBase->mValue.getInteger();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Start of tes3mp change (major)
|
Start of tes3mp change (major)
|
||||||
|
@ -513,6 +505,9 @@ namespace MWClass
|
||||||
if (dedicatedAttack->knockdown)
|
if (dedicatedAttack->knockdown)
|
||||||
stats.setKnockedDown(true);
|
stats.setKnockedDown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99())
|
||||||
|
stats.setKnockedDown(true);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99())
|
if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99())
|
||||||
|
@ -530,7 +525,7 @@ namespace MWClass
|
||||||
|
|
||||||
if(ishealth)
|
if(ishealth)
|
||||||
{
|
{
|
||||||
if (!attacker.isEmpty() && !godmode)
|
if (!attacker.isEmpty())
|
||||||
{
|
{
|
||||||
damage = scaleDamage(damage, attacker, ptr);
|
damage = scaleDamage(damage, attacker, ptr);
|
||||||
MWBase::Environment::get().getWorld()->spawnBloodEffect(ptr, hitPosition);
|
MWBase::Environment::get().getWorld()->spawnBloodEffect(ptr, hitPosition);
|
||||||
|
@ -671,8 +666,8 @@ namespace MWClass
|
||||||
|
|
||||||
const GMST& gmst = getGmst();
|
const GMST& gmst = getGmst();
|
||||||
|
|
||||||
float walkSpeed = gmst.fMinWalkSpeedCreature->getFloat() + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified()
|
float walkSpeed = gmst.fMinWalkSpeedCreature->mValue.getFloat() + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified()
|
||||||
* (gmst.fMaxWalkSpeedCreature->getFloat() - gmst.fMinWalkSpeedCreature->getFloat());
|
* (gmst.fMaxWalkSpeedCreature->mValue.getFloat() - gmst.fMinWalkSpeedCreature->mValue.getFloat());
|
||||||
|
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
|
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
|
||||||
|
@ -691,9 +686,9 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() +
|
float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() +
|
||||||
mageffects.get(ESM::MagicEffect::Levitate).getMagnitude());
|
mageffects.get(ESM::MagicEffect::Levitate).getMagnitude());
|
||||||
flySpeed = gmst.fMinFlySpeed->getFloat() + flySpeed*(gmst.fMaxFlySpeed->getFloat() - gmst.fMinFlySpeed->getFloat());
|
flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + flySpeed*(gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat());
|
||||||
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
||||||
flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->getFloat() * normalizedEncumbrance;
|
flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance;
|
||||||
flySpeed = std::max(0.0f, flySpeed);
|
flySpeed = std::max(0.0f, flySpeed);
|
||||||
moveSpeed = flySpeed;
|
moveSpeed = flySpeed;
|
||||||
}
|
}
|
||||||
|
@ -703,8 +698,8 @@ namespace MWClass
|
||||||
if(running)
|
if(running)
|
||||||
swimSpeed = runSpeed;
|
swimSpeed = runSpeed;
|
||||||
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
|
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
|
||||||
swimSpeed *= gmst.fSwimRunBase->getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) *
|
swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) *
|
||||||
gmst.fSwimRunAthleticsMult->getFloat();
|
gmst.fSwimRunAthleticsMult->mValue.getFloat();
|
||||||
moveSpeed = swimSpeed;
|
moveSpeed = swimSpeed;
|
||||||
}
|
}
|
||||||
else if(running)
|
else if(running)
|
||||||
|
@ -969,8 +964,8 @@ namespace MWClass
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat();
|
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat();
|
||||||
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat();
|
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat();
|
||||||
|
|
||||||
float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@ namespace MWClass
|
||||||
else if (creatureStats.isDead())
|
else if (creatureStats.isDead())
|
||||||
{
|
{
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat();
|
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat();
|
||||||
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat();
|
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat();
|
||||||
|
|
||||||
float delay = std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
float delay = std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
||||||
if (creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp())
|
if (creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp())
|
||||||
|
|
|
@ -171,7 +171,7 @@ namespace MWClass
|
||||||
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
||||||
|
|
||||||
static const float fWortChanceValue =
|
static const float fWortChanceValue =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->getFloat();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->mValue.getFloat();
|
||||||
|
|
||||||
MWGui::Widgets::SpellEffectList list;
|
MWGui::Widgets::SpellEffectList list;
|
||||||
for (int i=0; i<4; ++i)
|
for (int i=0; i<4; ++i)
|
||||||
|
|
|
@ -387,9 +387,9 @@ namespace MWClass
|
||||||
if (!ref->mBase->mFaction.empty())
|
if (!ref->mBase->mFaction.empty())
|
||||||
{
|
{
|
||||||
static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("iAutoRepFacMod")->getInt();
|
.find("iAutoRepFacMod")->mValue.getInteger();
|
||||||
static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("iAutoRepLevMod")->getInt();
|
.find("iAutoRepLevMod")->mValue.getInteger();
|
||||||
int rank = ref->mBase->getFactionRank();
|
int rank = ref->mBase->getFactionRank();
|
||||||
|
|
||||||
data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1));
|
data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1));
|
||||||
|
@ -543,7 +543,7 @@ namespace MWClass
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const MWWorld::Store<ESM::GameSetting> &store = world->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &store = world->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
return store.find("sWerewolfPopup")->getString();
|
return store.find("sWerewolfPopup")->mValue.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
const MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
const MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||||
|
@ -593,10 +593,10 @@ namespace MWClass
|
||||||
|
|
||||||
MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength);
|
MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength);
|
||||||
|
|
||||||
const float fCombatDistance = store.find("fCombatDistance")->getFloat();
|
const float fCombatDistance = store.find("fCombatDistance")->mValue.getFloat();
|
||||||
float dist = fCombatDistance * (!weapon.isEmpty() ?
|
float dist = fCombatDistance * (!weapon.isEmpty() ?
|
||||||
weapon.get<ESM::Weapon>()->mBase->mData.mReach :
|
weapon.get<ESM::Weapon>()->mBase->mData.mReach :
|
||||||
store.find("fHandToHandReach")->getFloat());
|
store.find("fHandToHandReach")->mValue.getFloat());
|
||||||
|
|
||||||
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result.
|
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result.
|
||||||
std::vector<MWWorld::Ptr> targetActors;
|
std::vector<MWWorld::Ptr> targetActors;
|
||||||
|
@ -701,14 +701,14 @@ namespace MWClass
|
||||||
&& !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, victim);
|
&& !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, victim);
|
||||||
if(unaware)
|
if(unaware)
|
||||||
{
|
{
|
||||||
damage *= store.find("fCombatCriticalStrikeMult")->getFloat();
|
damage *= store.find("fCombatCriticalStrikeMult")->mValue.getFloat();
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||||
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (othercls.getCreatureStats(victim).getKnockedDown())
|
if (othercls.getCreatureStats(victim).getKnockedDown())
|
||||||
damage *= store.find("fCombatKODamageMult")->getFloat();
|
damage *= store.find("fCombatKODamageMult")->mValue.getFloat();
|
||||||
|
|
||||||
// Apply "On hit" enchanted weapons
|
// Apply "On hit" enchanted weapons
|
||||||
|
|
||||||
|
@ -827,14 +827,14 @@ namespace MWClass
|
||||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
const GMST& gmst = getGmst();
|
const GMST& gmst = getGmst();
|
||||||
|
|
||||||
int chance = store.get<ESM::GameSetting>().find("iVoiceHitOdds")->getInt();
|
int chance = store.get<ESM::GameSetting>().find("iVoiceHitOdds")->mValue.getInteger();
|
||||||
if (Misc::Rng::roll0to99() < chance)
|
if (Misc::Rng::roll0to99() < chance)
|
||||||
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
|
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
|
||||||
|
|
||||||
// Check for knockdown
|
// Check for knockdown
|
||||||
float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * gmst.fKnockDownMult->getFloat();
|
float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * gmst.fKnockDownMult->mValue.getFloat();
|
||||||
float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified()
|
float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified()
|
||||||
* gmst.iKnockDownOddsMult->getInt() * 0.01f + gmst.iKnockDownOddsBase->getInt();
|
* gmst.iKnockDownOddsMult->mValue.getInteger() * 0.01f + gmst.iKnockDownOddsBase->mValue.getInteger();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Start of tes3mp change (major)
|
Start of tes3mp change (major)
|
||||||
|
@ -887,7 +887,7 @@ namespace MWClass
|
||||||
|
|
||||||
float unmitigatedDamage = damage;
|
float unmitigatedDamage = damage;
|
||||||
float x = damage / (damage + getArmorRating(ptr));
|
float x = damage / (damage + getArmorRating(ptr));
|
||||||
damage *= std::max(gmst.fCombatArmorMinMult->getFloat(), x);
|
damage *= std::max(gmst.fCombatArmorMinMult->mValue.getFloat(), x);
|
||||||
int damageDiff = static_cast<int>(unmitigatedDamage - damage);
|
int damageDiff = static_cast<int>(unmitigatedDamage - damage);
|
||||||
damage = std::max(1.f, damage);
|
damage = std::max(1.f, damage);
|
||||||
damageDiff = std::max(1, damageDiff);
|
damageDiff = std::max(1, damageDiff);
|
||||||
|
@ -1126,15 +1126,15 @@ namespace MWClass
|
||||||
bool sneaking = stats.getStance(MWMechanics::CreatureStats::Stance_Sneak);
|
bool sneaking = stats.getStance(MWMechanics::CreatureStats::Stance_Sneak);
|
||||||
bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run);
|
bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run);
|
||||||
|
|
||||||
float walkSpeed = gmst.fMinWalkSpeed->getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()*
|
float walkSpeed = gmst.fMinWalkSpeed->mValue.getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()*
|
||||||
(gmst.fMaxWalkSpeed->getFloat() - gmst.fMinWalkSpeed->getFloat());
|
(gmst.fMaxWalkSpeed->mValue.getFloat() - gmst.fMinWalkSpeed->mValue.getFloat());
|
||||||
walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->getFloat()*normalizedEncumbrance;
|
walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat()*normalizedEncumbrance;
|
||||||
walkSpeed = std::max(0.0f, walkSpeed);
|
walkSpeed = std::max(0.0f, walkSpeed);
|
||||||
if(sneaking)
|
if(sneaking)
|
||||||
walkSpeed *= gmst.fSneakSpeedMultiplier->getFloat();
|
walkSpeed *= gmst.fSneakSpeedMultiplier->mValue.getFloat();
|
||||||
|
|
||||||
float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() *
|
float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() *
|
||||||
gmst.fAthleticsRunBonus->getFloat() + gmst.fBaseRunMultiplier->getFloat());
|
gmst.fAthleticsRunBonus->mValue.getFloat() + gmst.fBaseRunMultiplier->mValue.getFloat());
|
||||||
|
|
||||||
float moveSpeed;
|
float moveSpeed;
|
||||||
if(getEncumbrance(ptr) > getCapacity(ptr))
|
if(getEncumbrance(ptr) > getCapacity(ptr))
|
||||||
|
@ -1144,8 +1144,8 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
float flySpeed = 0.01f*(npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified() +
|
float flySpeed = 0.01f*(npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified() +
|
||||||
mageffects.get(ESM::MagicEffect::Levitate).getMagnitude());
|
mageffects.get(ESM::MagicEffect::Levitate).getMagnitude());
|
||||||
flySpeed = gmst.fMinFlySpeed->getFloat() + flySpeed*(gmst.fMaxFlySpeed->getFloat() - gmst.fMinFlySpeed->getFloat());
|
flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + flySpeed*(gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat());
|
||||||
flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->getFloat() * normalizedEncumbrance;
|
flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance;
|
||||||
flySpeed = std::max(0.0f, flySpeed);
|
flySpeed = std::max(0.0f, flySpeed);
|
||||||
moveSpeed = flySpeed;
|
moveSpeed = flySpeed;
|
||||||
}
|
}
|
||||||
|
@ -1155,8 +1155,8 @@ namespace MWClass
|
||||||
if(running)
|
if(running)
|
||||||
swimSpeed = runSpeed;
|
swimSpeed = runSpeed;
|
||||||
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
|
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
|
||||||
swimSpeed *= gmst.fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
|
swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()*
|
||||||
gmst.fSwimRunAthleticsMult->getFloat();
|
gmst.fSwimRunAthleticsMult->mValue.getFloat();
|
||||||
moveSpeed = swimSpeed;
|
moveSpeed = swimSpeed;
|
||||||
}
|
}
|
||||||
else if(running && !sneaking)
|
else if(running && !sneaking)
|
||||||
|
@ -1167,7 +1167,7 @@ namespace MWClass
|
||||||
moveSpeed *= 0.75f;
|
moveSpeed *= 0.75f;
|
||||||
|
|
||||||
if(npcdata->mNpcStats.isWerewolf() && running && npcdata->mNpcStats.getDrawState() == MWMechanics::DrawState_Nothing)
|
if(npcdata->mNpcStats.isWerewolf() && running && npcdata->mNpcStats.getDrawState() == MWMechanics::DrawState_Nothing)
|
||||||
moveSpeed *= gmst.fWereWolfRunMult->getFloat();
|
moveSpeed *= gmst.fWereWolfRunMult->mValue.getFloat();
|
||||||
|
|
||||||
return moveSpeed;
|
return moveSpeed;
|
||||||
}
|
}
|
||||||
|
@ -1177,11 +1177,15 @@ namespace MWClass
|
||||||
if(getEncumbrance(ptr) > getCapacity(ptr))
|
if(getEncumbrance(ptr) > getCapacity(ptr))
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
|
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead())
|
||||||
|
return 0.f;
|
||||||
|
|
||||||
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||||
const GMST& gmst = getGmst();
|
const GMST& gmst = getGmst();
|
||||||
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
||||||
const float encumbranceTerm = gmst.fJumpEncumbranceBase->getFloat() +
|
const float encumbranceTerm = gmst.fJumpEncumbranceBase->mValue.getFloat() +
|
||||||
gmst.fJumpEncumbranceMultiplier->getFloat() *
|
gmst.fJumpEncumbranceMultiplier->mValue.getFloat() *
|
||||||
(1.0f - Npc::getNormalizedEncumbrance(ptr));
|
(1.0f - Npc::getNormalizedEncumbrance(ptr));
|
||||||
|
|
||||||
float a = static_cast<float>(npcdata->mNpcStats.getSkill(ESM::Skill::Acrobatics).getModified());
|
float a = static_cast<float>(npcdata->mNpcStats.getSkill(ESM::Skill::Acrobatics).getModified());
|
||||||
|
@ -1192,14 +1196,14 @@ namespace MWClass
|
||||||
a = 50.0f;
|
a = 50.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float x = gmst.fJumpAcrobaticsBase->getFloat() +
|
float x = gmst.fJumpAcrobaticsBase->mValue.getFloat() +
|
||||||
std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->getFloat());
|
std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->mValue.getFloat());
|
||||||
x += 3.0f * b * gmst.fJumpAcroMultiplier->getFloat();
|
x += 3.0f * b * gmst.fJumpAcroMultiplier->mValue.getFloat();
|
||||||
x += mageffects.get(ESM::MagicEffect::Jump).getMagnitude() * 64;
|
x += mageffects.get(ESM::MagicEffect::Jump).getMagnitude() * 64;
|
||||||
x *= encumbranceTerm;
|
x *= encumbranceTerm;
|
||||||
|
|
||||||
if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run))
|
if(stats.getStance(MWMechanics::CreatureStats::Stance_Run))
|
||||||
x *= gmst.fJumpRunMultiplier->getFloat();
|
x *= gmst.fJumpRunMultiplier->mValue.getFloat();
|
||||||
x *= npcdata->mNpcStats.getFatigueTerm();
|
x *= npcdata->mNpcStats.getFatigueTerm();
|
||||||
x -= -627.2f;/*gravity constant*/
|
x -= -627.2f;/*gravity constant*/
|
||||||
x /= 3.0f;
|
x /= 3.0f;
|
||||||
|
@ -1264,7 +1268,7 @@ namespace MWClass
|
||||||
float Npc::getCapacity (const MWWorld::Ptr& ptr) const
|
float Npc::getCapacity (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||||
static const float fEncumbranceStrMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fEncumbranceStrMult")->getFloat();
|
static const float fEncumbranceStrMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fEncumbranceStrMult")->mValue.getFloat();
|
||||||
return stats.getAttribute(ESM::Attribute::Strength).getModified()*fEncumbranceStrMult;
|
return stats.getAttribute(ESM::Attribute::Strength).getModified()*fEncumbranceStrMult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1307,8 +1311,8 @@ namespace MWClass
|
||||||
MWMechanics::NpcStats &stats = getNpcStats(ptr);
|
MWMechanics::NpcStats &stats = getNpcStats(ptr);
|
||||||
const MWWorld::InventoryStore &invStore = getInventoryStore(ptr);
|
const MWWorld::InventoryStore &invStore = getInventoryStore(ptr);
|
||||||
|
|
||||||
float fUnarmoredBase1 = store.find("fUnarmoredBase1")->getFloat();
|
float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat();
|
||||||
float fUnarmoredBase2 = store.find("fUnarmoredBase2")->getFloat();
|
float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat();
|
||||||
int unarmoredSkill = stats.getSkill(ESM::Skill::Unarmored).getModified();
|
int unarmoredSkill = stats.getSkill(ESM::Skill::Unarmored).getModified();
|
||||||
|
|
||||||
float ratings[MWWorld::InventoryStore::Slots];
|
float ratings[MWWorld::InventoryStore::Slots];
|
||||||
|
@ -1426,11 +1430,10 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
osg::Vec3f pos(ptr.getRefData().getPosition().asVec3());
|
osg::Vec3f pos(ptr.getRefData().getPosition().asVec3());
|
||||||
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
if (world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return "DefaultLandWater";
|
return "DefaultLandWater";
|
||||||
if(world->isOnGround(ptr))
|
|
||||||
return "DefaultLand";
|
return "DefaultLand";
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
if(name == "swimleft")
|
if(name == "swimleft")
|
||||||
return "Swim Left";
|
return "Swim Left";
|
||||||
|
@ -1549,8 +1552,8 @@ namespace MWClass
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->getFloat();
|
static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat();
|
||||||
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->getFloat();
|
static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat();
|
||||||
|
|
||||||
float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay);
|
||||||
|
|
||||||
|
|
|
@ -321,8 +321,8 @@ namespace MWClass
|
||||||
std::string type = mapping[ref->mBase->mData.mType].first;
|
std::string type = mapping[ref->mBase->mData.mType].first;
|
||||||
std::string oneOrTwoHanded = mapping[ref->mBase->mData.mType].second;
|
std::string oneOrTwoHanded = mapping[ref->mBase->mData.mType].second;
|
||||||
|
|
||||||
text += store.get<ESM::GameSetting>().find(type)->getString() +
|
text += store.get<ESM::GameSetting>().find(type)->mValue.getString() +
|
||||||
((oneOrTwoHanded != "") ? ", " + store.get<ESM::GameSetting>().find(oneOrTwoHanded)->getString() : "");
|
((oneOrTwoHanded != "") ? ", " + store.get<ESM::GameSetting>().find(oneOrTwoHanded)->mValue.getString() : "");
|
||||||
|
|
||||||
// weapon damage
|
// weapon damage
|
||||||
if (ref->mBase->mData.mType >= 9)
|
if (ref->mBase->mData.mType >= 9)
|
||||||
|
@ -360,7 +360,7 @@ namespace MWClass
|
||||||
if (ref->mBase->mData.mType < 9 && Settings::Manager::getBool("show melee info", "Game"))
|
if (ref->mBase->mData.mType < 9 && Settings::Manager::getBool("show melee info", "Game"))
|
||||||
{
|
{
|
||||||
// 64 game units = 1 yard = 3 ft, display value in feet
|
// 64 game units = 1 yard = 3 ft, display value in feet
|
||||||
const float combatDistance = store.get<ESM::GameSetting>().find("fCombatDistance")->getFloat() * ref->mBase->mData.mReach;
|
const float combatDistance = store.get<ESM::GameSetting>().find("fCombatDistance")->mValue.getFloat() * ref->mBase->mData.mReach;
|
||||||
text += MWGui::ToolTips::getWeightString(combatDistance*3/64, "#{sRange}");
|
text += MWGui::ToolTips::getWeightString(combatDistance*3/64, "#{sRange}");
|
||||||
text += " #{sFeet}";
|
text += " #{sFeet}";
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,7 @@ namespace MWDialogue
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmsts =
|
const MWWorld::Store<ESM::GameSetting>& gmsts =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
title = gmsts.find (modifiedTopic)->getString();
|
title = gmsts.find (modifiedTopic)->mValue.getString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
title = topic;
|
title = topic;
|
||||||
|
@ -587,7 +587,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
||||||
|
|
||||||
callback->addResponse(gmsts.find ("sServiceRefusal")->getString(), Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
|
callback->addResponse(gmsts.find ("sServiceRefusal")->mValue.getString(), Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
|
||||||
|
|
||||||
executeScript (info->mResultScript, mActor);
|
executeScript (info->mResultScript, mActor);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -365,15 +365,15 @@ namespace MWGui
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
const std::string sPersuasion = gmst.find("sPersuasion")->getString();
|
const std::string sPersuasion = gmst.find("sPersuasion")->mValue.getString();
|
||||||
const std::string sCompanionShare = gmst.find("sCompanionShare")->getString();
|
const std::string sCompanionShare = gmst.find("sCompanionShare")->mValue.getString();
|
||||||
const std::string sBarter = gmst.find("sBarter")->getString();
|
const std::string sBarter = gmst.find("sBarter")->mValue.getString();
|
||||||
const std::string sSpells = gmst.find("sSpells")->getString();
|
const std::string sSpells = gmst.find("sSpells")->mValue.getString();
|
||||||
const std::string sTravel = gmst.find("sTravel")->getString();
|
const std::string sTravel = gmst.find("sTravel")->mValue.getString();
|
||||||
const std::string sSpellMakingMenuTitle = gmst.find("sSpellMakingMenuTitle")->getString();
|
const std::string sSpellMakingMenuTitle = gmst.find("sSpellMakingMenuTitle")->mValue.getString();
|
||||||
const std::string sEnchanting = gmst.find("sEnchanting")->getString();
|
const std::string sEnchanting = gmst.find("sEnchanting")->mValue.getString();
|
||||||
const std::string sServiceTrainingTitle = gmst.find("sServiceTrainingTitle")->getString();
|
const std::string sServiceTrainingTitle = gmst.find("sServiceTrainingTitle")->mValue.getString();
|
||||||
const std::string sRepair = gmst.find("sRepair")->getString();
|
const std::string sRepair = gmst.find("sRepair")->mValue.getString();
|
||||||
|
|
||||||
if (topic != sPersuasion && topic != sCompanionShare && topic != sBarter
|
if (topic != sPersuasion && topic != sCompanionShare && topic != sBarter
|
||||||
&& topic != sSpells && topic != sTravel && topic != sSpellMakingMenuTitle
|
&& topic != sSpells && topic != sTravel && topic != sSpellMakingMenuTitle
|
||||||
|
@ -458,7 +458,7 @@ namespace MWGui
|
||||||
void DialogueWindow::restock()
|
void DialogueWindow::restock()
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
|
MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
|
||||||
float delay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->getFloat();
|
float delay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->mValue.getFloat();
|
||||||
|
|
||||||
// Gold is restocked every 24h
|
// Gold is restocked every 24h
|
||||||
if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getLastRestockTime() + delay)
|
if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getLastRestockTime() + delay)
|
||||||
|
@ -503,31 +503,31 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||||
mTopicsList->addItem(gmst.find("sPersuasion")->getString());
|
mTopicsList->addItem(gmst.find("sPersuasion")->mValue.getString());
|
||||||
|
|
||||||
if (services & ESM::NPC::AllItems)
|
if (services & ESM::NPC::AllItems)
|
||||||
mTopicsList->addItem(gmst.find("sBarter")->getString());
|
mTopicsList->addItem(gmst.find("sBarter")->mValue.getString());
|
||||||
|
|
||||||
if (services & ESM::NPC::Spells)
|
if (services & ESM::NPC::Spells)
|
||||||
mTopicsList->addItem(gmst.find("sSpells")->getString());
|
mTopicsList->addItem(gmst.find("sSpells")->mValue.getString());
|
||||||
|
|
||||||
if (travel)
|
if (travel)
|
||||||
mTopicsList->addItem(gmst.find("sTravel")->getString());
|
mTopicsList->addItem(gmst.find("sTravel")->mValue.getString());
|
||||||
|
|
||||||
if (services & ESM::NPC::Spellmaking)
|
if (services & ESM::NPC::Spellmaking)
|
||||||
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());
|
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->mValue.getString());
|
||||||
|
|
||||||
if (services & ESM::NPC::Enchanting)
|
if (services & ESM::NPC::Enchanting)
|
||||||
mTopicsList->addItem(gmst.find("sEnchanting")->getString());
|
mTopicsList->addItem(gmst.find("sEnchanting")->mValue.getString());
|
||||||
|
|
||||||
if (services & ESM::NPC::Training)
|
if (services & ESM::NPC::Training)
|
||||||
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
|
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->mValue.getString());
|
||||||
|
|
||||||
if (services & ESM::NPC::Repair)
|
if (services & ESM::NPC::Repair)
|
||||||
mTopicsList->addItem(gmst.find("sRepair")->getString());
|
mTopicsList->addItem(gmst.find("sRepair")->mValue.getString());
|
||||||
|
|
||||||
if (isCompanion())
|
if (isCompanion())
|
||||||
mTopicsList->addItem(gmst.find("sCompanionShare")->getString());
|
mTopicsList->addItem(gmst.find("sCompanionShare")->mValue.getString());
|
||||||
|
|
||||||
if (mTopicsList->getItemCount() > 0)
|
if (mTopicsList->getItemCount() > 0)
|
||||||
mTopicsList->addSeparator();
|
mTopicsList->addSeparator();
|
||||||
|
@ -592,7 +592,7 @@ namespace MWGui
|
||||||
Goodbye* link = new Goodbye();
|
Goodbye* link = new Goodbye();
|
||||||
link->eventActivated += MyGUI::newDelegate(this, &DialogueWindow::onGoodbyeActivated);
|
link->eventActivated += MyGUI::newDelegate(this, &DialogueWindow::onGoodbyeActivated);
|
||||||
mLinks.push_back(link);
|
mLinks.push_back(link);
|
||||||
std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString();
|
std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->mValue.getString();
|
||||||
BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, textColours.answer, textColours.answerOver,
|
BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, textColours.answer, textColours.answerOver,
|
||||||
textColours.answerPressed,
|
textColours.answerPressed,
|
||||||
TypesetBook::InteractiveId(link));
|
TypesetBook::InteractiveId(link));
|
||||||
|
|
|
@ -341,7 +341,7 @@ namespace MWGui
|
||||||
MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem();
|
MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem();
|
||||||
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(), mPtr))
|
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(), mPtr))
|
||||||
{
|
{
|
||||||
std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->getString();
|
std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->mValue.getString();
|
||||||
if (msg.find("%s") != std::string::npos)
|
if (msg.find("%s") != std::string::npos)
|
||||||
msg.replace(msg.find("%s"), 2, item.getClass().getName(item));
|
msg.replace(msg.find("%s"), 2, item.getClass().getName(item));
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox(msg);
|
MWBase::Environment::get().getWindowManager()->messageBox(msg);
|
||||||
|
|
|
@ -670,7 +670,7 @@ namespace MWGui
|
||||||
// Therefore any value < 1 should show as an empty health bar. We do the same in statswindow :)
|
// Therefore any value < 1 should show as an empty health bar. We do the same in statswindow :)
|
||||||
mEnemyHealth->setProgressPosition(static_cast<size_t>(stats.getHealth().getCurrent() / stats.getHealth().getModified() * 100));
|
mEnemyHealth->setProgressPosition(static_cast<size_t>(stats.getHealth().getCurrent() / stats.getHealth().getModified() * 100));
|
||||||
|
|
||||||
static const float fNPCHealthBarFade = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fNPCHealthBarFade")->getFloat();
|
static const float fNPCHealthBarFade = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fNPCHealthBarFade")->mValue.getFloat();
|
||||||
if (fNPCHealthBarFade > 0.f)
|
if (fNPCHealthBarFade > 0.f)
|
||||||
mEnemyHealth->setAlpha(std::max(0.f, std::min(1.f, mEnemyHealthTimer/fNPCHealthBarFade)));
|
mEnemyHealth->setAlpha(std::max(0.f, std::min(1.f, mEnemyHealthTimer/fNPCHealthBarFade)));
|
||||||
|
|
||||||
|
@ -679,7 +679,7 @@ namespace MWGui
|
||||||
void HUD::setEnemy(const MWWorld::Ptr &enemy)
|
void HUD::setEnemy(const MWWorld::Ptr &enemy)
|
||||||
{
|
{
|
||||||
mEnemyActorId = enemy.getClass().getCreatureStats(enemy).getActorId();
|
mEnemyActorId = enemy.getClass().getCreatureStats(enemy).getActorId();
|
||||||
mEnemyHealthTimer = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fNPCHealthBarTime")->getFloat();
|
mEnemyHealthTimer = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fNPCHealthBarTime")->mValue.getFloat();
|
||||||
if (!mEnemyHealth->getVisible())
|
if (!mEnemyHealth->getVisible())
|
||||||
mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() - MyGUI::IntPoint(0,20));
|
mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() - MyGUI::IntPoint(0,20));
|
||||||
mEnemyHealth->setVisible(true);
|
mEnemyHealth->setVisible(true);
|
||||||
|
|
|
@ -82,6 +82,7 @@ namespace MWGui
|
||||||
, mPreview(new MWRender::InventoryPreview(parent, resourceSystem, MWMechanics::getPlayer()))
|
, mPreview(new MWRender::InventoryPreview(parent, resourceSystem, MWMechanics::getPlayer()))
|
||||||
, mTrading(false)
|
, mTrading(false)
|
||||||
, mScaleFactor(1.0f)
|
, mScaleFactor(1.0f)
|
||||||
|
, mUpdateTimer(0.f)
|
||||||
{
|
{
|
||||||
float uiScale = Settings::Manager::getFloat("scaling factor", "GUI");
|
float uiScale = Settings::Manager::getFloat("scaling factor", "GUI");
|
||||||
if (uiScale > 1.0)
|
if (uiScale > 1.0)
|
||||||
|
@ -655,6 +656,22 @@ namespace MWGui
|
||||||
void InventoryWindow::onFrame(float dt)
|
void InventoryWindow::onFrame(float dt)
|
||||||
{
|
{
|
||||||
updateEncumbranceBar();
|
updateEncumbranceBar();
|
||||||
|
|
||||||
|
if (mPinned)
|
||||||
|
{
|
||||||
|
mUpdateTimer += dt;
|
||||||
|
if (0.1f < mUpdateTimer)
|
||||||
|
{
|
||||||
|
mUpdateTimer = 0;
|
||||||
|
|
||||||
|
// Update pinned inventory in-game
|
||||||
|
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||||
|
{
|
||||||
|
mItemView->update();
|
||||||
|
notifyContentChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::setTrading(bool trading)
|
void InventoryWindow::setTrading(bool trading)
|
||||||
|
@ -705,6 +722,8 @@ namespace MWGui
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int count = object.getRefData().getCount();
|
int count = object.getRefData().getCount();
|
||||||
|
if (object.getClass().isGold(object))
|
||||||
|
count *= object.getClass().getValue(object);
|
||||||
|
|
||||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||||
MWBase::Environment::get().getWorld()->breakInvisibility(player);
|
MWBase::Environment::get().getWorld()->breakInvisibility(player);
|
||||||
|
|
|
@ -102,6 +102,7 @@ namespace MWGui
|
||||||
|
|
||||||
bool mTrading;
|
bool mTrading;
|
||||||
float mScaleFactor;
|
float mScaleFactor;
|
||||||
|
float mUpdateTimer;
|
||||||
|
|
||||||
void onItemSelected(int index);
|
void onItemSelected(int index);
|
||||||
void onItemSelectedFromSourceModel(int index);
|
void onItemSelectedFromSourceModel(int index);
|
||||||
|
|
|
@ -163,9 +163,9 @@ namespace MWGui
|
||||||
|
|
||||||
std::string message;
|
std::string message;
|
||||||
if (mDays == 1)
|
if (mDays == 1)
|
||||||
message = gmst.find("sNotifyMessage42")->getString();
|
message = gmst.find("sNotifyMessage42")->mValue.getString();
|
||||||
else
|
else
|
||||||
message = gmst.find("sNotifyMessage43")->getString();
|
message = gmst.find("sNotifyMessage43")->mValue.getString();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Start of tes3mp addition
|
Start of tes3mp addition
|
||||||
|
@ -185,10 +185,10 @@ namespace MWGui
|
||||||
|
|
||||||
for (std::set<int>::iterator it = skills.begin(); it != skills.end(); ++it)
|
for (std::set<int>::iterator it = skills.begin(); it != skills.end(); ++it)
|
||||||
{
|
{
|
||||||
std::string skillName = gmst.find(ESM::Skill::sSkillNameIds[*it])->getString();
|
std::string skillName = gmst.find(ESM::Skill::sSkillNameIds[*it])->mValue.getString();
|
||||||
std::stringstream skillValue;
|
std::stringstream skillValue;
|
||||||
skillValue << player.getClass().getNpcStats(player).getSkill(*it).getBase();
|
skillValue << player.getClass().getNpcStats(player).getSkill(*it).getBase();
|
||||||
std::string skillMsg = gmst.find("sNotifyMessage44")->getString();
|
std::string skillMsg = gmst.find("sNotifyMessage44")->mValue.getString();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Start of tes3mp change (minor)
|
Start of tes3mp change (minor)
|
||||||
|
@ -200,7 +200,7 @@ namespace MWGui
|
||||||
/*
|
/*
|
||||||
End of tes3mp change (minor)
|
End of tes3mp change (minor)
|
||||||
*/
|
*/
|
||||||
skillMsg = gmst.find("sNotifyMessage39")->getString();
|
skillMsg = gmst.find("sNotifyMessage39")->mValue.getString();
|
||||||
|
|
||||||
if (skillMsg.find("%s") != std::string::npos)
|
if (skillMsg.find("%s") != std::string::npos)
|
||||||
skillMsg.replace(skillMsg.find("%s"), 2, skillName);
|
skillMsg.replace(skillMsg.find("%s"), 2, skillName);
|
||||||
|
|
|
@ -57,7 +57,7 @@ void MerchantRepair::setPtr(const MWWorld::Ptr &actor)
|
||||||
|
|
||||||
int basePrice = iter->getClass().getValue(*iter);
|
int basePrice = iter->getClass().getValue(*iter);
|
||||||
float fRepairMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
float fRepairMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fRepairMult")->getFloat();
|
.find("fRepairMult")->mValue.getFloat();
|
||||||
|
|
||||||
float p = static_cast<float>(std::max(1, basePrice));
|
float p = static_cast<float>(std::max(1, basePrice));
|
||||||
float r = static_cast<float>(std::max(1, static_cast<int>(maxDurability / p)));
|
float r = static_cast<float>(std::max(1, static_cast<int>(maxDurability / p)));
|
||||||
|
@ -71,7 +71,7 @@ void MerchantRepair::setPtr(const MWWorld::Ptr &actor)
|
||||||
std::string name = iter->getClass().getName(*iter)
|
std::string name = iter->getClass().getName(*iter)
|
||||||
+ " - " + MyGUI::utility::toString(price)
|
+ " - " + MyGUI::utility::toString(price)
|
||||||
+ MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
+ MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("sgp")->getString();
|
.find("sgp")->mValue.getString();
|
||||||
|
|
||||||
|
|
||||||
MyGUI::Button* button =
|
MyGUI::Button* button =
|
||||||
|
|
|
@ -199,19 +199,18 @@ void Recharge::onItemClicked(MyGUI::Widget *sender, const MWWorld::Ptr& item)
|
||||||
MWBase::Environment::get().getWindowManager()->playSound("Enchant Success");
|
MWBase::Environment::get().getWindowManager()->playSound("Enchant Success");
|
||||||
|
|
||||||
player.getClass().getContainerStore(player).restack(item);
|
player.getClass().getContainerStore(player).restack(item);
|
||||||
|
|
||||||
player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->playSound("Enchant Fail");
|
MWBase::Environment::get().getWindowManager()->playSound("Enchant Fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0);
|
||||||
gem.getContainerStore()->remove(gem, 1, player);
|
gem.getContainerStore()->remove(gem, 1, player);
|
||||||
|
|
||||||
if (gem.getRefData().getCount() == 0)
|
if (gem.getRefData().getCount() == 0)
|
||||||
{
|
{
|
||||||
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage51")->getString();
|
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage51")->mValue.getString();
|
||||||
message = boost::str(boost::format(message) % gem.getClass().getName(gem));
|
message = boost::str(boost::format(message) % gem.getClass().getName(gem));
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox(message);
|
MWBase::Environment::get().getWindowManager()->messageBox(message);
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace MWGui
|
||||||
const MWWorld::ESMStore &store =
|
const MWWorld::ESMStore &store =
|
||||||
MWBase::Environment::get().getWorld()->getStore();
|
MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
int price = static_cast<int>(spell.mData.mCost*store.get<ESM::GameSetting>().find("fSpellValueMult")->getFloat());
|
int price = static_cast<int>(spell.mData.mCost*store.get<ESM::GameSetting>().find("fSpellValueMult")->mValue.getFloat());
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
||||||
|
|
||||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||||
|
|
|
@ -44,8 +44,8 @@ namespace
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
return gmst.find(ESM::MagicEffect::effectIdToString (id1))->getString()
|
return gmst.find(ESM::MagicEffect::effectIdToString (id1))->mValue.getString()
|
||||||
< gmst.find(ESM::MagicEffect::effectIdToString (id2))->getString();
|
< gmst.find(ESM::MagicEffect::effectIdToString (id2))->mValue.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(ESM::ENAMstruct& effect)
|
void init(ESM::ENAMstruct& effect)
|
||||||
|
@ -495,7 +495,7 @@ namespace MWGui
|
||||||
mMagickaCost->setCaption(MyGUI::utility::toString(int(y)));
|
mMagickaCost->setCaption(MyGUI::utility::toString(int(y)));
|
||||||
|
|
||||||
float fSpellMakingValueMult =
|
float fSpellMakingValueMult =
|
||||||
store.get<ESM::GameSetting>().find("fSpellMakingValueMult")->getFloat();
|
store.get<ESM::GameSetting>().find("fSpellMakingValueMult")->mValue.getFloat();
|
||||||
|
|
||||||
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, static_cast<int>(y * fSpellMakingValueMult),true);
|
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, static_cast<int>(y * fSpellMakingValueMult),true);
|
||||||
|
|
||||||
|
@ -573,7 +573,7 @@ namespace MWGui
|
||||||
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
|
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
|
||||||
{
|
{
|
||||||
mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find(
|
mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find(
|
||||||
ESM::MagicEffect::effectIdToString (*it))->getString());
|
ESM::MagicEffect::effectIdToString (*it))->mValue.getString());
|
||||||
mButtonMapping[i] = *it;
|
mButtonMapping[i] = *it;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -583,7 +583,7 @@ namespace MWGui
|
||||||
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
|
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
|
||||||
{
|
{
|
||||||
std::string name = MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find(
|
std::string name = MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find(
|
||||||
ESM::MagicEffect::effectIdToString (*it))->getString();
|
ESM::MagicEffect::effectIdToString (*it))->mValue.getString();
|
||||||
MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name);
|
MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name);
|
||||||
|
|
||||||
ToolTips::createMagicEffectToolTip (w, *it);
|
ToolTips::createMagicEffectToolTip (w, *it);
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace MWGui
|
||||||
|
|
||||||
std::string sourcesDescription;
|
std::string sourcesDescription;
|
||||||
|
|
||||||
static const float fadeTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fMagicStartIconBlink")->getFloat();
|
static const float fadeTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fMagicStartIconBlink")->mValue.getFloat();
|
||||||
|
|
||||||
for (std::vector<MagicEffectInfo>::const_iterator effectIt = it->second.begin();
|
for (std::vector<MagicEffectInfo>::const_iterator effectIt = it->second.begin();
|
||||||
effectIt != it->second.end(); ++effectIt)
|
effectIt != it->second.end(); ++effectIt)
|
||||||
|
|
|
@ -97,6 +97,10 @@ namespace MWGui
|
||||||
mUpdateTimer = 0;
|
mUpdateTimer = 0;
|
||||||
mSpellView->incrementalUpdate();
|
mSpellView->incrementalUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update effects in-game too if the window is pinned
|
||||||
|
if (mPinned && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||||
|
mSpellIcons->updateWidgets(mEffectBox, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpellWindow::updateSpells()
|
void SpellWindow::updateSpells()
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace MWGui
|
||||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
for (int i=0; names[i][0]; ++i)
|
for (int i=0; names[i][0]; ++i)
|
||||||
{
|
{
|
||||||
setText (names[i][0], store.get<ESM::GameSetting>().find (names[i][1])->getString());
|
setText (names[i][0], store.get<ESM::GameSetting>().find (names[i][1])->mValue.getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
getWidget(mSkillView, "SkillView");
|
getWidget(mSkillView, "SkillView");
|
||||||
|
@ -306,7 +306,7 @@ namespace MWGui
|
||||||
MyGUI::Widget* levelWidget;
|
MyGUI::Widget* levelWidget;
|
||||||
for (int i=0; i<2; ++i)
|
for (int i=0; i<2; ++i)
|
||||||
{
|
{
|
||||||
int max = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iLevelUpTotal")->getInt();
|
int max = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iLevelUpTotal")->mValue.getInteger();
|
||||||
getWidget(levelWidget, i==0 ? "Level_str" : "LevelText");
|
getWidget(levelWidget, i==0 ? "Level_str" : "LevelText");
|
||||||
levelWidget->setUserString("RangePosition_LevelProgress", MyGUI::utility::toString(PCstats.getLevelProgress()));
|
levelWidget->setUserString("RangePosition_LevelProgress", MyGUI::utility::toString(PCstats.getLevelProgress()));
|
||||||
levelWidget->setUserString("Range_LevelProgress", MyGUI::utility::toString(max));
|
levelWidget->setUserString("Range_LevelProgress", MyGUI::utility::toString(max));
|
||||||
|
|
|
@ -313,7 +313,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(it->mBase.getCellRef().getRefId(), mPtr))
|
if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(it->mBase.getCellRef().getRefId(), mPtr))
|
||||||
{
|
{
|
||||||
std::string msg = gmst.find("sNotifyMessage49")->getString();
|
std::string msg = gmst.find("sNotifyMessage49")->mValue.getString();
|
||||||
if (msg.find("%s") != std::string::npos)
|
if (msg.find("%s") != std::string::npos)
|
||||||
msg.replace(msg.find("%s"), 2, it->mBase.getClass().getName(it->mBase));
|
msg.replace(msg.find("%s"), 2, it->mBase.getClass().getName(it->mBase));
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox(msg);
|
MWBase::Environment::get().getWindowManager()->messageBox(msg);
|
||||||
|
@ -331,8 +331,8 @@ namespace MWGui
|
||||||
// apply disposition change if merchant is NPC
|
// apply disposition change if merchant is NPC
|
||||||
if ( mPtr.getClass().isNpc() ) {
|
if ( mPtr.getClass().isNpc() ) {
|
||||||
int dispositionDelta = offerAccepted
|
int dispositionDelta = offerAccepted
|
||||||
? gmst.find("iBarterSuccessDisposition")->getInt()
|
? gmst.find("iBarterSuccessDisposition")->mValue.getInteger()
|
||||||
: gmst.find("iBarterFailDisposition")->getInt();
|
: gmst.find("iBarterFailDisposition")->mValue.getInteger();
|
||||||
|
|
||||||
MWBase::Environment::get().getDialogueManager()->applyBarterDispositionChange(dispositionDelta);
|
MWBase::Environment::get().getDialogueManager()->applyBarterDispositionChange(dispositionDelta);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace MWGui
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
{
|
{
|
||||||
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
|
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer
|
||||||
(mPtr,pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true);
|
(mPtr,pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->mValue.getInteger(),true);
|
||||||
|
|
||||||
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip
|
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip
|
||||||
MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);
|
MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);
|
||||||
|
@ -136,7 +136,7 @@ namespace MWGui
|
||||||
const MWWorld::ESMStore &store =
|
const MWWorld::ESMStore &store =
|
||||||
MWBase::Environment::get().getWorld()->getStore();
|
MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
int price = pcStats.getSkill (skillId).getBase() * store.get<ESM::GameSetting>().find("iTrainingMod")->getInt ();
|
int price = pcStats.getSkill (skillId).getBase() * store.get<ESM::GameSetting>().find("iTrainingMod")->mValue.getInteger();
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true);
|
||||||
|
|
||||||
if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId))
|
if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId))
|
||||||
|
|
|
@ -58,13 +58,13 @@ namespace MWGui
|
||||||
|
|
||||||
if (!mPtr.getCell()->isExterior())
|
if (!mPtr.getCell()->isExterior())
|
||||||
{
|
{
|
||||||
price = gmst.find("fMagesGuildTravel")->getInt();
|
price = gmst.find("fMagesGuildTravel")->mValue.getInteger();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ESM::Position PlayerPos = player.getRefData().getPosition();
|
ESM::Position PlayerPos = player.getRefData().getPosition();
|
||||||
float d = sqrt(pow(pos.pos[0] - PlayerPos.pos[0], 2) + pow(pos.pos[1] - PlayerPos.pos[1], 2) + pow(pos.pos[2] - PlayerPos.pos[2], 2));
|
float d = sqrt(pow(pos.pos[0] - PlayerPos.pos[0], 2) + pow(pos.pos[1] - PlayerPos.pos[1], 2) + pow(pos.pos[2] - PlayerPos.pos[2], 2));
|
||||||
price = static_cast<int>(d / gmst.find("fTravelMult")->getFloat());
|
price = static_cast<int>(d / gmst.find("fTravelMult")->mValue.getFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
||||||
|
@ -176,7 +176,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
ESM::Position playerPos = player.getRefData().getPosition();
|
ESM::Position playerPos = player.getRefData().getPosition();
|
||||||
float d = (osg::Vec3f(pos.pos[0], pos.pos[1], 0) - osg::Vec3f(playerPos.pos[0], playerPos.pos[1], 0)).length();
|
float d = (osg::Vec3f(pos.pos[0], pos.pos[1], 0) - osg::Vec3f(playerPos.pos[0], playerPos.pos[1], 0)).length();
|
||||||
int hours = static_cast<int>(d /MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTravelTimeMult")->getFloat());
|
int hours = static_cast<int>(d /MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTravelTimeMult")->mValue.getFloat());
|
||||||
for(int i = 0;i < hours;i++)
|
for(int i = 0;i < hours;i++)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getMechanicsManager ()->rest (true);
|
MWBase::Environment::get().getMechanicsManager ()->rest (true);
|
||||||
|
|
|
@ -22,6 +22,8 @@ VideoWidget::VideoWidget()
|
||||||
setNeedKeyFocus(true);
|
setNeedKeyFocus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoWidget::~VideoWidget() = default;
|
||||||
|
|
||||||
void VideoWidget::setVFS(const VFS::Manager *vfs)
|
void VideoWidget::setVFS(const VFS::Manager *vfs)
|
||||||
{
|
{
|
||||||
mVFS = vfs;
|
mVFS = vfs;
|
||||||
|
|
|
@ -25,6 +25,8 @@ namespace MWGui
|
||||||
MYGUI_RTTI_DERIVED(VideoWidget)
|
MYGUI_RTTI_DERIVED(VideoWidget)
|
||||||
|
|
||||||
VideoWidget();
|
VideoWidget();
|
||||||
|
|
||||||
|
~VideoWidget();
|
||||||
|
|
||||||
/// Set the VFS (virtual file system) to find the videos on.
|
/// Set the VFS (virtual file system) to find the videos on.
|
||||||
void setVFS(const VFS::Manager* vfs);
|
void setVFS(const VFS::Manager* vfs);
|
||||||
|
|
|
@ -193,10 +193,10 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
// figure out if player will be woken while sleeping
|
// figure out if player will be woken while sleeping
|
||||||
int x = Misc::Rng::rollDice(hoursToWait);
|
int x = Misc::Rng::rollDice(hoursToWait);
|
||||||
float fSleepRandMod = world->getStore().get<ESM::GameSetting>().find("fSleepRandMod")->getFloat();
|
float fSleepRandMod = world->getStore().get<ESM::GameSetting>().find("fSleepRandMod")->mValue.getFloat();
|
||||||
if (x < fSleepRandMod * hoursToWait)
|
if (x < fSleepRandMod * hoursToWait)
|
||||||
{
|
{
|
||||||
float fSleepRestMod = world->getStore().get<ESM::GameSetting>().find("fSleepRestMod")->getFloat();
|
float fSleepRestMod = world->getStore().get<ESM::GameSetting>().find("fSleepRestMod")->mValue.getFloat();
|
||||||
int interruptAtHoursRemaining = int(fSleepRestMod * hoursToWait);
|
int interruptAtHoursRemaining = int(fSleepRestMod * hoursToWait);
|
||||||
if (interruptAtHoursRemaining != 0)
|
if (interruptAtHoursRemaining != 0)
|
||||||
{
|
{
|
||||||
|
@ -271,7 +271,7 @@ namespace MWGui
|
||||||
// trigger levelup if possible
|
// trigger levelup if possible
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
if (mSleeping && pcstats.getLevelProgress () >= gmst.find("iLevelUpTotal")->getInt())
|
if (mSleeping && pcstats.getLevelProgress () >= gmst.find("iLevelUpTotal")->mValue.getInteger())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode (GM_Levelup);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode (GM_Levelup);
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,7 +370,7 @@ namespace MWGui
|
||||||
mGuiModeStates[GM_Journal].mCloseSound = "book close";
|
mGuiModeStates[GM_Journal].mCloseSound = "book close";
|
||||||
mGuiModeStates[GM_Journal].mOpenSound = "book open";
|
mGuiModeStates[GM_Journal].mOpenSound = "book open";
|
||||||
|
|
||||||
mMessageBoxManager = new MessageBoxManager(mStore->get<ESM::GameSetting>().find("fMessageTimePerChar")->getFloat());
|
mMessageBoxManager = new MessageBoxManager(mStore->get<ESM::GameSetting>().find("fMessageTimePerChar")->mValue.getFloat());
|
||||||
|
|
||||||
SpellBuyingWindow* spellBuyingWindow = new SpellBuyingWindow();
|
SpellBuyingWindow* spellBuyingWindow = new SpellBuyingWindow();
|
||||||
mWindows.push_back(spellBuyingWindow);
|
mWindows.push_back(spellBuyingWindow);
|
||||||
|
|
|
@ -1284,7 +1284,7 @@ namespace MWInput
|
||||||
void InputManager::updateIdleTime(float dt)
|
void InputManager::updateIdleTime(float dt)
|
||||||
{
|
{
|
||||||
static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fVanityDelay")->getFloat();
|
.find("fVanityDelay")->mValue.getFloat();
|
||||||
if (mTimeIdle >= 0.f)
|
if (mTimeIdle >= 0.f)
|
||||||
mTimeIdle += dt;
|
mTimeIdle += dt;
|
||||||
if (mTimeIdle > vanityDelay) {
|
if (mTimeIdle > vanityDelay) {
|
||||||
|
|
|
@ -197,8 +197,14 @@ namespace MWMechanics
|
||||||
|
|
||||||
void ActiveSpells::removeEffects(const std::string &id)
|
void ActiveSpells::removeEffects(const std::string &id)
|
||||||
{
|
{
|
||||||
mSpells.erase(Misc::StringUtils::lowerCase(id));
|
for (TContainer::iterator spell = mSpells.begin(); spell != mSpells.end(); ++spell)
|
||||||
mSpellsChanged = true;
|
{
|
||||||
|
if (spell->first == id)
|
||||||
|
{
|
||||||
|
spell->second.mEffects.clear();
|
||||||
|
mSpellsChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActiveSpells::visitEffectSources(EffectSourceVisitor &visitor) const
|
void ActiveSpells::visitEffectSources(EffectSourceVisitor &visitor) const
|
||||||
|
|
|
@ -71,22 +71,22 @@ int getBoundItemSlot (const std::string& itemId)
|
||||||
static std::map<std::string, int> boundItemsMap;
|
static std::map<std::string, int> boundItemsMap;
|
||||||
if (boundItemsMap.empty())
|
if (boundItemsMap.empty())
|
||||||
{
|
{
|
||||||
std::string boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundBootsID")->getString();
|
std::string boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundBootsID")->mValue.getString();
|
||||||
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Boots;
|
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Boots;
|
||||||
|
|
||||||
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundCuirassID")->getString();
|
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundCuirassID")->mValue.getString();
|
||||||
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Cuirass;
|
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Cuirass;
|
||||||
|
|
||||||
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundLeftGauntletID")->getString();
|
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundLeftGauntletID")->mValue.getString();
|
||||||
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_LeftGauntlet;
|
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_LeftGauntlet;
|
||||||
|
|
||||||
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundRightGauntletID")->getString();
|
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundRightGauntletID")->mValue.getString();
|
||||||
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_RightGauntlet;
|
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_RightGauntlet;
|
||||||
|
|
||||||
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundHelmID")->getString();
|
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundHelmID")->mValue.getString();
|
||||||
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Helmet;
|
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_Helmet;
|
||||||
|
|
||||||
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundShieldID")->getString();
|
boundId = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sMagicBoundShieldID")->mValue.getString();
|
||||||
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_CarriedLeft;
|
boundItemsMap[boundId] = MWWorld::InventoryStore::Slot_CarriedLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float
|
||||||
magicka = 0;
|
magicka = 0;
|
||||||
if (!stunted)
|
if (!stunted)
|
||||||
{
|
{
|
||||||
float fRestMagicMult = settings.find("fRestMagicMult")->getFloat ();
|
float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat ();
|
||||||
magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
|
magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ namespace MWMechanics
|
||||||
if (caster.isEmpty() || !caster.getClass().isActor())
|
if (caster.isEmpty() || !caster.getClass().isActor())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static const float fSoulgemMult = world->getStore().get<ESM::GameSetting>().find("fSoulgemMult")->getFloat();
|
static const float fSoulgemMult = world->getStore().get<ESM::GameSetting>().find("fSoulgemMult")->mValue.getFloat();
|
||||||
|
|
||||||
int creatureSoulValue = mCreature.get<ESM::Creature>()->mBase->mData.mSoul;
|
int creatureSoulValue = mCreature.get<ESM::Creature>()->mBase->mData.mSoul;
|
||||||
if (creatureSoulValue == 0)
|
if (creatureSoulValue == 0)
|
||||||
|
@ -354,9 +354,9 @@ namespace MWMechanics
|
||||||
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance)
|
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance)
|
||||||
{
|
{
|
||||||
static const float fMaxHeadTrackDistance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const float fMaxHeadTrackDistance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fMaxHeadTrackDistance")->getFloat();
|
.find("fMaxHeadTrackDistance")->mValue.getFloat();
|
||||||
static const float fInteriorHeadTrackMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const float fInteriorHeadTrackMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fInteriorHeadTrackMult")->getFloat();
|
.find("fInteriorHeadTrackMult")->mValue.getFloat();
|
||||||
float maxDistance = fMaxHeadTrackDistance;
|
float maxDistance = fMaxHeadTrackDistance;
|
||||||
const ESM::Cell* currentCell = actor.getCell()->getCell();
|
const ESM::Cell* currentCell = actor.getCell()->getCell();
|
||||||
if (!currentCell->isExterior() && !(currentCell->mData.mFlags & ESM::Cell::QuasiEx))
|
if (!currentCell->isExterior() && !(currentCell->mData.mFlags & ESM::Cell::QuasiEx))
|
||||||
|
@ -523,7 +523,7 @@ namespace MWMechanics
|
||||||
if (actor1.getClass().isClass(actor1, "Guard") && !actor2.getClass().isNpc())
|
if (actor1.getClass().isClass(actor1, "Guard") && !actor2.getClass().isNpc())
|
||||||
{
|
{
|
||||||
// Check if the creature is too far
|
// Check if the creature is too far
|
||||||
static const float fAlarmRadius = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->getFloat();
|
static const float fAlarmRadius = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->mValue.getFloat();
|
||||||
if (sqrDist > fAlarmRadius * fAlarmRadius)
|
if (sqrDist > fAlarmRadius * fAlarmRadius)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -587,9 +587,9 @@ namespace MWMechanics
|
||||||
|
|
||||||
float base = 1.f;
|
float base = 1.f;
|
||||||
if (ptr == getPlayer())
|
if (ptr == getPlayer())
|
||||||
base = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fPCbaseMagickaMult")->getFloat();
|
base = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fPCbaseMagickaMult")->mValue.getFloat();
|
||||||
else
|
else
|
||||||
base = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fNPCbaseMagickaMult")->getFloat();
|
base = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fNPCbaseMagickaMult")->mValue.getFloat();
|
||||||
|
|
||||||
double magickaFactor = base +
|
double magickaFactor = base +
|
||||||
creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1;
|
creatureStats.getMagicEffects().get (EffectKey (ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1;
|
||||||
|
@ -637,9 +637,9 @@ namespace MWMechanics
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Restore fatigue
|
// Restore fatigue
|
||||||
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
|
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat ();
|
||||||
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
|
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat ();
|
||||||
float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat ();
|
float fEndFatigueMult = settings.find("fEndFatigueMult")->mValue.getFloat ();
|
||||||
|
|
||||||
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
||||||
x *= fEndFatigueMult * endurance;
|
x *= fEndFatigueMult * endurance;
|
||||||
|
@ -664,8 +664,8 @@ namespace MWMechanics
|
||||||
// Restore fatigue
|
// Restore fatigue
|
||||||
int endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified();
|
int endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified();
|
||||||
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
|
static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat ();
|
||||||
static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
|
static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat ();
|
||||||
|
|
||||||
float x = fFatigueReturnBase + fFatigueReturnMult * endurance;
|
float x = fFatigueReturnBase + fFatigueReturnMult * endurance;
|
||||||
|
|
||||||
|
@ -925,14 +925,14 @@ namespace MWMechanics
|
||||||
|
|
||||||
std::string itemGmst = it->second;
|
std::string itemGmst = it->second;
|
||||||
std::string item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
std::string item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
itemGmst)->getString();
|
itemGmst)->mValue.getString();
|
||||||
|
|
||||||
magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr);
|
magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr);
|
||||||
|
|
||||||
if (it->first == ESM::MagicEffect::BoundGloves)
|
if (it->first == ESM::MagicEffect::BoundGloves)
|
||||||
{
|
{
|
||||||
item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
item = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"sMagicBoundRightGauntletID")->getString();
|
"sMagicBoundRightGauntletID")->mValue.getString();
|
||||||
magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr);
|
magnitude > 0 ? addBoundItem(item, ptr) : removeBoundItem(item, ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +1008,7 @@ namespace MWMechanics
|
||||||
NpcStats &stats = ptr.getClass().getNpcStats(ptr);
|
NpcStats &stats = ptr.getClass().getNpcStats(ptr);
|
||||||
|
|
||||||
// When npc stats are just initialized, mTimeToStartDrowning == -1 and we should get value from GMST
|
// When npc stats are just initialized, mTimeToStartDrowning == -1 and we should get value from GMST
|
||||||
static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHoldBreathTime")->getFloat();
|
static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHoldBreathTime")->mValue.getFloat();
|
||||||
if (stats.getTimeToStartDrowning() == -1.f)
|
if (stats.getTimeToStartDrowning() == -1.f)
|
||||||
stats.setTimeToStartDrowning(fHoldBreathTime);
|
stats.setTimeToStartDrowning(fHoldBreathTime);
|
||||||
|
|
||||||
|
@ -1042,7 +1042,7 @@ namespace MWMechanics
|
||||||
if(timeLeft == 0.0f && !godmode)
|
if(timeLeft == 0.0f && !godmode)
|
||||||
{
|
{
|
||||||
// If drowning, apply 3 points of damage per second
|
// If drowning, apply 3 points of damage per second
|
||||||
static const float fSuffocationDamage = world->getStore().get<ESM::GameSetting>().find("fSuffocationDamage")->getFloat();
|
static const float fSuffocationDamage = world->getStore().get<ESM::GameSetting>().find("fSuffocationDamage")->mValue.getFloat();
|
||||||
DynamicStat<float> health = stats.getHealth();
|
DynamicStat<float> health = stats.getHealth();
|
||||||
health.setCurrent(health.getCurrent() - fSuffocationDamage*duration);
|
health.setCurrent(health.getCurrent() - fSuffocationDamage*duration);
|
||||||
stats.setHealth(health);
|
stats.setHealth(health);
|
||||||
|
@ -1179,7 +1179,7 @@ namespace MWMechanics
|
||||||
&& creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0)
|
&& creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0)
|
||||||
{
|
{
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
static const int cutoff = esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->getInt();
|
static const int cutoff = esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->mValue.getInteger();
|
||||||
// Force dialogue on sight if bounty is greater than the cutoff
|
// Force dialogue on sight if bounty is greater than the cutoff
|
||||||
// In vanilla morrowind, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or attack (>= 5000 bounty)
|
// In vanilla morrowind, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or attack (>= 5000 bounty)
|
||||||
if ( player.getClass().getNpcStats(player).getBounty() >= cutoff
|
if ( player.getClass().getNpcStats(player).getBounty() >= cutoff
|
||||||
|
@ -1187,7 +1187,7 @@ namespace MWMechanics
|
||||||
&& MWBase::Environment::get().getWorld()->getLOS(ptr, player)
|
&& MWBase::Environment::get().getWorld()->getLOS(ptr, player)
|
||||||
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr))
|
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr))
|
||||||
{
|
{
|
||||||
static const int iCrimeThresholdMultiplier = esmStore.get<ESM::GameSetting>().find("iCrimeThresholdMultiplier")->getInt();
|
static const int iCrimeThresholdMultiplier = esmStore.get<ESM::GameSetting>().find("iCrimeThresholdMultiplier")->mValue.getInteger();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Start of tes3mp change (major)
|
Start of tes3mp change (major)
|
||||||
|
@ -1675,9 +1675,9 @@ namespace MWMechanics
|
||||||
static float sneakSkillTimer = 0.f; // times sneak skill progress from "avoid notice"
|
static float sneakSkillTimer = 0.f; // times sneak skill progress from "avoid notice"
|
||||||
|
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
const int radius = esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->getInt();
|
const int radius = esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->mValue.getInteger();
|
||||||
|
|
||||||
static float fSneakUseDelay = esmStore.get<ESM::GameSetting>().find("fSneakUseDelay")->getFloat();
|
static float fSneakUseDelay = esmStore.get<ESM::GameSetting>().find("fSneakUseDelay")->mValue.getFloat();
|
||||||
|
|
||||||
if (sneakTimer >= fSneakUseDelay)
|
if (sneakTimer >= fSneakUseDelay)
|
||||||
sneakTimer = 0.f;
|
sneakTimer = 0.f;
|
||||||
|
@ -1921,7 +1921,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first);
|
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first);
|
||||||
if (animation)
|
if (animation)
|
||||||
animation->updateEffects(duration);
|
animation->updateEffects();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2037,6 +2037,8 @@ namespace MWMechanics
|
||||||
if (iteratedActor == getPlayer())
|
if (iteratedActor == getPlayer())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
const bool sameActor = (iteratedActor == actor);
|
||||||
|
|
||||||
const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor);
|
const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor);
|
||||||
if (stats.isDead())
|
if (stats.isDead())
|
||||||
continue;
|
continue;
|
||||||
|
@ -2045,14 +2047,13 @@ namespace MWMechanics
|
||||||
// Actors that are targeted by this actor's Follow or Escort packages also side with them
|
// Actors that are targeted by this actor's Follow or Escort packages also side with them
|
||||||
for (auto package = stats.getAiSequence().begin(); package != stats.getAiSequence().end(); ++package)
|
for (auto package = stats.getAiSequence().begin(); package != stats.getAiSequence().end(); ++package)
|
||||||
{
|
{
|
||||||
const MWWorld::Ptr &target = (*package)->getTarget();
|
if ((*package)->sideWithTarget() && !(*package)->getTarget().isEmpty())
|
||||||
if ((*package)->sideWithTarget() && !target.isEmpty())
|
|
||||||
{
|
{
|
||||||
if (iteratedActor == actor)
|
if (sameActor)
|
||||||
{
|
{
|
||||||
list.push_back(target);
|
list.push_back((*package)->getTarget());
|
||||||
}
|
}
|
||||||
else if (target == actor)
|
else if ((*package)->getTarget() == actor)
|
||||||
{
|
{
|
||||||
list.push_back(iteratedActor);
|
list.push_back(iteratedActor);
|
||||||
}
|
}
|
||||||
|
@ -2071,7 +2072,7 @@ namespace MWMechanics
|
||||||
for(PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
for(PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
||||||
{
|
{
|
||||||
const MWWorld::Ptr &iteratedActor = iter->first;
|
const MWWorld::Ptr &iteratedActor = iter->first;
|
||||||
if (iteratedActor == getPlayer())
|
if (iteratedActor == getPlayer() || iteratedActor == actor)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor);
|
const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor);
|
||||||
|
@ -2134,7 +2135,7 @@ namespace MWMechanics
|
||||||
for(PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
for(PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
||||||
{
|
{
|
||||||
const MWWorld::Ptr &iteratedActor = iter->first;
|
const MWWorld::Ptr &iteratedActor = iter->first;
|
||||||
if (iteratedActor == getPlayer())
|
if (iteratedActor == getPlayer() || iteratedActor == actor)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor);
|
const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor);
|
||||||
|
@ -2164,8 +2165,11 @@ namespace MWMechanics
|
||||||
getObjectsInRange(position, aiProcessingDistance, neighbors);
|
getObjectsInRange(position, aiProcessingDistance, neighbors);
|
||||||
for(auto neighbor = neighbors.begin(); neighbor != neighbors.end(); ++neighbor)
|
for(auto neighbor = neighbors.begin(); neighbor != neighbors.end(); ++neighbor)
|
||||||
{
|
{
|
||||||
|
if (*neighbor == actor)
|
||||||
|
continue;
|
||||||
|
|
||||||
const CreatureStats &stats = neighbor->getClass().getCreatureStats(*neighbor);
|
const CreatureStats &stats = neighbor->getClass().getCreatureStats(*neighbor);
|
||||||
if (stats.isDead() || *neighbor == actor)
|
if (stats.isDead())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (stats.getAiSequence().isInCombat(actor))
|
if (stats.getAiSequence().isInCombat(actor))
|
||||||
|
|
|
@ -19,7 +19,7 @@ MWMechanics::AiBreathe::AiBreathe()
|
||||||
|
|
||||||
bool MWMechanics::AiBreathe::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
bool MWMechanics::AiBreathe::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHoldBreathTime")->getFloat();
|
static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHoldBreathTime")->mValue.getFloat();
|
||||||
|
|
||||||
const MWWorld::Class& actorClass = actor.getClass();
|
const MWWorld::Class& actorClass = actor.getClass();
|
||||||
if (actorClass.isNpc())
|
if (actorClass.isNpc())
|
||||||
|
|
|
@ -417,7 +417,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
case AiCombatStorage::FleeState_RunToDestination:
|
case AiCombatStorage::FleeState_RunToDestination:
|
||||||
{
|
{
|
||||||
static const float fFleeDistance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fFleeDistance")->getFloat();
|
static const float fFleeDistance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fFleeDistance")->mValue.getFloat();
|
||||||
|
|
||||||
float dist = (actor.getRefData().getPosition().asVec3() - target.getRefData().getPosition().asVec3()).length();
|
float dist = (actor.getRefData().getPosition().asVec3() - target.getRefData().getPosition().asVec3()).length();
|
||||||
if ((dist > fFleeDistance && !storage.mLOS)
|
if ((dist > fFleeDistance && !storage.mLOS)
|
||||||
|
@ -604,13 +604,13 @@ namespace MWMechanics
|
||||||
|
|
||||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
float baseDelay = store.get<ESM::GameSetting>().find("fCombatDelayCreature")->getFloat();
|
float baseDelay = store.get<ESM::GameSetting>().find("fCombatDelayCreature")->mValue.getFloat();
|
||||||
if (actor.getClass().isNpc())
|
if (actor.getClass().isNpc())
|
||||||
{
|
{
|
||||||
baseDelay = store.get<ESM::GameSetting>().find("fCombatDelayNPC")->getFloat();
|
baseDelay = store.get<ESM::GameSetting>().find("fCombatDelayNPC")->mValue.getFloat();
|
||||||
|
|
||||||
//say a provoking combat phrase
|
//say a provoking combat phrase
|
||||||
int chance = store.get<ESM::GameSetting>().find("iVoiceAttackOdds")->getInt();
|
int chance = store.get<ESM::GameSetting>().find("iVoiceAttackOdds")->mValue.getInteger();
|
||||||
if (Misc::Rng::roll0to99() < chance)
|
if (Misc::Rng::roll0to99() < chance)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getDialogueManager()->say(actor, "attack");
|
MWBase::Environment::get().getDialogueManager()->say(actor, "attack");
|
||||||
|
@ -700,21 +700,21 @@ osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& t
|
||||||
// get projectile speed (depending on weapon type)
|
// get projectile speed (depending on weapon type)
|
||||||
if (weapType == ESM::Weapon::MarksmanThrown)
|
if (weapType == ESM::Weapon::MarksmanThrown)
|
||||||
{
|
{
|
||||||
static float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->getFloat();
|
static float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat();
|
||||||
static float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat();
|
static float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat();
|
||||||
|
|
||||||
projSpeed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * strength;
|
projSpeed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * strength;
|
||||||
}
|
}
|
||||||
else if (weapType != 0)
|
else if (weapType != 0)
|
||||||
{
|
{
|
||||||
static float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->getFloat();
|
static float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat();
|
||||||
static float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat();
|
static float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat();
|
||||||
|
|
||||||
projSpeed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * strength;
|
projSpeed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * strength;
|
||||||
}
|
}
|
||||||
else // weapType is 0 ==> it's a target spell projectile
|
else // weapType is 0 ==> it's a target spell projectile
|
||||||
{
|
{
|
||||||
projSpeed = gmst.find("fTargetSpellMaxSpeed")->getFloat();
|
projSpeed = gmst.find("fTargetSpellMaxSpeed")->mValue.getFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
// idea: perpendicular to dir to target speed components of target move vector and projectile vector should be the same
|
// idea: perpendicular to dir to target speed components of target move vector and projectile vector should be the same
|
||||||
|
|
|
@ -23,8 +23,8 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
float suggestCombatRange(int rangeTypes)
|
float suggestCombatRange(int rangeTypes)
|
||||||
{
|
{
|
||||||
static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fCombatDistance")->getFloat();
|
static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fCombatDistance")->mValue.getFloat();
|
||||||
static float fHandToHandReach = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHandToHandReach")->getFloat();
|
static float fHandToHandReach = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHandToHandReach")->mValue.getFloat();
|
||||||
|
|
||||||
// This distance is a possible distance of melee attack
|
// This distance is a possible distance of melee attack
|
||||||
static float distance = fCombatDistance * std::max(2.f, fHandToHandReach);
|
static float distance = fCombatDistance * std::max(2.f, fHandToHandReach);
|
||||||
|
@ -114,13 +114,13 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
isRanged = false;
|
isRanged = false;
|
||||||
|
|
||||||
static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fCombatDistance")->getFloat();
|
static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fCombatDistance")->mValue.getFloat();
|
||||||
static const float fProjectileMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fProjectileMaxSpeed")->getFloat();
|
static const float fProjectileMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fProjectileMaxSpeed")->mValue.getFloat();
|
||||||
|
|
||||||
if (mWeapon.isEmpty())
|
if (mWeapon.isEmpty())
|
||||||
{
|
{
|
||||||
static float fHandToHandReach =
|
static float fHandToHandReach =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHandToHandReach")->getFloat();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHandToHandReach")->mValue.getFloat();
|
||||||
return fHandToHandReach * fCombatDistance;
|
return fHandToHandReach * fCombatDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,11 +190,6 @@ namespace MWMechanics
|
||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
{
|
{
|
||||||
std::vector<int> equipmentSlots = it->getClass().getEquipmentSlots(*it).first;
|
|
||||||
if (std::find(equipmentSlots.begin(), equipmentSlots.end(), (int)MWWorld::InventoryStore::Slot_CarriedRight)
|
|
||||||
== equipmentSlots.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating);
|
float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating);
|
||||||
if (rating > bestActionRating)
|
if (rating > bestActionRating)
|
||||||
{
|
{
|
||||||
|
@ -215,14 +210,12 @@ namespace MWMechanics
|
||||||
|
|
||||||
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||||
{
|
{
|
||||||
const ESM::Spell* spell = it->first;
|
float rating = rateSpell(it->first, actor, enemy);
|
||||||
|
|
||||||
float rating = rateSpell(spell, actor, enemy);
|
|
||||||
if (rating > bestActionRating)
|
if (rating > bestActionRating)
|
||||||
{
|
{
|
||||||
bestActionRating = rating;
|
bestActionRating = rating;
|
||||||
bestAction.reset(new ActionSpell(spell->mId));
|
bestAction.reset(new ActionSpell(it->first->mId));
|
||||||
antiFleeRating = vanillaRateSpell(spell, actor, enemy);
|
antiFleeRating = vanillaRateSpell(it->first, actor, enemy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,11 +258,6 @@ namespace MWMechanics
|
||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
{
|
{
|
||||||
std::vector<int> equipmentSlots = it->getClass().getEquipmentSlots(*it).first;
|
|
||||||
if (std::find(equipmentSlots.begin(), equipmentSlots.end(), (int)MWWorld::InventoryStore::Slot_CarriedRight)
|
|
||||||
== equipmentSlots.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating);
|
float rating = rateWeapon(*it, actor, enemy, -1, bestArrowRating, bestBoltRating);
|
||||||
if (rating > bestActionRating)
|
if (rating > bestActionRating)
|
||||||
{
|
{
|
||||||
|
@ -280,9 +268,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
for (Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
|
||||||
{
|
{
|
||||||
const ESM::Spell* spell = it->first;
|
float rating = rateSpell(it->first, actor, enemy);
|
||||||
|
|
||||||
float rating = rateSpell(spell, actor, enemy);
|
|
||||||
if (rating > bestActionRating)
|
if (rating > bestActionRating)
|
||||||
{
|
{
|
||||||
bestActionRating = rating;
|
bestActionRating = rating;
|
||||||
|
@ -336,7 +322,7 @@ namespace MWMechanics
|
||||||
float dist = 1.0f;
|
float dist = 1.0f;
|
||||||
if (activeWeapon.isEmpty() && !selectedSpellId.empty() && !selectedEnchItem.isEmpty())
|
if (activeWeapon.isEmpty() && !selectedSpellId.empty() && !selectedEnchItem.isEmpty())
|
||||||
{
|
{
|
||||||
static const float fHandToHandReach = gmst.find("fHandToHandReach")->getFloat();
|
static const float fHandToHandReach = gmst.find("fHandToHandReach")->mValue.getFloat();
|
||||||
dist = fHandToHandReach;
|
dist = fHandToHandReach;
|
||||||
}
|
}
|
||||||
else if (stats.getDrawState() == MWMechanics::DrawState_Spell)
|
else if (stats.getDrawState() == MWMechanics::DrawState_Spell)
|
||||||
|
@ -375,7 +361,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float fTargetSpellMaxSpeed = gmst.find("fTargetSpellMaxSpeed")->getFloat();
|
static const float fTargetSpellMaxSpeed = gmst.find("fTargetSpellMaxSpeed")->mValue.getFloat();
|
||||||
dist *= std::max(1000.0f, fTargetSpellMaxSpeed);
|
dist *= std::max(1000.0f, fTargetSpellMaxSpeed);
|
||||||
}
|
}
|
||||||
else if (!activeWeapon.isEmpty())
|
else if (!activeWeapon.isEmpty())
|
||||||
|
@ -383,7 +369,7 @@ namespace MWMechanics
|
||||||
const ESM::Weapon* esmWeap = activeWeapon.get<ESM::Weapon>()->mBase;
|
const ESM::Weapon* esmWeap = activeWeapon.get<ESM::Weapon>()->mBase;
|
||||||
if (esmWeap->mData.mType >= ESM::Weapon::MarksmanBow)
|
if (esmWeap->mData.mType >= ESM::Weapon::MarksmanBow)
|
||||||
{
|
{
|
||||||
static const float fTargetSpellMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat();
|
static const float fTargetSpellMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat();
|
||||||
dist = fTargetSpellMaxSpeed;
|
dist = fTargetSpellMaxSpeed;
|
||||||
if (!activeAmmo.isEmpty())
|
if (!activeAmmo.isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -399,8 +385,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
dist = (dist > 0.f) ? dist : 1.0f;
|
dist = (dist > 0.f) ? dist : 1.0f;
|
||||||
|
|
||||||
static const float fCombatDistance = gmst.find("fCombatDistance")->getFloat();
|
static const float fCombatDistance = gmst.find("fCombatDistance")->mValue.getFloat();
|
||||||
static const float fCombatDistanceWerewolfMod = gmst.find("fCombatDistanceWerewolfMod")->getFloat();
|
static const float fCombatDistanceWerewolfMod = gmst.find("fCombatDistanceWerewolfMod")->mValue.getFloat();
|
||||||
|
|
||||||
float combatDistance = fCombatDistance;
|
float combatDistance = fCombatDistance;
|
||||||
if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
|
if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
|
||||||
|
@ -485,20 +471,20 @@ namespace MWMechanics
|
||||||
if (flee >= 100)
|
if (flee >= 100)
|
||||||
return flee;
|
return flee;
|
||||||
|
|
||||||
static const float fAIFleeHealthMult = gmst.find("fAIFleeHealthMult")->getFloat();
|
static const float fAIFleeHealthMult = gmst.find("fAIFleeHealthMult")->mValue.getFloat();
|
||||||
static const float fAIFleeFleeMult = gmst.find("fAIFleeFleeMult")->getFloat();
|
static const float fAIFleeFleeMult = gmst.find("fAIFleeFleeMult")->mValue.getFloat();
|
||||||
|
|
||||||
float healthPercentage = (stats.getHealth().getModified() == 0.0f)
|
float healthPercentage = (stats.getHealth().getModified() == 0.0f)
|
||||||
? 1.0f : stats.getHealth().getCurrent() / stats.getHealth().getModified();
|
? 1.0f : stats.getHealth().getCurrent() / stats.getHealth().getModified();
|
||||||
float rating = (1.0f - healthPercentage) * fAIFleeHealthMult + flee * fAIFleeFleeMult;
|
float rating = (1.0f - healthPercentage) * fAIFleeHealthMult + flee * fAIFleeFleeMult;
|
||||||
|
|
||||||
static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->getInt();
|
static const int iWereWolfLevelToAttack = gmst.find("iWereWolfLevelToAttack")->mValue.getInteger();
|
||||||
|
|
||||||
if (actor.getClass().isNpc() && enemy.getClass().isNpc())
|
if (actor.getClass().isNpc() && enemy.getClass().isNpc())
|
||||||
{
|
{
|
||||||
if (enemy.getClass().getNpcStats(enemy).isWerewolf() && stats.getLevel() < iWereWolfLevelToAttack)
|
if (enemy.getClass().getNpcStats(enemy).isWerewolf() && stats.getLevel() < iWereWolfLevelToAttack)
|
||||||
{
|
{
|
||||||
static const int iWereWolfFleeMod = gmst.find("iWereWolfFleeMod")->getInt();
|
static const int iWereWolfFleeMod = gmst.find("iWereWolfFleeMod")->mValue.getInteger();
|
||||||
rating = iWereWolfFleeMod;
|
rating = iWereWolfFleeMod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
||||||
{
|
{
|
||||||
if ((*it)->getTypeId() != AiPackage::TypeIdCombat) break;
|
if ((*it)->getTypeId() != AiPackage::TypeIdCombat) break;
|
||||||
|
|
||||||
MWWorld::Ptr target = static_cast<const AiCombat *>(*it)->getTarget();
|
MWWorld::Ptr target = (*it)->getTarget();
|
||||||
|
|
||||||
// target disappeared (e.g. summoned creatures)
|
// target disappeared (e.g. summoned creatures)
|
||||||
if (target.isEmpty())
|
if (target.isEmpty())
|
||||||
|
@ -242,11 +242,11 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
||||||
|
|
||||||
const ESM::Position &targetPos = target.getRefData().getPosition();
|
const ESM::Position &targetPos = target.getRefData().getPosition();
|
||||||
|
|
||||||
float distTo = (targetPos.asVec3() - vActorPos).length();
|
float distTo = (targetPos.asVec3() - vActorPos).length2();
|
||||||
|
|
||||||
// Small threshold for changing target
|
// Small threshold for changing target
|
||||||
if (it == mPackages.begin())
|
if (it == mPackages.begin())
|
||||||
distTo = std::max(0.f, distTo - 50.f);
|
distTo = std::max(0.f, distTo - 2500.f);
|
||||||
|
|
||||||
// if a target has higher priority than current target or has same priority but closer
|
// if a target has higher priority than current target or has same priority but closer
|
||||||
if (rating > bestRating || ((distTo < nearestDist) && rating == bestRating))
|
if (rating > bestRating || ((distTo < nearestDist) && rating == bestRating))
|
||||||
|
|
|
@ -495,7 +495,7 @@ namespace MWMechanics
|
||||||
MWWorld::Ptr player = getPlayer();
|
MWWorld::Ptr player = getPlayer();
|
||||||
|
|
||||||
static float fVoiceIdleOdds = MWBase::Environment::get().getWorld()->getStore()
|
static float fVoiceIdleOdds = MWBase::Environment::get().getWorld()->getStore()
|
||||||
.get<ESM::GameSetting>().find("fVoiceIdleOdds")->getFloat();
|
.get<ESM::GameSetting>().find("fVoiceIdleOdds")->mValue.getFloat();
|
||||||
|
|
||||||
float roll = Misc::Rng::rollProbability() * 10000.0f;
|
float roll = Misc::Rng::rollProbability() * 10000.0f;
|
||||||
|
|
||||||
|
@ -522,7 +522,7 @@ namespace MWMechanics
|
||||||
int hello = actor.getClass().getCreatureStats(actor).getAiSetting(CreatureStats::AI_Hello).getModified();
|
int hello = actor.getClass().getCreatureStats(actor).getAiSetting(CreatureStats::AI_Hello).getModified();
|
||||||
float helloDistance = static_cast<float>(hello);
|
float helloDistance = static_cast<float>(hello);
|
||||||
static int iGreetDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore()
|
static int iGreetDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore()
|
||||||
.get<ESM::GameSetting>().find("iGreetDistanceMultiplier")->getInt();
|
.get<ESM::GameSetting>().find("iGreetDistanceMultiplier")->mValue.getInteger();
|
||||||
|
|
||||||
helloDistance *= iGreetDistanceMultiplier;
|
helloDistance *= iGreetDistanceMultiplier;
|
||||||
|
|
||||||
|
@ -700,7 +700,7 @@ namespace MWMechanics
|
||||||
for(unsigned int counter = 0; counter < mIdle.size(); counter++)
|
for(unsigned int counter = 0; counter < mIdle.size(); counter++)
|
||||||
{
|
{
|
||||||
static float fIdleChanceMultiplier = MWBase::Environment::get().getWorld()->getStore()
|
static float fIdleChanceMultiplier = MWBase::Environment::get().getWorld()->getStore()
|
||||||
.get<ESM::GameSetting>().find("fIdleChanceMultiplier")->getFloat();
|
.get<ESM::GameSetting>().find("fIdleChanceMultiplier")->mValue.getFloat();
|
||||||
|
|
||||||
unsigned short idleChance = static_cast<unsigned short>(fIdleChanceMultiplier * mIdle[counter]);
|
unsigned short idleChance = static_cast<unsigned short>(fIdleChanceMultiplier * mIdle[counter]);
|
||||||
unsigned short randSelect = (int)(Misc::Rng::rollProbability() * int(100 / fIdleChanceMultiplier));
|
unsigned short randSelect = (int)(Misc::Rng::rollProbability() * int(100 / fIdleChanceMultiplier));
|
||||||
|
|
|
@ -153,11 +153,11 @@ void MWMechanics::Alchemy::updateEffects()
|
||||||
float x = getAlchemyFactor();
|
float x = getAlchemyFactor();
|
||||||
|
|
||||||
x *= mTools[ESM::Apparatus::MortarPestle].get<ESM::Apparatus>()->mBase->mData.mQuality;
|
x *= mTools[ESM::Apparatus::MortarPestle].get<ESM::Apparatus>()->mBase->mData.mQuality;
|
||||||
x *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionStrengthMult")->getFloat();
|
x *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionStrengthMult")->mValue.getFloat();
|
||||||
|
|
||||||
// value
|
// value
|
||||||
mValue = static_cast<int> (
|
mValue = static_cast<int> (
|
||||||
x * MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("iAlchemyMod")->getFloat());
|
x * MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("iAlchemyMod")->mValue.getFloat());
|
||||||
|
|
||||||
// build quantified effect list
|
// build quantified effect list
|
||||||
for (std::set<EffectKey>::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter)
|
for (std::set<EffectKey>::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter)
|
||||||
|
@ -173,13 +173,13 @@ void MWMechanics::Alchemy::updateEffects()
|
||||||
}
|
}
|
||||||
|
|
||||||
float fPotionT1MagMul =
|
float fPotionT1MagMul =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionT1MagMult")->getFloat();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionT1MagMult")->mValue.getFloat();
|
||||||
|
|
||||||
if (fPotionT1MagMul<=0)
|
if (fPotionT1MagMul<=0)
|
||||||
throw std::runtime_error ("invalid gmst: fPotionT1MagMul");
|
throw std::runtime_error ("invalid gmst: fPotionT1MagMul");
|
||||||
|
|
||||||
float fPotionT1DurMult =
|
float fPotionT1DurMult =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionT1DurMult")->getFloat();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fPotionT1DurMult")->mValue.getFloat();
|
||||||
|
|
||||||
if (fPotionT1DurMult<=0)
|
if (fPotionT1DurMult<=0)
|
||||||
throw std::runtime_error ("invalid gmst: fPotionT1DurMult");
|
throw std::runtime_error ("invalid gmst: fPotionT1DurMult");
|
||||||
|
@ -478,7 +478,7 @@ bool MWMechanics::Alchemy::knownEffect(unsigned int potionEffectIndex, const MWW
|
||||||
MWMechanics::NpcStats& npcStats = npc.getClass().getNpcStats(npc);
|
MWMechanics::NpcStats& npcStats = npc.getClass().getNpcStats(npc);
|
||||||
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase();
|
||||||
static const float fWortChanceValue =
|
static const float fWortChanceValue =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->getFloat();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->mValue.getFloat();
|
||||||
return (potionEffectIndex <= 1 && alchemySkill >= fWortChanceValue)
|
return (potionEffectIndex <= 1 && alchemySkill >= fWortChanceValue)
|
||||||
|| (potionEffectIndex <= 3 && alchemySkill >= fWortChanceValue*2)
|
|| (potionEffectIndex <= 3 && alchemySkill >= fWortChanceValue*2)
|
||||||
|| (potionEffectIndex <= 5 && alchemySkill >= fWortChanceValue*3)
|
|| (potionEffectIndex <= 5 && alchemySkill >= fWortChanceValue*3)
|
||||||
|
@ -532,5 +532,5 @@ std::string MWMechanics::Alchemy::suggestPotionName()
|
||||||
|
|
||||||
int effectId = effects.begin()->mId;
|
int effectId = effects.begin()->mId;
|
||||||
return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
ESM::MagicEffect::effectIdToString(effectId))->getString();
|
ESM::MagicEffect::effectIdToString(effectId))->mValue.getString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace MWMechanics
|
||||||
std::vector<std::string> autoCalcNpcSpells(const int *actorSkills, const int *actorAttributes, const ESM::Race* race)
|
std::vector<std::string> autoCalcNpcSpells(const int *actorSkills, const int *actorAttributes, const ESM::Race* race)
|
||||||
{
|
{
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
static const float fNPCbaseMagickaMult = gmst.find("fNPCbaseMagickaMult")->getFloat();
|
static const float fNPCbaseMagickaMult = gmst.find("fNPCbaseMagickaMult")->mValue.getFloat();
|
||||||
float baseMagicka = fNPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence];
|
float baseMagicka = fNPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence];
|
||||||
|
|
||||||
static const std::string schools[] = {
|
static const std::string schools[] = {
|
||||||
|
@ -38,7 +38,7 @@ namespace MWMechanics
|
||||||
for (int i=0; i<6; ++i)
|
for (int i=0; i<6; ++i)
|
||||||
{
|
{
|
||||||
const std::string& gmstName = "iAutoSpell" + schools[i] + "Max";
|
const std::string& gmstName = "iAutoSpell" + schools[i] + "Max";
|
||||||
iAutoSpellSchoolMax[i] = gmst.find(gmstName)->getInt();
|
iAutoSpellSchoolMax[i] = gmst.find(gmstName)->mValue.getInteger();
|
||||||
}
|
}
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ namespace MWMechanics
|
||||||
continue;
|
continue;
|
||||||
if (!(spell->mData.mFlags & ESM::Spell::F_Autocalc))
|
if (!(spell->mData.mFlags & ESM::Spell::F_Autocalc))
|
||||||
continue;
|
continue;
|
||||||
static const int iAutoSpellTimesCanCast = gmst.find("iAutoSpellTimesCanCast")->getInt();
|
static const int iAutoSpellTimesCanCast = gmst.find("iAutoSpellTimesCanCast")->mValue.getInteger();
|
||||||
if (baseMagicka < iAutoSpellTimesCanCast * spell->mData.mCost)
|
if (baseMagicka < iAutoSpellTimesCanCast * spell->mData.mCost)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ namespace MWMechanics
|
||||||
if (cap.mReachedLimit && spell->mData.mCost <= cap.mMinCost)
|
if (cap.mReachedLimit && spell->mData.mCost <= cap.mMinCost)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
static const float fAutoSpellChance = gmst.find("fAutoSpellChance")->getFloat();
|
static const float fAutoSpellChance = gmst.find("fAutoSpellChance")->mValue.getFloat();
|
||||||
if (calcAutoCastChance(spell, actorSkills, actorAttributes, school) < fAutoSpellChance)
|
if (calcAutoCastChance(spell, actorSkills, actorAttributes, school) < fAutoSpellChance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
static const float fPCbaseMagickaMult = esmStore.get<ESM::GameSetting>().find("fPCbaseMagickaMult")->getFloat();
|
static const float fPCbaseMagickaMult = esmStore.get<ESM::GameSetting>().find("fPCbaseMagickaMult")->mValue.getFloat();
|
||||||
|
|
||||||
float baseMagicka = fPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence];
|
float baseMagicka = fPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence];
|
||||||
bool reachedLimit = false;
|
bool reachedLimit = false;
|
||||||
|
@ -173,7 +173,7 @@ namespace MWMechanics
|
||||||
if (baseMagicka < spell->mData.mCost)
|
if (baseMagicka < spell->mData.mCost)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
static const float fAutoPCSpellChance = esmStore.get<ESM::GameSetting>().find("fAutoPCSpellChance")->getFloat();
|
static const float fAutoPCSpellChance = esmStore.get<ESM::GameSetting>().find("fAutoPCSpellChance")->mValue.getFloat();
|
||||||
if (calcAutoCastChance(spell, actorSkills, actorAttributes, -1) < fAutoPCSpellChance)
|
if (calcAutoCastChance(spell, actorSkills, actorAttributes, -1) < fAutoPCSpellChance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ namespace MWMechanics
|
||||||
weakestSpell = spell;
|
weakestSpell = spell;
|
||||||
minCost = weakestSpell->mData.mCost;
|
minCost = weakestSpell->mData.mCost;
|
||||||
}
|
}
|
||||||
static const unsigned int iAutoPCSpellMax = esmStore.get<ESM::GameSetting>().find("iAutoPCSpellMax")->getInt();
|
static const unsigned int iAutoPCSpellMax = esmStore.get<ESM::GameSetting>().find("iAutoPCSpellMax")->mValue.getInteger();
|
||||||
if (selectedSpells.size() == iAutoPCSpellMax)
|
if (selectedSpells.size() == iAutoPCSpellMax)
|
||||||
reachedLimit = true;
|
reachedLimit = true;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ namespace MWMechanics
|
||||||
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt)
|
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt)
|
||||||
{
|
{
|
||||||
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectIt->mEffectID);
|
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effectIt->mEffectID);
|
||||||
static const int iAutoSpellAttSkillMin = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iAutoSpellAttSkillMin")->getInt();
|
static const int iAutoSpellAttSkillMin = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iAutoSpellAttSkillMin")->mValue.getInteger();
|
||||||
|
|
||||||
if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill))
|
if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill))
|
||||||
{
|
{
|
||||||
|
@ -278,7 +278,7 @@ namespace MWMechanics
|
||||||
duration = effect.mDuration;
|
duration = effect.mDuration;
|
||||||
|
|
||||||
static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore()
|
static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore()
|
||||||
.get<ESM::GameSetting>().find("fEffectCostMult")->getFloat();
|
.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
|
||||||
|
|
||||||
float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn));
|
float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn));
|
||||||
x *= 0.1 * magicEffect->mData.mBaseCost;
|
x *= 0.1 * magicEffect->mData.mBaseCost;
|
||||||
|
|
|
@ -139,16 +139,16 @@ float getFallDamage(const MWWorld::Ptr& ptr, float fallHeight)
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const MWWorld::Store<ESM::GameSetting> &store = world->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &store = world->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
const float fallDistanceMin = store.find("fFallDamageDistanceMin")->getFloat();
|
const float fallDistanceMin = store.find("fFallDamageDistanceMin")->mValue.getFloat();
|
||||||
|
|
||||||
if (fallHeight >= fallDistanceMin)
|
if (fallHeight >= fallDistanceMin)
|
||||||
{
|
{
|
||||||
const float acrobaticsSkill = static_cast<float>(ptr.getClass().getSkill(ptr, ESM::Skill::Acrobatics));
|
const float acrobaticsSkill = static_cast<float>(ptr.getClass().getSkill(ptr, ESM::Skill::Acrobatics));
|
||||||
const float jumpSpellBonus = ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude();
|
const float jumpSpellBonus = ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude();
|
||||||
const float fallAcroBase = store.find("fFallAcroBase")->getFloat();
|
const float fallAcroBase = store.find("fFallAcroBase")->mValue.getFloat();
|
||||||
const float fallAcroMult = store.find("fFallAcroMult")->getFloat();
|
const float fallAcroMult = store.find("fFallAcroMult")->mValue.getFloat();
|
||||||
const float fallDistanceBase = store.find("fFallDistanceBase")->getFloat();
|
const float fallDistanceBase = store.find("fFallDistanceBase")->mValue.getFloat();
|
||||||
const float fallDistanceMult = store.find("fFallDistanceMult")->getFloat();
|
const float fallDistanceMult = store.find("fFallDistanceMult")->mValue.getFloat();
|
||||||
|
|
||||||
float x = fallHeight - fallDistanceMin;
|
float x = fallHeight - fallDistanceMin;
|
||||||
x -= (1.5f * acrobaticsSkill) + jumpSpellBonus;
|
x -= (1.5f * acrobaticsSkill) + jumpSpellBonus;
|
||||||
|
@ -968,11 +968,14 @@ void CharacterController::handleTextKey(const std::string &groupname, const std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (soundgen == "land") // Morrowind ignores land soundgen for some reason
|
||||||
|
return;
|
||||||
|
|
||||||
std::string sound = mPtr.getClass().getSoundIdFromSndGen(mPtr, soundgen);
|
std::string sound = mPtr.getClass().getSoundIdFromSndGen(mPtr, soundgen);
|
||||||
if(!sound.empty())
|
if(!sound.empty())
|
||||||
{
|
{
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
if(evt.compare(10, evt.size()-10, "left") == 0 || evt.compare(10, evt.size()-10, "right") == 0 || evt.compare(10, evt.size()-10, "land") == 0)
|
if(soundgen == "left" || soundgen == "right")
|
||||||
{
|
{
|
||||||
// Don't make foot sounds local for the player, it makes sense to keep them
|
// Don't make foot sounds local for the player, it makes sense to keep them
|
||||||
// positioned on the ground.
|
// positioned on the ground.
|
||||||
|
@ -1910,10 +1913,11 @@ void CharacterController::update(float duration)
|
||||||
else if(!cls.getCreatureStats(mPtr).isDead())
|
else if(!cls.getCreatureStats(mPtr).isDead())
|
||||||
{
|
{
|
||||||
bool onground = world->isOnGround(mPtr);
|
bool onground = world->isOnGround(mPtr);
|
||||||
|
bool incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown());
|
||||||
bool inwater = world->isSwimming(mPtr);
|
bool inwater = world->isSwimming(mPtr);
|
||||||
bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak);
|
|
||||||
bool flying = world->isFlying(mPtr);
|
bool flying = world->isFlying(mPtr);
|
||||||
// Can't run while flying (see speed formula in Npc/Creature::getSpeed)
|
// Can't run and sneak while flying (see speed formula in Npc/Creature::getSpeed)
|
||||||
|
bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying;
|
||||||
bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying;
|
bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying;
|
||||||
CreatureStats &stats = cls.getCreatureStats(mPtr);
|
CreatureStats &stats = cls.getCreatureStats(mPtr);
|
||||||
|
|
||||||
|
@ -2025,14 +2029,14 @@ void CharacterController::update(float duration)
|
||||||
// reduce fatigue
|
// reduce fatigue
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||||
float fatigueLoss = 0;
|
float fatigueLoss = 0;
|
||||||
static const float fFatigueRunBase = gmst.find("fFatigueRunBase")->getFloat();
|
static const float fFatigueRunBase = gmst.find("fFatigueRunBase")->mValue.getFloat();
|
||||||
static const float fFatigueRunMult = gmst.find("fFatigueRunMult")->getFloat();
|
static const float fFatigueRunMult = gmst.find("fFatigueRunMult")->mValue.getFloat();
|
||||||
static const float fFatigueSwimWalkBase = gmst.find("fFatigueSwimWalkBase")->getFloat();
|
static const float fFatigueSwimWalkBase = gmst.find("fFatigueSwimWalkBase")->mValue.getFloat();
|
||||||
static const float fFatigueSwimRunBase = gmst.find("fFatigueSwimRunBase")->getFloat();
|
static const float fFatigueSwimRunBase = gmst.find("fFatigueSwimRunBase")->mValue.getFloat();
|
||||||
static const float fFatigueSwimWalkMult = gmst.find("fFatigueSwimWalkMult")->getFloat();
|
static const float fFatigueSwimWalkMult = gmst.find("fFatigueSwimWalkMult")->mValue.getFloat();
|
||||||
static const float fFatigueSwimRunMult = gmst.find("fFatigueSwimRunMult")->getFloat();
|
static const float fFatigueSwimRunMult = gmst.find("fFatigueSwimRunMult")->mValue.getFloat();
|
||||||
static const float fFatigueSneakBase = gmst.find("fFatigueSneakBase")->getFloat();
|
static const float fFatigueSneakBase = gmst.find("fFatigueSneakBase")->mValue.getFloat();
|
||||||
static const float fFatigueSneakMult = gmst.find("fFatigueSneakMult")->getFloat();
|
static const float fFatigueSneakMult = gmst.find("fFatigueSneakMult")->mValue.getFloat();
|
||||||
|
|
||||||
if (cls.getEncumbrance(mPtr) <= cls.getCapacity(mPtr))
|
if (cls.getEncumbrance(mPtr) <= cls.getCapacity(mPtr))
|
||||||
{
|
{
|
||||||
|
@ -2061,7 +2065,7 @@ void CharacterController::update(float duration)
|
||||||
cls.getCreatureStats(mPtr).setFatigue(fatigue);
|
cls.getCreatureStats(mPtr).setFatigue(fatigue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sneak || inwater || flying)
|
if(sneak || inwater || flying || incapacitated)
|
||||||
vec.z() = 0.0f;
|
vec.z() = 0.0f;
|
||||||
|
|
||||||
bool inJump = true;
|
bool inJump = true;
|
||||||
|
@ -2072,8 +2076,8 @@ void CharacterController::update(float duration)
|
||||||
forcestateupdate = (mJumpState != JumpState_InAir);
|
forcestateupdate = (mJumpState != JumpState_InAir);
|
||||||
jumpstate = JumpState_InAir;
|
jumpstate = JumpState_InAir;
|
||||||
|
|
||||||
static const float fJumpMoveBase = gmst.find("fJumpMoveBase")->getFloat();
|
static const float fJumpMoveBase = gmst.find("fJumpMoveBase")->mValue.getFloat();
|
||||||
static const float fJumpMoveMult = gmst.find("fJumpMoveMult")->getFloat();
|
static const float fJumpMoveMult = gmst.find("fJumpMoveMult")->mValue.getFloat();
|
||||||
float factor = fJumpMoveBase + fJumpMoveMult * mPtr.getClass().getSkill(mPtr, ESM::Skill::Acrobatics)/100.f;
|
float factor = fJumpMoveBase + fJumpMoveMult * mPtr.getClass().getSkill(mPtr, ESM::Skill::Acrobatics)/100.f;
|
||||||
factor = std::min(1.f, factor);
|
factor = std::min(1.f, factor);
|
||||||
vec.x() *= factor;
|
vec.x() *= factor;
|
||||||
|
@ -2100,8 +2104,8 @@ void CharacterController::update(float duration)
|
||||||
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0);
|
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0);
|
||||||
|
|
||||||
// decrease fatigue
|
// decrease fatigue
|
||||||
const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat();
|
const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat();
|
||||||
const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat();
|
const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat();
|
||||||
float normalizedEncumbrance = mPtr.getClass().getNormalizedEncumbrance(mPtr);
|
float normalizedEncumbrance = mPtr.getClass().getNormalizedEncumbrance(mPtr);
|
||||||
if (normalizedEncumbrance > 1)
|
if (normalizedEncumbrance > 1)
|
||||||
normalizedEncumbrance = 1;
|
normalizedEncumbrance = 1;
|
||||||
|
@ -2130,17 +2134,15 @@ void CharacterController::update(float duration)
|
||||||
// inflict fall damages
|
// inflict fall damages
|
||||||
if (!godmode)
|
if (!godmode)
|
||||||
{
|
{
|
||||||
DynamicStat<float> health = cls.getCreatureStats(mPtr).getHealth();
|
|
||||||
float realHealthLost = static_cast<float>(healthLost * (1.0f - 0.25f * fatigueTerm));
|
float realHealthLost = static_cast<float>(healthLost * (1.0f - 0.25f * fatigueTerm));
|
||||||
health.setCurrent(health.getCurrent() - realHealthLost);
|
|
||||||
cls.getCreatureStats(mPtr).setHealth(health);
|
|
||||||
cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), osg::Vec3f(), true);
|
cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), osg::Vec3f(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics);
|
const int acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics);
|
||||||
if (healthLost > (acrobaticsSkill * fatigueTerm))
|
if (healthLost > (acrobaticsSkill * fatigueTerm))
|
||||||
{
|
{
|
||||||
cls.getCreatureStats(mPtr).setKnockedDown(true);
|
if (!godmode)
|
||||||
|
cls.getCreatureStats(mPtr).setKnockedDown(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2149,6 +2151,12 @@ void CharacterController::update(float duration)
|
||||||
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1);
|
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Play landing sound
|
||||||
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
|
std::string sound = cls.getSoundIdFromSndGen(mPtr, "land");
|
||||||
|
if (!sound.empty())
|
||||||
|
sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2158,6 +2166,12 @@ void CharacterController::update(float duration)
|
||||||
|
|
||||||
inJump = false;
|
inJump = false;
|
||||||
|
|
||||||
|
// Do not play turning animation for player if rotation speed is very slow.
|
||||||
|
// Actual threshold should take framerate in account.
|
||||||
|
float rotationThreshold = 0;
|
||||||
|
if (mPtr == getPlayer())
|
||||||
|
rotationThreshold = 0.015 * 60 * duration;
|
||||||
|
|
||||||
if(std::abs(vec.x()/2.0f) > std::abs(vec.y()))
|
if(std::abs(vec.x()/2.0f) > std::abs(vec.y()))
|
||||||
{
|
{
|
||||||
if(vec.x() > 0.0f)
|
if(vec.x() > 0.0f)
|
||||||
|
@ -2182,9 +2196,9 @@ void CharacterController::update(float duration)
|
||||||
}
|
}
|
||||||
else if(rot.z() != 0.0f && !sneak && !(mPtr == getPlayer() && MWBase::Environment::get().getWorld()->isFirstPerson()))
|
else if(rot.z() != 0.0f && !sneak && !(mPtr == getPlayer() && MWBase::Environment::get().getWorld()->isFirstPerson()))
|
||||||
{
|
{
|
||||||
if(rot.z() > 0.0f)
|
if(rot.z() > rotationThreshold)
|
||||||
movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight;
|
movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight;
|
||||||
else if(rot.z() < 0.0f)
|
else if(rot.z() < -rotationThreshold)
|
||||||
movestate = inwater ? CharState_SwimTurnLeft : CharState_TurnLeft;
|
movestate = inwater ? CharState_SwimTurnLeft : CharState_TurnLeft;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2335,9 +2349,6 @@ void CharacterController::update(float duration)
|
||||||
moved *= (l / newLength);
|
moved *= (l / newLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSkipAnim)
|
|
||||||
mAnimation->updateEffects(duration);
|
|
||||||
|
|
||||||
if (mFloatToSurface && cls.isActor() && cls.getCreatureStats(mPtr).isDead() && cls.canSwim(mPtr))
|
if (mFloatToSurface && cls.isActor() && cls.getCreatureStats(mPtr).isDead() && cls.canSwim(mPtr))
|
||||||
moved.z() = 1.0;
|
moved.z() = 1.0;
|
||||||
|
|
||||||
|
|
|
@ -97,9 +97,9 @@ namespace MWMechanics
|
||||||
osg::Vec3f(0,0,1)));
|
osg::Vec3f(0,0,1)));
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
if (angleDegrees < gmst.find("fCombatBlockLeftAngle")->getFloat())
|
if (angleDegrees < gmst.find("fCombatBlockLeftAngle")->mValue.getFloat())
|
||||||
return false;
|
return false;
|
||||||
if (angleDegrees > gmst.find("fCombatBlockRightAngle")->getFloat())
|
if (angleDegrees > gmst.find("fCombatBlockRightAngle")->mValue.getFloat())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);
|
MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);
|
||||||
|
@ -107,11 +107,11 @@ namespace MWMechanics
|
||||||
float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2f * blockerStats.getAttribute(ESM::Attribute::Agility).getModified()
|
float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2f * blockerStats.getAttribute(ESM::Attribute::Agility).getModified()
|
||||||
+ 0.1f * blockerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
+ 0.1f * blockerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||||
float enemySwing = attackStrength;
|
float enemySwing = attackStrength;
|
||||||
float swingTerm = enemySwing * gmst.find("fSwingBlockMult")->getFloat() + gmst.find("fSwingBlockBase")->getFloat();
|
float swingTerm = enemySwing * gmst.find("fSwingBlockMult")->mValue.getFloat() + gmst.find("fSwingBlockBase")->mValue.getFloat();
|
||||||
|
|
||||||
float blockerTerm = blockTerm * swingTerm;
|
float blockerTerm = blockTerm * swingTerm;
|
||||||
if (blocker.getClass().getMovementSettings(blocker).mPosition[1] <= 0)
|
if (blocker.getClass().getMovementSettings(blocker).mPosition[1] <= 0)
|
||||||
blockerTerm *= gmst.find("fBlockStillBonus")->getFloat();
|
blockerTerm *= gmst.find("fBlockStillBonus")->mValue.getFloat();
|
||||||
blockerTerm *= blockerStats.getFatigueTerm();
|
blockerTerm *= blockerStats.getFatigueTerm();
|
||||||
|
|
||||||
int attackerSkill = 0;
|
int attackerSkill = 0;
|
||||||
|
@ -124,8 +124,8 @@ namespace MWMechanics
|
||||||
attackerTerm *= attackerStats.getFatigueTerm();
|
attackerTerm *= attackerStats.getFatigueTerm();
|
||||||
|
|
||||||
int x = int(blockerTerm - attackerTerm);
|
int x = int(blockerTerm - attackerTerm);
|
||||||
int iBlockMaxChance = gmst.find("iBlockMaxChance")->getInt();
|
int iBlockMaxChance = gmst.find("iBlockMaxChance")->mValue.getInteger();
|
||||||
int iBlockMinChance = gmst.find("iBlockMinChance")->getInt();
|
int iBlockMinChance = gmst.find("iBlockMinChance")->mValue.getInteger();
|
||||||
x = std::min(iBlockMaxChance, std::max(iBlockMinChance, x));
|
x = std::min(iBlockMaxChance, std::max(iBlockMinChance, x));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -165,9 +165,9 @@ namespace MWMechanics
|
||||||
inv.unequipItem(*shield, blocker);
|
inv.unequipItem(*shield, blocker);
|
||||||
}
|
}
|
||||||
// Reduce blocker fatigue
|
// Reduce blocker fatigue
|
||||||
const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->getFloat();
|
const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->mValue.getFloat();
|
||||||
const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat();
|
const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->mValue.getFloat();
|
||||||
const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->getFloat();
|
const float fWeaponFatigueBlockMult = gmst.find("fWeaponFatigueBlockMult")->mValue.getFloat();
|
||||||
MWMechanics::DynamicStat<float> fatigue = blockerStats.getFatigue();
|
MWMechanics::DynamicStat<float> fatigue = blockerStats.getFatigue();
|
||||||
float normalizedEncumbrance = blocker.getClass().getNormalizedEncumbrance(blocker);
|
float normalizedEncumbrance = blocker.getClass().getNormalizedEncumbrance(blocker);
|
||||||
normalizedEncumbrance = std::min(1.f, normalizedEncumbrance);
|
normalizedEncumbrance = std::min(1.f, normalizedEncumbrance);
|
||||||
|
@ -205,7 +205,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
if ((weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Silver)
|
if ((weapon.get<ESM::Weapon>()->mBase->mData.mFlags & ESM::Weapon::Silver)
|
||||||
&& actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
|
&& actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf())
|
||||||
damage *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWereWolfSilverWeaponDamageMult")->getFloat();
|
damage *= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWereWolfSilverWeaponDamageMult")->mValue.getFloat();
|
||||||
|
|
||||||
if (damage == 0 && attacker == getPlayer())
|
if (damage == 0 && attacker == getPlayer())
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}");
|
||||||
|
@ -302,14 +302,14 @@ namespace MWMechanics
|
||||||
|
|
||||||
if (unaware)
|
if (unaware)
|
||||||
{
|
{
|
||||||
damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat();
|
damage *= gmst.find("fCombatCriticalStrikeMult")->mValue.getFloat();
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||||
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (victim.getClass().getCreatureStats(victim).getKnockedDown())
|
if (victim.getClass().getCreatureStats(victim).getKnockedDown())
|
||||||
damage *= gmst.find("fCombatKODamageMult")->getFloat();
|
damage *= gmst.find("fCombatKODamageMult")->mValue.getFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
reduceWeaponCondition(damage, validVictim, weapon, attacker);
|
reduceWeaponCondition(damage, validVictim, weapon, attacker);
|
||||||
|
@ -343,7 +343,7 @@ namespace MWMechanics
|
||||||
// Non-enchanted arrows shot at enemies have a chance to turn up in their inventory
|
// Non-enchanted arrows shot at enemies have a chance to turn up in their inventory
|
||||||
if (victim != getPlayer() && !appliedEnchantment)
|
if (victim != getPlayer() && !appliedEnchantment)
|
||||||
{
|
{
|
||||||
float fProjectileThrownStoreChance = gmst.find("fProjectileThrownStoreChance")->getFloat();
|
float fProjectileThrownStoreChance = gmst.find("fProjectileThrownStoreChance")->mValue.getFloat();
|
||||||
if (Misc::Rng::rollProbability() < fProjectileThrownStoreChance / 100.f)
|
if (Misc::Rng::rollProbability() < fProjectileThrownStoreChance / 100.f)
|
||||||
victim.getClass().getContainerStore(victim).add(projectile, 1, victim);
|
victim.getClass().getContainerStore(victim).add(projectile, 1, victim);
|
||||||
}
|
}
|
||||||
|
@ -388,10 +388,10 @@ namespace MWMechanics
|
||||||
defenseTerm = victimStats.getEvasion();
|
defenseTerm = victimStats.getEvasion();
|
||||||
}
|
}
|
||||||
defenseTerm += std::min(100.f,
|
defenseTerm += std::min(100.f,
|
||||||
gmst.find("fCombatInvisoMult")->getFloat() *
|
gmst.find("fCombatInvisoMult")->mValue.getFloat() *
|
||||||
victimStats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude());
|
victimStats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude());
|
||||||
defenseTerm += std::min(100.f,
|
defenseTerm += std::min(100.f,
|
||||||
gmst.find("fCombatInvisoMult")->getFloat() *
|
gmst.find("fCombatInvisoMult")->mValue.getFloat() *
|
||||||
victimStats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude());
|
victimStats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude());
|
||||||
}
|
}
|
||||||
float attackTerm = skillValue +
|
float attackTerm = skillValue +
|
||||||
|
@ -437,7 +437,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
x = std::min(100.f, x + elementResistance);
|
x = std::min(100.f, x + elementResistance);
|
||||||
|
|
||||||
static const float fElementalShieldMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fElementalShieldMult")->getFloat();
|
static const float fElementalShieldMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fElementalShieldMult")->mValue.getFloat();
|
||||||
x = fElementalShieldMult * magnitude * (1.f - 0.01f * x);
|
x = fElementalShieldMult * magnitude * (1.f - 0.01f * x);
|
||||||
|
|
||||||
// Note swapped victim and attacker, since the attacker takes the damage here.
|
// Note swapped victim and attacker, since the attacker takes the damage here.
|
||||||
|
@ -467,7 +467,7 @@ namespace MWMechanics
|
||||||
// weapon condition does not degrade when godmode is on
|
// weapon condition does not degrade when godmode is on
|
||||||
if (!godmode)
|
if (!godmode)
|
||||||
{
|
{
|
||||||
const float fWeaponDamageMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWeaponDamageMult")->getFloat();
|
const float fWeaponDamageMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWeaponDamageMult")->mValue.getFloat();
|
||||||
float x = std::max(1.f, fWeaponDamageMult * damage);
|
float x = std::max(1.f, fWeaponDamageMult * damage);
|
||||||
|
|
||||||
weaphealth -= std::min(int(x), weaphealth);
|
weaphealth -= std::min(int(x), weaphealth);
|
||||||
|
@ -494,9 +494,9 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float fDamageStrengthBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const float fDamageStrengthBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fDamageStrengthBase")->getFloat();
|
.find("fDamageStrengthBase")->mValue.getFloat();
|
||||||
static const float fDamageStrengthMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const float fDamageStrengthMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fDamageStrengthMult")->getFloat();
|
.find("fDamageStrengthMult")->mValue.getFloat();
|
||||||
damage *= fDamageStrengthBase +
|
damage *= fDamageStrengthBase +
|
||||||
(attacker.getClass().getCreatureStats(attacker).getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult * 0.1f);
|
(attacker.getClass().getCreatureStats(attacker).getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult * 0.1f);
|
||||||
}
|
}
|
||||||
|
@ -504,8 +504,8 @@ namespace MWMechanics
|
||||||
void getHandToHandDamage(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, float &damage, bool &healthdmg, float attackStrength)
|
void getHandToHandDamage(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, float &damage, bool &healthdmg, float attackStrength)
|
||||||
{
|
{
|
||||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
float minstrike = store.get<ESM::GameSetting>().find("fMinHandToHandMult")->getFloat();
|
float minstrike = store.get<ESM::GameSetting>().find("fMinHandToHandMult")->mValue.getFloat();
|
||||||
float maxstrike = store.get<ESM::GameSetting>().find("fMaxHandToHandMult")->getFloat();
|
float maxstrike = store.get<ESM::GameSetting>().find("fMaxHandToHandMult")->mValue.getFloat();
|
||||||
damage = static_cast<float>(attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand));
|
damage = static_cast<float>(attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand));
|
||||||
damage *= minstrike + ((maxstrike-minstrike)*attackStrength);
|
damage *= minstrike + ((maxstrike-minstrike)*attackStrength);
|
||||||
|
|
||||||
|
@ -530,7 +530,7 @@ namespace MWMechanics
|
||||||
damage *= MWBase::Environment::get().getWorld()->getGlobalFloat("werewolfclawmult");
|
damage *= MWBase::Environment::get().getWorld()->getGlobalFloat("werewolfclawmult");
|
||||||
}
|
}
|
||||||
if(healthdmg)
|
if(healthdmg)
|
||||||
damage *= store.get<ESM::GameSetting>().find("fHandtoHandHealthPer")->getFloat();
|
damage *= store.get<ESM::GameSetting>().find("fHandtoHandHealthPer")->mValue.getFloat();
|
||||||
|
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
if(isWerewolf)
|
if(isWerewolf)
|
||||||
|
@ -547,9 +547,9 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
// somewhat of a guess, but using the weapon weight makes sense
|
// somewhat of a guess, but using the weapon weight makes sense
|
||||||
const MWWorld::Store<ESM::GameSetting>& store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
const float fFatigueAttackBase = store.find("fFatigueAttackBase")->getFloat();
|
const float fFatigueAttackBase = store.find("fFatigueAttackBase")->mValue.getFloat();
|
||||||
const float fFatigueAttackMult = store.find("fFatigueAttackMult")->getFloat();
|
const float fFatigueAttackMult = store.find("fFatigueAttackMult")->mValue.getFloat();
|
||||||
const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->getFloat();
|
const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->mValue.getFloat();
|
||||||
CreatureStats& stats = attacker.getClass().getCreatureStats(attacker);
|
CreatureStats& stats = attacker.getClass().getCreatureStats(attacker);
|
||||||
MWMechanics::DynamicStat<float> fatigue = stats.getFatigue();
|
MWMechanics::DynamicStat<float> fatigue = stats.getFatigue();
|
||||||
const float normalizedEncumbrance = attacker.getClass().getNormalizedEncumbrance(attacker);
|
const float normalizedEncumbrance = attacker.getClass().getNormalizedEncumbrance(attacker);
|
||||||
|
@ -574,9 +574,9 @@ namespace MWMechanics
|
||||||
float d = (pos1 - pos2).length();
|
float d = (pos1 - pos2).length();
|
||||||
|
|
||||||
static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"iFightDistanceBase")->getInt();
|
"iFightDistanceBase")->mValue.getInteger();
|
||||||
static const float fFightDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
static const float fFightDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"fFightDistanceMultiplier")->getFloat();
|
"fFightDistanceMultiplier")->mValue.getFloat();
|
||||||
|
|
||||||
return (iFightDistanceBase - fFightDistanceMultiplier * d);
|
return (iFightDistanceBase - fFightDistanceMultiplier * d);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,8 +59,8 @@ namespace MWMechanics
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
static const float fFatigueBase = gmst.find("fFatigueBase")->getFloat();
|
static const float fFatigueBase = gmst.find("fFatigueBase")->mValue.getFloat();
|
||||||
static const float fFatigueMult = gmst.find("fFatigueMult")->getFloat();
|
static const float fFatigueMult = gmst.find("fFatigueMult")->mValue.getFloat();
|
||||||
|
|
||||||
return fFatigueBase - fFatigueMult * (1-normalised);
|
return fFatigueBase - fFatigueMult * (1-normalised);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ float scaleDamage(float damage, const MWWorld::Ptr& attacker, const MWWorld::Ptr
|
||||||
End of tes3mp change (major)
|
End of tes3mp change (major)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const float fDifficultyMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDifficultyMult")->getFloat();
|
static const float fDifficultyMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDifficultyMult")->mValue.getFloat();
|
||||||
|
|
||||||
float difficultyTerm = 0.01f * difficultySetting;
|
float difficultyTerm = 0.01f * difficultySetting;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
float fDiseaseXferChance =
|
float fDiseaseXferChance =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"fDiseaseXferChance")->getFloat();
|
"fDiseaseXferChance")->mValue.getFloat();
|
||||||
|
|
||||||
MagicEffects& actorEffects = actor.getClass().getCreatureStats(actor).getMagicEffects();
|
MagicEffects& actorEffects = actor.getClass().getCreatureStats(actor).getMagicEffects();
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ namespace MWMechanics
|
||||||
actor.getClass().getCreatureStats(actor).getSpells().add(it->first);
|
actor.getClass().getCreatureStats(actor).getSpells().add(it->first);
|
||||||
|
|
||||||
std::string msg = "sMagicContractDisease";
|
std::string msg = "sMagicContractDisease";
|
||||||
msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(msg)->getString();
|
msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(msg)->mValue.getString();
|
||||||
if (msg.find("%s") != std::string::npos)
|
if (msg.find("%s") != std::string::npos)
|
||||||
msg.replace(msg.find("%s"), 2, spell->mName);
|
msg.replace(msg.find("%s"), 2, spell->mName);
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox(msg);
|
MWBase::Environment::get().getWindowManager()->messageBox(msg);
|
||||||
|
|
|
@ -136,7 +136,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool powerfulSoul = getGemCharge() >= \
|
const bool powerfulSoul = getGemCharge() >= \
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("iSoulAmountForConstantEffect")->getInt();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("iSoulAmountForConstantEffect")->mValue.getInteger();
|
||||||
if ((mObjectType == typeid(ESM::Armor).name()) || (mObjectType == typeid(ESM::Clothing).name()))
|
if ((mObjectType == typeid(ESM::Armor).name()) || (mObjectType == typeid(ESM::Clothing).name()))
|
||||||
{ // Armor or Clothing
|
{ // Armor or Clothing
|
||||||
switch(mCastStyle)
|
switch(mCastStyle)
|
||||||
|
@ -213,7 +213,7 @@ namespace MWMechanics
|
||||||
float magnitudeCost = (magMin + magMax) * baseCost * 0.05f;
|
float magnitudeCost = (magMin + magMax) * baseCost * 0.05f;
|
||||||
if (mCastStyle == ESM::Enchantment::ConstantEffect)
|
if (mCastStyle == ESM::Enchantment::ConstantEffect)
|
||||||
{
|
{
|
||||||
magnitudeCost *= store.get<ESM::GameSetting>().find("fEnchantmentConstantDurationMult")->getFloat();
|
magnitudeCost *= store.get<ESM::GameSetting>().find("fEnchantmentConstantDurationMult")->mValue.getFloat();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -222,7 +222,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
float areaCost = area * 0.05f * baseCost;
|
float areaCost = area * 0.05f * baseCost;
|
||||||
|
|
||||||
const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->getFloat();
|
const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
|
||||||
|
|
||||||
cost += (magnitudeCost + areaCost) * fEffectCostMult;
|
cost += (magnitudeCost + areaCost) * fEffectCostMult;
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ namespace MWMechanics
|
||||||
if(mEnchanter.isEmpty())
|
if(mEnchanter.isEmpty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
float priceMultipler = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fEnchantmentValueMult")->getFloat();
|
float priceMultipler = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fEnchantmentValueMult")->mValue.getFloat();
|
||||||
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mEnchanter, static_cast<int>(getEnchantPoints() * priceMultipler), true);
|
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mEnchanter, static_cast<int>(getEnchantPoints() * priceMultipler), true);
|
||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
return static_cast<int>(mOldItemPtr.getClass().getEnchantmentPoints(mOldItemPtr) * store.get<ESM::GameSetting>().find("fEnchantmentMult")->getFloat());
|
return static_cast<int>(mOldItemPtr.getClass().getEnchantmentPoints(mOldItemPtr) * store.get<ESM::GameSetting>().find("fEnchantmentMult")->mValue.getFloat());
|
||||||
}
|
}
|
||||||
bool Enchanting::soulEmpty() const
|
bool Enchanting::soulEmpty() const
|
||||||
{
|
{
|
||||||
|
@ -317,8 +317,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
float chance2 = 7.5f / (gmst.find("fEnchantmentChanceMult")->getFloat() * ((mCastStyle == ESM::Enchantment::ConstantEffect) ?
|
float chance2 = 7.5f / (gmst.find("fEnchantmentChanceMult")->mValue.getFloat() * ((mCastStyle == ESM::Enchantment::ConstantEffect) ?
|
||||||
gmst.find("fEnchantmentConstantChanceMult")->getFloat() : 1.0f ))
|
gmst.find("fEnchantmentConstantChanceMult")->mValue.getFloat() : 1.0f ))
|
||||||
* getEnchantPoints();
|
* getEnchantPoints();
|
||||||
|
|
||||||
return (chance1-chance2);
|
return (chance1-chance2);
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace
|
||||||
float getFightDispositionBias(float disposition)
|
float getFightDispositionBias(float disposition)
|
||||||
{
|
{
|
||||||
static const float fFightDispMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
static const float fFightDispMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"fFightDispMult")->getFloat();
|
"fFightDispMult")->mValue.getFloat();
|
||||||
return ((50.f - disposition) * fFightDispMult);
|
return ((50.f - disposition) * fFightDispMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,11 +58,11 @@ namespace
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
float persTerm = stats.getAttribute(ESM::Attribute::Personality).getModified() / gmst.find("fPersonalityMod")->getFloat();
|
float persTerm = stats.getAttribute(ESM::Attribute::Personality).getModified() / gmst.find("fPersonalityMod")->mValue.getFloat();
|
||||||
float luckTerm = stats.getAttribute(ESM::Attribute::Luck).getModified() / gmst.find("fLuckMod")->getFloat();
|
float luckTerm = stats.getAttribute(ESM::Attribute::Luck).getModified() / gmst.find("fLuckMod")->mValue.getFloat();
|
||||||
float repTerm = stats.getReputation() * gmst.find("fReputationMod")->getFloat();
|
float repTerm = stats.getReputation() * gmst.find("fReputationMod")->mValue.getFloat();
|
||||||
float fatigueTerm = stats.getFatigueTerm();
|
float fatigueTerm = stats.getFatigueTerm();
|
||||||
float levelTerm = stats.getLevel() * gmst.find("fLevelMod")->getFloat();
|
float levelTerm = stats.getLevel() * gmst.find("fLevelMod")->mValue.getFloat();
|
||||||
|
|
||||||
rating1 = (repTerm + luckTerm + persTerm + stats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm;
|
rating1 = (repTerm + luckTerm + persTerm + stats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm;
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ namespace MWMechanics
|
||||||
if(timeToDrown != mWatchedTimeToStartDrowning)
|
if(timeToDrown != mWatchedTimeToStartDrowning)
|
||||||
{
|
{
|
||||||
static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fHoldBreathTime")->getFloat();
|
.find("fHoldBreathTime")->mValue.getFloat();
|
||||||
|
|
||||||
mWatchedTimeToStartDrowning = timeToDrown;
|
mWatchedTimeToStartDrowning = timeToDrown;
|
||||||
|
|
||||||
|
@ -556,12 +556,12 @@ namespace MWMechanics
|
||||||
const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr);
|
const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr);
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
static const float fDispRaceMod = gmst.find("fDispRaceMod")->getFloat();
|
static const float fDispRaceMod = gmst.find("fDispRaceMod")->mValue.getFloat();
|
||||||
if (Misc::StringUtils::ciEqual(npc->mBase->mRace, player->mBase->mRace))
|
if (Misc::StringUtils::ciEqual(npc->mBase->mRace, player->mBase->mRace))
|
||||||
x += fDispRaceMod;
|
x += fDispRaceMod;
|
||||||
|
|
||||||
static const float fDispPersonalityMult = gmst.find("fDispPersonalityMult")->getFloat();
|
static const float fDispPersonalityMult = gmst.find("fDispPersonalityMult")->mValue.getFloat();
|
||||||
static const float fDispPersonalityBase = gmst.find("fDispPersonalityBase")->getFloat();
|
static const float fDispPersonalityBase = gmst.find("fDispPersonalityBase")->mValue.getFloat();
|
||||||
x += fDispPersonalityMult * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - fDispPersonalityBase);
|
x += fDispPersonalityMult * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - fDispPersonalityBase);
|
||||||
|
|
||||||
float reaction = 0;
|
float reaction = 0;
|
||||||
|
@ -605,20 +605,20 @@ namespace MWMechanics
|
||||||
rank = 0;
|
rank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float fDispFactionRankMult = gmst.find("fDispFactionRankMult")->getFloat();
|
static const float fDispFactionRankMult = gmst.find("fDispFactionRankMult")->mValue.getFloat();
|
||||||
static const float fDispFactionRankBase = gmst.find("fDispFactionRankBase")->getFloat();
|
static const float fDispFactionRankBase = gmst.find("fDispFactionRankBase")->mValue.getFloat();
|
||||||
static const float fDispFactionMod = gmst.find("fDispFactionMod")->getFloat();
|
static const float fDispFactionMod = gmst.find("fDispFactionMod")->mValue.getFloat();
|
||||||
x += (fDispFactionRankMult * rank
|
x += (fDispFactionRankMult * rank
|
||||||
+ fDispFactionRankBase)
|
+ fDispFactionRankBase)
|
||||||
* fDispFactionMod * reaction;
|
* fDispFactionMod * reaction;
|
||||||
|
|
||||||
static const float fDispCrimeMod = gmst.find("fDispCrimeMod")->getFloat();
|
static const float fDispCrimeMod = gmst.find("fDispCrimeMod")->mValue.getFloat();
|
||||||
static const float fDispDiseaseMod = gmst.find("fDispDiseaseMod")->getFloat();
|
static const float fDispDiseaseMod = gmst.find("fDispDiseaseMod")->mValue.getFloat();
|
||||||
x -= fDispCrimeMod * playerStats.getBounty();
|
x -= fDispCrimeMod * playerStats.getBounty();
|
||||||
if (playerStats.hasCommonDisease() || playerStats.hasBlightDisease())
|
if (playerStats.hasCommonDisease() || playerStats.hasBlightDisease())
|
||||||
x += fDispDiseaseMod;
|
x += fDispDiseaseMod;
|
||||||
|
|
||||||
static const float fDispWeaponDrawn = gmst.find("fDispWeaponDrawn")->getFloat();
|
static const float fDispWeaponDrawn = gmst.find("fDispWeaponDrawn")->mValue.getFloat();
|
||||||
if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon)
|
if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon)
|
||||||
x += fDispWeaponDrawn;
|
x += fDispWeaponDrawn;
|
||||||
|
|
||||||
|
@ -699,16 +699,16 @@ namespace MWMechanics
|
||||||
float target2 = d * (playerRating2 - npcRating2 + 50);
|
float target2 = d * (playerRating2 - npcRating2 + 50);
|
||||||
|
|
||||||
float bribeMod;
|
float bribeMod;
|
||||||
if (type == PT_Bribe10) bribeMod = gmst.find("fBribe10Mod")->getFloat();
|
if (type == PT_Bribe10) bribeMod = gmst.find("fBribe10Mod")->mValue.getFloat();
|
||||||
else if (type == PT_Bribe100) bribeMod = gmst.find("fBribe100Mod")->getFloat();
|
else if (type == PT_Bribe100) bribeMod = gmst.find("fBribe100Mod")->mValue.getFloat();
|
||||||
else bribeMod = gmst.find("fBribe1000Mod")->getFloat();
|
else bribeMod = gmst.find("fBribe1000Mod")->mValue.getFloat();
|
||||||
|
|
||||||
float target3 = d * (playerRating3 - npcRating3 + 50) + bribeMod;
|
float target3 = d * (playerRating3 - npcRating3 + 50) + bribeMod;
|
||||||
|
|
||||||
float iPerMinChance = floor(gmst.find("iPerMinChance")->getFloat());
|
float iPerMinChance = floor(gmst.find("iPerMinChance")->mValue.getFloat());
|
||||||
float iPerMinChange = floor(gmst.find("iPerMinChange")->getFloat());
|
float iPerMinChange = floor(gmst.find("iPerMinChange")->mValue.getFloat());
|
||||||
float fPerDieRollMult = gmst.find("fPerDieRollMult")->getFloat();
|
float fPerDieRollMult = gmst.find("fPerDieRollMult")->mValue.getFloat();
|
||||||
float fPerTempMult = gmst.find("fPerTempMult")->getFloat();
|
float fPerTempMult = gmst.find("fPerTempMult")->mValue.getFloat();
|
||||||
|
|
||||||
float x = 0;
|
float x = 0;
|
||||||
float y = 0;
|
float y = 0;
|
||||||
|
@ -911,7 +911,7 @@ namespace MWMechanics
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// All sMagicBound* GMST's should be of type string
|
// All sMagicBound* GMST's should be of type string
|
||||||
std::string currentGMSTValue = currentSetting.getString();
|
std::string currentGMSTValue = currentSetting.mValue.getString();
|
||||||
Misc::StringUtils::lowerCaseInPlace(currentGMSTValue);
|
Misc::StringUtils::lowerCaseInPlace(currentGMSTValue);
|
||||||
|
|
||||||
boundItemIDCache.insert(currentGMSTValue);
|
boundItemIDCache.insert(currentGMSTValue);
|
||||||
|
@ -1225,7 +1225,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
osg::Vec3f from (player.getRefData().getPosition().asVec3());
|
osg::Vec3f from (player.getRefData().getPosition().asVec3());
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
float radius = esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->getFloat();
|
float radius = esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->mValue.getFloat();
|
||||||
|
|
||||||
mActors.getObjectsInRange(from, radius, neighbors);
|
mActors.getObjectsInRange(from, radius, neighbors);
|
||||||
|
|
||||||
|
@ -1334,29 +1334,29 @@ namespace MWMechanics
|
||||||
float disp = 0.f, dispVictim = 0.f;
|
float disp = 0.f, dispVictim = 0.f;
|
||||||
if (type == OT_Trespassing || type == OT_SleepingInOwnedBed)
|
if (type == OT_Trespassing || type == OT_SleepingInOwnedBed)
|
||||||
{
|
{
|
||||||
arg = store.find("iCrimeTresspass")->getInt();
|
arg = store.find("iCrimeTresspass")->mValue.getInteger();
|
||||||
disp = dispVictim = store.find("iDispTresspass")->getFloat();
|
disp = dispVictim = store.find("iDispTresspass")->mValue.getFloat();
|
||||||
}
|
}
|
||||||
else if (type == OT_Pickpocket)
|
else if (type == OT_Pickpocket)
|
||||||
{
|
{
|
||||||
arg = store.find("iCrimePickPocket")->getInt();
|
arg = store.find("iCrimePickPocket")->mValue.getInteger();
|
||||||
disp = dispVictim = store.find("fDispPickPocketMod")->getFloat();
|
disp = dispVictim = store.find("fDispPickPocketMod")->mValue.getFloat();
|
||||||
}
|
}
|
||||||
else if (type == OT_Assault)
|
else if (type == OT_Assault)
|
||||||
{
|
{
|
||||||
arg = store.find("iCrimeAttack")->getInt();
|
arg = store.find("iCrimeAttack")->mValue.getInteger();
|
||||||
disp = store.find("iDispAttackMod")->getFloat();
|
disp = store.find("iDispAttackMod")->mValue.getFloat();
|
||||||
dispVictim = store.find("fDispAttacking")->getFloat();
|
dispVictim = store.find("fDispAttacking")->mValue.getFloat();
|
||||||
}
|
}
|
||||||
else if (type == OT_Murder)
|
else if (type == OT_Murder)
|
||||||
{
|
{
|
||||||
arg = store.find("iCrimeKilling")->getInt();
|
arg = store.find("iCrimeKilling")->mValue.getInteger();
|
||||||
disp = dispVictim = store.find("iDispKilling")->getFloat();
|
disp = dispVictim = store.find("iDispKilling")->mValue.getFloat();
|
||||||
}
|
}
|
||||||
else if (type == OT_Theft)
|
else if (type == OT_Theft)
|
||||||
{
|
{
|
||||||
disp = dispVictim = store.find("fDispStealing")->getFloat() * arg;
|
disp = dispVictim = store.find("fDispStealing")->mValue.getFloat() * arg;
|
||||||
arg = static_cast<int>(arg * store.find("fCrimeStealing")->getFloat());
|
arg = static_cast<int>(arg * store.find("fCrimeStealing")->mValue.getFloat());
|
||||||
arg = std::max(1, arg); // Minimum bounty of 1, in case items with zero value are stolen
|
arg = std::max(1, arg); // Minimum bounty of 1, in case items with zero value are stolen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1366,7 +1366,7 @@ namespace MWMechanics
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
osg::Vec3f from (player.getRefData().getPosition().asVec3());
|
osg::Vec3f from (player.getRefData().getPosition().asVec3());
|
||||||
float radius = esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->getFloat();
|
float radius = esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->mValue.getFloat();
|
||||||
|
|
||||||
mActors.getObjectsInRange(from, radius, neighbors);
|
mActors.getObjectsInRange(from, radius, neighbors);
|
||||||
|
|
||||||
|
@ -1380,21 +1380,21 @@ namespace MWMechanics
|
||||||
// Controls whether witnesses will engage combat with the criminal.
|
// Controls whether witnesses will engage combat with the criminal.
|
||||||
int fight = 0, fightVictim = 0;
|
int fight = 0, fightVictim = 0;
|
||||||
if (type == OT_Trespassing || type == OT_SleepingInOwnedBed)
|
if (type == OT_Trespassing || type == OT_SleepingInOwnedBed)
|
||||||
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("iFightTrespass")->getInt();
|
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("iFightTrespass")->mValue.getInteger();
|
||||||
else if (type == OT_Pickpocket)
|
else if (type == OT_Pickpocket)
|
||||||
{
|
{
|
||||||
fight = esmStore.get<ESM::GameSetting>().find("iFightPickpocket")->getInt();
|
fight = esmStore.get<ESM::GameSetting>().find("iFightPickpocket")->mValue.getInteger();
|
||||||
fightVictim = esmStore.get<ESM::GameSetting>().find("iFightPickpocket")->getInt() * 4; // *4 according to research wiki
|
fightVictim = esmStore.get<ESM::GameSetting>().find("iFightPickpocket")->mValue.getInteger() * 4; // *4 according to research wiki
|
||||||
}
|
}
|
||||||
else if (type == OT_Assault)
|
else if (type == OT_Assault)
|
||||||
{
|
{
|
||||||
fight = esmStore.get<ESM::GameSetting>().find("iFightAttacking")->getInt();
|
fight = esmStore.get<ESM::GameSetting>().find("iFightAttacking")->mValue.getInteger();
|
||||||
fightVictim = esmStore.get<ESM::GameSetting>().find("iFightAttack")->getInt();
|
fightVictim = esmStore.get<ESM::GameSetting>().find("iFightAttack")->mValue.getInteger();
|
||||||
}
|
}
|
||||||
else if (type == OT_Murder)
|
else if (type == OT_Murder)
|
||||||
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("iFightKilling")->getInt();
|
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("iFightKilling")->mValue.getInteger();
|
||||||
else if (type == OT_Theft)
|
else if (type == OT_Theft)
|
||||||
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("fFightStealing")->getInt();
|
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("fFightStealing")->mValue.getInteger();
|
||||||
|
|
||||||
bool reported = false;
|
bool reported = false;
|
||||||
|
|
||||||
|
@ -1645,8 +1645,8 @@ namespace MWMechanics
|
||||||
&& !MWBase::Environment::get().getWorld()->isSwimming(ptr)
|
&& !MWBase::Environment::get().getWorld()->isSwimming(ptr)
|
||||||
&& MWBase::Environment::get().getWorld()->isOnGround(ptr))
|
&& MWBase::Environment::get().getWorld()->isOnGround(ptr))
|
||||||
{
|
{
|
||||||
static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat();
|
static float fSneakSkillMult = store.find("fSneakSkillMult")->mValue.getFloat();
|
||||||
static float fSneakBootMult = store.find("fSneakBootMult")->getFloat();
|
static float fSneakBootMult = store.find("fSneakBootMult")->mValue.getFloat();
|
||||||
float sneak = static_cast<float>(ptr.getClass().getSkill(ptr, ESM::Skill::Sneak));
|
float sneak = static_cast<float>(ptr.getClass().getSkill(ptr, ESM::Skill::Sneak));
|
||||||
int agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
int agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||||
int luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
int luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||||
|
@ -1661,8 +1661,8 @@ namespace MWMechanics
|
||||||
sneakTerm = fSneakSkillMult * sneak + 0.2f * agility + 0.1f * luck + bootWeight * fSneakBootMult;
|
sneakTerm = fSneakSkillMult * sneak + 0.2f * agility + 0.1f * luck + bootWeight * fSneakBootMult;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float fSneakDistBase = store.find("fSneakDistanceBase")->getFloat();
|
static float fSneakDistBase = store.find("fSneakDistanceBase")->mValue.getFloat();
|
||||||
static float fSneakDistMult = store.find("fSneakDistanceMultiplier")->getFloat();
|
static float fSneakDistMult = store.find("fSneakDistanceMultiplier")->mValue.getFloat();
|
||||||
|
|
||||||
osg::Vec3f pos1 (ptr.getRefData().getPosition().asVec3());
|
osg::Vec3f pos1 (ptr.getRefData().getPosition().asVec3());
|
||||||
osg::Vec3f pos2 (observer.getRefData().getPosition().asVec3());
|
osg::Vec3f pos2 (observer.getRefData().getPosition().asVec3());
|
||||||
|
@ -1680,8 +1680,8 @@ namespace MWMechanics
|
||||||
float obsTerm = obsSneak + 0.2f * obsAgility + 0.1f * obsLuck - obsBlind;
|
float obsTerm = obsSneak + 0.2f * obsAgility + 0.1f * obsLuck - obsBlind;
|
||||||
|
|
||||||
// is ptr behind the observer?
|
// is ptr behind the observer?
|
||||||
static float fSneakNoViewMult = store.find("fSneakNoViewMult")->getFloat();
|
static float fSneakNoViewMult = store.find("fSneakNoViewMult")->mValue.getFloat();
|
||||||
static float fSneakViewMult = store.find("fSneakViewMult")->getFloat();
|
static float fSneakViewMult = store.find("fSneakViewMult")->mValue.getFloat();
|
||||||
float y = 0;
|
float y = 0;
|
||||||
osg::Vec3f vec = pos1 - pos2;
|
osg::Vec3f vec = pos1 - pos2;
|
||||||
if (observer.getRefData().getBaseNode())
|
if (observer.getRefData().getBaseNode())
|
||||||
|
@ -1841,7 +1841,7 @@ namespace MWMechanics
|
||||||
MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf")))
|
MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf")))
|
||||||
{
|
{
|
||||||
const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iWerewolfFightMod");
|
const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iWerewolfFightMod");
|
||||||
fight += iWerewolfFightMod->getInt();
|
fight += iWerewolfFightMod->mValue.getInteger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1934,7 +1934,7 @@ namespace MWMechanics
|
||||||
// Witnesses of the player's transformation will make them a globally known werewolf
|
// Witnesses of the player's transformation will make them a globally known werewolf
|
||||||
std::vector<MWWorld::Ptr> closeActors;
|
std::vector<MWWorld::Ptr> closeActors;
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->getFloat(), closeActors);
|
getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->mValue.getFloat(), closeActors);
|
||||||
|
|
||||||
bool detected = false, reported = false;
|
bool detected = false, reported = false;
|
||||||
for (std::vector<MWWorld::Ptr>::const_iterator it = closeActors.begin(); it != closeActors.end(); ++it)
|
for (std::vector<MWWorld::Ptr>::const_iterator it = closeActors.begin(); it != closeActors.end(); ++it)
|
||||||
|
@ -1959,7 +1959,7 @@ namespace MWMechanics
|
||||||
if (reported)
|
if (reported)
|
||||||
{
|
{
|
||||||
npcStats.setBounty(npcStats.getBounty()+
|
npcStats.setBounty(npcStats.getBounty()+
|
||||||
gmst.find("iWereWolfBounty")->getInt());
|
gmst.find("iWereWolfBounty")->mValue.getInteger());
|
||||||
windowManager->messageBox("#{sCrimeMessage}");
|
windowManager->messageBox("#{sCrimeMessage}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1971,7 +1971,7 @@ namespace MWMechanics
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor);
|
MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor);
|
||||||
|
|
||||||
stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->getInt());
|
stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->mValue.getInteger());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::cleanupSummonedCreature(const MWWorld::Ptr &caster, int creatureActorId)
|
void MechanicsManager::cleanupSummonedCreature(const MWWorld::Ptr &caster, int creatureActorId)
|
||||||
|
|
|
@ -149,12 +149,12 @@ float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
float typeFactor = gmst.find ("fMiscSkillBonus")->getFloat();
|
float typeFactor = gmst.find ("fMiscSkillBonus")->mValue.getFloat();
|
||||||
|
|
||||||
for (int i=0; i<5; ++i)
|
for (int i=0; i<5; ++i)
|
||||||
if (class_.mData.mSkills[i][0]==skillIndex)
|
if (class_.mData.mSkills[i][0]==skillIndex)
|
||||||
{
|
{
|
||||||
typeFactor = gmst.find ("fMinorSkillBonus")->getFloat();
|
typeFactor = gmst.find ("fMinorSkillBonus")->mValue.getFloat();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const
|
||||||
for (int i=0; i<5; ++i)
|
for (int i=0; i<5; ++i)
|
||||||
if (class_.mData.mSkills[i][1]==skillIndex)
|
if (class_.mData.mSkills[i][1]==skillIndex)
|
||||||
{
|
{
|
||||||
typeFactor = gmst.find ("fMajorSkillBonus")->getFloat();
|
typeFactor = gmst.find ("fMajorSkillBonus")->mValue.getFloat();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
||||||
if (skill->mData.mSpecialization==class_.mData.mSpecialization)
|
if (skill->mData.mSpecialization==class_.mData.mSpecialization)
|
||||||
{
|
{
|
||||||
specialisationFactor = gmst.find ("fSpecialSkillBonus")->getFloat();
|
specialisationFactor = gmst.find ("fSpecialSkillBonus")->mValue.getFloat();
|
||||||
|
|
||||||
if (specialisationFactor<=0)
|
if (specialisationFactor<=0)
|
||||||
throw std::runtime_error ("invalid skill specialisation factor");
|
throw std::runtime_error ("invalid skill specialisation factor");
|
||||||
|
@ -227,21 +227,21 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
// is this a minor or major skill?
|
// is this a minor or major skill?
|
||||||
int increase = gmst.find("iLevelupMiscMultAttriubte")->getInt(); // Note: GMST has a typo
|
int increase = gmst.find("iLevelupMiscMultAttriubte")->mValue.getInteger(); // Note: GMST has a typo
|
||||||
for (int k=0; k<5; ++k)
|
for (int k=0; k<5; ++k)
|
||||||
{
|
{
|
||||||
if (class_.mData.mSkills[k][0] == skillIndex)
|
if (class_.mData.mSkills[k][0] == skillIndex)
|
||||||
{
|
{
|
||||||
mLevelProgress += gmst.find("iLevelUpMinorMult")->getInt();
|
mLevelProgress += gmst.find("iLevelUpMinorMult")->mValue.getInteger();
|
||||||
increase = gmst.find("iLevelUpMajorMultAttribute")->getInt();
|
increase = gmst.find("iLevelUpMajorMultAttribute")->mValue.getInteger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int k=0; k<5; ++k)
|
for (int k=0; k<5; ++k)
|
||||||
{
|
{
|
||||||
if (class_.mData.mSkills[k][1] == skillIndex)
|
if (class_.mData.mSkills[k][1] == skillIndex)
|
||||||
{
|
{
|
||||||
mLevelProgress += gmst.find("iLevelUpMajorMult")->getInt();
|
mLevelProgress += gmst.find("iLevelUpMajorMult")->mValue.getInteger();
|
||||||
increase = gmst.find("iLevelUpMinorMultAttribute")->getInt();
|
increase = gmst.find("iLevelUpMinorMultAttribute")->mValue.getInteger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
|
||||||
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::Skill>().find(skillIndex);
|
MWBase::Environment::get().getWorld ()->getStore ().get<ESM::Skill>().find(skillIndex);
|
||||||
mSkillIncreases[skill->mData.mAttribute] += increase;
|
mSkillIncreases[skill->mData.mAttribute] += increase;
|
||||||
|
|
||||||
mSpecIncreases[skill->mData.mSpecialization] += gmst.find("iLevelupSpecialization")->getInt();
|
mSpecIncreases[skill->mData.mSpecialization] += gmst.find("iLevelupSpecialization")->mValue.getInteger();
|
||||||
|
|
||||||
// Play sound & skill progress notification
|
// Play sound & skill progress notification
|
||||||
/// \todo check if character is the player, if levelling is ever implemented for NPCs
|
/// \todo check if character is the player, if levelling is ever implemented for NPCs
|
||||||
|
@ -266,7 +266,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager ()->messageBox(message.str(), MWGui::ShowInDialogueMode_Never);
|
MWBase::Environment::get().getWindowManager ()->messageBox(message.str(), MWGui::ShowInDialogueMode_Never);
|
||||||
|
|
||||||
if (mLevelProgress >= gmst.find("iLevelUpTotal")->getInt())
|
if (mLevelProgress >= gmst.find("iLevelUpTotal")->mValue.getInteger())
|
||||||
{
|
{
|
||||||
// levelup is possible now
|
// levelup is possible now
|
||||||
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never);
|
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never);
|
||||||
|
@ -348,7 +348,7 @@ void MWMechanics::NpcStats::levelUp()
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
mLevelProgress -= gmst.find("iLevelUpTotal")->getInt();
|
mLevelProgress -= gmst.find("iLevelUpTotal")->mValue.getInteger();
|
||||||
mLevelProgress = std::max(0, mLevelProgress); // might be necessary when levelup was invoked via console
|
mLevelProgress = std::max(0, mLevelProgress); // might be necessary when levelup was invoked via console
|
||||||
|
|
||||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
@ -359,7 +359,7 @@ void MWMechanics::NpcStats::levelUp()
|
||||||
// "When you gain a level, in addition to increasing three primary attributes, your Health
|
// "When you gain a level, in addition to increasing three primary attributes, your Health
|
||||||
// will automatically increase by 10% of your Endurance attribute. If you increased Endurance this level,
|
// will automatically increase by 10% of your Endurance attribute. If you increased Endurance this level,
|
||||||
// the Health increase is calculated from the increased Endurance"
|
// the Health increase is calculated from the increased Endurance"
|
||||||
setHealth(getHealth().getBase() + endurance * gmst.find("fLevelUpHealthEndMult")->getFloat());
|
setHealth(getHealth().getBase() + endurance * gmst.find("fLevelUpHealthEndMult")->mValue.getFloat());
|
||||||
|
|
||||||
setLevel(getLevel()+1);
|
setLevel(getLevel()+1);
|
||||||
}
|
}
|
||||||
|
@ -385,7 +385,7 @@ int MWMechanics::NpcStats::getLevelupAttributeMultiplier(int attribute) const
|
||||||
std::stringstream gmst;
|
std::stringstream gmst;
|
||||||
gmst << "iLevelUp" << std::setfill('0') << std::setw(2) << num << "Mult";
|
gmst << "iLevelUp" << std::setfill('0') << std::setw(2) << num << "Mult";
|
||||||
|
|
||||||
return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(gmst.str())->getInt();
|
return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(gmst.str())->mValue.getInteger();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWMechanics::NpcStats::getSkillIncreasesForSpecialization(int spec) const
|
int MWMechanics::NpcStats::getSkillIncreasesForSpecialization(int spec) const
|
||||||
|
|
|
@ -37,9 +37,9 @@ namespace MWMechanics
|
||||||
|
|
||||||
float pcSneak = static_cast<float>(mThief.getClass().getSkill(mThief, ESM::Skill::Sneak));
|
float pcSneak = static_cast<float>(mThief.getClass().getSkill(mThief, ESM::Skill::Sneak));
|
||||||
int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("iPickMinChance")->getInt();
|
.find("iPickMinChance")->mValue.getInteger();
|
||||||
int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("iPickMaxChance")->getInt();
|
.find("iPickMaxChance")->mValue.getInteger();
|
||||||
|
|
||||||
int roll = Misc::Rng::roll0to99();
|
int roll = Misc::Rng::roll0to99();
|
||||||
if (t < pcSneak / iPickMinChance)
|
if (t < pcSneak / iPickMinChance)
|
||||||
|
@ -57,7 +57,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
float stackValue = static_cast<float>(item.getClass().getValue(item) * count);
|
float stackValue = static_cast<float>(item.getClass().getValue(item) * count);
|
||||||
float fPickPocketMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
float fPickPocketMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fPickPocketMod")->getFloat();
|
.find("fPickPocketMod")->mValue.getFloat();
|
||||||
float valueTerm = 10 * fPickPocketMod * stackValue;
|
float valueTerm = 10 * fPickPocketMod * stackValue;
|
||||||
|
|
||||||
return getDetected(valueTerm);
|
return getDetected(valueTerm);
|
||||||
|
|
|
@ -55,7 +55,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
|
||||||
int armorerSkill = npcStats.getSkill(ESM::Skill::Armorer).getModified();
|
int armorerSkill = npcStats.getSkill(ESM::Skill::Armorer).getModified();
|
||||||
|
|
||||||
float fRepairAmountMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
float fRepairAmountMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fRepairAmountMult")->getFloat();
|
.find("fRepairAmountMult")->mValue.getFloat();
|
||||||
|
|
||||||
float toolQuality = ref->mBase->mData.mQuality;
|
float toolQuality = ref->mBase->mData.mQuality;
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
|
||||||
store.remove(mTool, 1, player);
|
store.remove(mTool, 1, player);
|
||||||
|
|
||||||
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("sNotifyMessage51")->getString();
|
.find("sNotifyMessage51")->mValue.getString();
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox((boost::format(message) % mTool.getClass().getName(mTool)).str());
|
MWBase::Environment::get().getWindowManager()->messageBox((boost::format(message) % mTool.getClass().getName(mTool)).str());
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
float pickQuality = lockpick.get<ESM::Lockpick>()->mBase->mData.mQuality;
|
float pickQuality = lockpick.get<ESM::Lockpick>()->mBase->mData.mQuality;
|
||||||
|
|
||||||
float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fPickLockMult")->getFloat();
|
float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fPickLockMult")->mValue.getFloat();
|
||||||
|
|
||||||
float x = 0.2f * mAgility + 0.1f * mLuck + mSecuritySkill;
|
float x = 0.2f * mAgility + 0.1f * mLuck + mSecuritySkill;
|
||||||
x *= pickQuality * mFatigueTerm;
|
x *= pickQuality * mFatigueTerm;
|
||||||
|
@ -119,7 +119,7 @@ namespace MWMechanics
|
||||||
const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(trap.getCellRef().getTrap());
|
const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(trap.getCellRef().getTrap());
|
||||||
int trapSpellPoints = trapSpell->mData.mCost;
|
int trapSpellPoints = trapSpell->mData.mCost;
|
||||||
|
|
||||||
float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTrapCostMult")->getFloat();
|
float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTrapCostMult")->mValue.getFloat();
|
||||||
|
|
||||||
float x = 0.2f * mAgility + 0.1f * mLuck + mSecuritySkill;
|
float x = 0.2f * mAgility + 0.1f * mLuck + mSecuritySkill;
|
||||||
x += fTrapCostMult * trapSpellPoints;
|
x += fTrapCostMult * trapSpellPoints;
|
||||||
|
|
|
@ -51,13 +51,17 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
ESM::Skill::SkillEnum spellSchoolToSkill(int school)
|
ESM::Skill::SkillEnum spellSchoolToSkill(int school)
|
||||||
{
|
{
|
||||||
std::map<int, ESM::Skill::SkillEnum> schoolSkillMap; // maps spell school to skill id
|
static std::map<int, ESM::Skill::SkillEnum> schoolSkillMap; // maps spell school to skill id
|
||||||
schoolSkillMap[0] = ESM::Skill::Alteration;
|
if (schoolSkillMap.empty())
|
||||||
schoolSkillMap[1] = ESM::Skill::Conjuration;
|
{
|
||||||
schoolSkillMap[3] = ESM::Skill::Illusion;
|
schoolSkillMap[0] = ESM::Skill::Alteration;
|
||||||
schoolSkillMap[2] = ESM::Skill::Destruction;
|
schoolSkillMap[1] = ESM::Skill::Conjuration;
|
||||||
schoolSkillMap[4] = ESM::Skill::Mysticism;
|
schoolSkillMap[3] = ESM::Skill::Illusion;
|
||||||
schoolSkillMap[5] = ESM::Skill::Restoration;
|
schoolSkillMap[2] = ESM::Skill::Destruction;
|
||||||
|
schoolSkillMap[4] = ESM::Skill::Mysticism;
|
||||||
|
schoolSkillMap[5] = ESM::Skill::Restoration;
|
||||||
|
}
|
||||||
|
|
||||||
assert(schoolSkillMap.find(school) != schoolSkillMap.end());
|
assert(schoolSkillMap.find(school) != schoolSkillMap.end());
|
||||||
return schoolSkillMap[school];
|
return schoolSkillMap[school];
|
||||||
}
|
}
|
||||||
|
@ -65,7 +69,11 @@ namespace MWMechanics
|
||||||
float calcEffectCost(const ESM::ENAMstruct& effect)
|
float calcEffectCost(const ESM::ENAMstruct& effect)
|
||||||
{
|
{
|
||||||
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
||||||
|
return calcEffectCost(effect, magicEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect)
|
||||||
|
{
|
||||||
int minMagn = 1;
|
int minMagn = 1;
|
||||||
int maxMagn = 1;
|
int maxMagn = 1;
|
||||||
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
|
||||||
|
@ -79,7 +87,7 @@ namespace MWMechanics
|
||||||
duration = effect.mDuration;
|
duration = effect.mDuration;
|
||||||
|
|
||||||
static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore()
|
static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore()
|
||||||
.get<ESM::GameSetting>().find("fEffectCostMult")->getFloat();
|
.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
|
||||||
|
|
||||||
float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn));
|
float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn));
|
||||||
x *= 0.1 * magicEffect->mData.mBaseCost;
|
x *= 0.1 * magicEffect->mData.mBaseCost;
|
||||||
|
@ -110,7 +118,7 @@ namespace MWMechanics
|
||||||
if (it->mRange == ESM::RT_Target)
|
if (it->mRange == ESM::RT_Target)
|
||||||
x *= 1.5f;
|
x *= 1.5f;
|
||||||
static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"fEffectCostMult")->getFloat();
|
"fEffectCostMult")->mValue.getFloat();
|
||||||
x *= fEffectCostMult;
|
x *= fEffectCostMult;
|
||||||
|
|
||||||
float s = 2.0f * actor.getClass().getSkill(actor, spellSchoolToSkill(magicEffect->mData.mSchool));
|
float s = 2.0f * actor.getClass().getSkill(actor, spellSchoolToSkill(magicEffect->mData.mSchool));
|
||||||
|
@ -996,8 +1004,8 @@ namespace MWMechanics
|
||||||
if (!godmode)
|
if (!godmode)
|
||||||
{
|
{
|
||||||
// Reduce fatigue (note that in the vanilla game, both GMSTs are 0, and there's no fatigue loss)
|
// Reduce fatigue (note that in the vanilla game, both GMSTs are 0, and there's no fatigue loss)
|
||||||
static const float fFatigueSpellBase = store.get<ESM::GameSetting>().find("fFatigueSpellBase")->getFloat();
|
static const float fFatigueSpellBase = store.get<ESM::GameSetting>().find("fFatigueSpellBase")->mValue.getFloat();
|
||||||
static const float fFatigueSpellMult = store.get<ESM::GameSetting>().find("fFatigueSpellMult")->getFloat();
|
static const float fFatigueSpellMult = store.get<ESM::GameSetting>().find("fFatigueSpellMult")->mValue.getFloat();
|
||||||
DynamicStat<float> fatigue = stats.getFatigue();
|
DynamicStat<float> fatigue = stats.getFatigue();
|
||||||
const float normalizedEncumbrance = mCaster.getClass().getNormalizedEncumbrance(mCaster);
|
const float normalizedEncumbrance = mCaster.getClass().getNormalizedEncumbrance(mCaster);
|
||||||
|
|
||||||
|
@ -1098,7 +1106,7 @@ namespace MWMechanics
|
||||||
if (roll > x)
|
if (roll > x)
|
||||||
{
|
{
|
||||||
// "X has no effect on you"
|
// "X has no effect on you"
|
||||||
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage50")->getString();
|
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage50")->mValue.getString();
|
||||||
message = boost::str(boost::format(message) % ingredient->mName);
|
message = boost::str(boost::format(message) % ingredient->mName);
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox(message);
|
MWBase::Environment::get().getWindowManager()->messageBox(message);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1381,7 +1389,7 @@ namespace MWMechanics
|
||||||
float damageScale = 1.f - timeDiff / 7.f;
|
float damageScale = 1.f - timeDiff / 7.f;
|
||||||
// When cloudy, the sun damage effect is halved
|
// When cloudy, the sun damage effect is halved
|
||||||
static float fMagicSunBlockedMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
static float fMagicSunBlockedMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"fMagicSunBlockedMult")->getFloat();
|
"fMagicSunBlockedMult")->mValue.getFloat();
|
||||||
|
|
||||||
int weather = MWBase::Environment::get().getWorld()->getCurrentWeather();
|
int weather = MWBase::Environment::get().getWorld()->getCurrentWeather();
|
||||||
if (weather > 1)
|
if (weather > 1)
|
||||||
|
@ -1494,7 +1502,7 @@ namespace MWMechanics
|
||||||
if (it == summonMap.end())
|
if (it == summonMap.end())
|
||||||
return std::string();
|
return std::string();
|
||||||
else
|
else
|
||||||
return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(it->second)->getString();
|
return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(it->second)->mValue.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyLoopingParticlesVisitor::visit (MWMechanics::EffectKey key,
|
void ApplyLoopingParticlesVisitor::visit (MWMechanics::EffectKey key,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <components/esm/effectlist.hpp>
|
#include <components/esm/effectlist.hpp>
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
|
#include <components/esm/loadmgef.hpp>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ namespace MWMechanics
|
||||||
ESM::Skill::SkillEnum spellSchoolToSkill(int school);
|
ESM::Skill::SkillEnum spellSchoolToSkill(int school);
|
||||||
|
|
||||||
float calcEffectCost(const ESM::ENAMstruct& effect);
|
float calcEffectCost(const ESM::ENAMstruct& effect);
|
||||||
|
float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect);
|
||||||
|
|
||||||
bool isSummoningEffect(int effectId);
|
bool isSummoningEffect(int effectId);
|
||||||
|
|
||||||
|
|
|
@ -515,8 +515,6 @@ namespace MWMechanics
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
|
||||||
|
|
||||||
// Underwater casting not possible
|
// Underwater casting not possible
|
||||||
if (effect.mRange == ESM::RT_Target)
|
if (effect.mRange == ESM::RT_Target)
|
||||||
{
|
{
|
||||||
|
@ -530,6 +528,7 @@ namespace MWMechanics
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(effect.mEffectID);
|
||||||
if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful)
|
if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful)
|
||||||
{
|
{
|
||||||
rating *= -1.f;
|
rating *= -1.f;
|
||||||
|
@ -565,7 +564,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rating *= calcEffectCost(effect);
|
rating *= calcEffectCost(effect, magicEffect);
|
||||||
|
|
||||||
// Currently treating all "on target" or "on touch" effects to target the enemy actor.
|
// Currently treating all "on target" or "on touch" effects to target the enemy actor.
|
||||||
// Combat AI is egoistic, so doesn't consider applying positive effects to friendly actors.
|
// Combat AI is egoistic, so doesn't consider applying positive effects to friendly actors.
|
||||||
|
@ -593,8 +592,8 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
static const float fAIMagicSpellMult = gmst.find("fAIMagicSpellMult")->getFloat();
|
static const float fAIMagicSpellMult = gmst.find("fAIMagicSpellMult")->mValue.getFloat();
|
||||||
static const float fAIRangeMagicSpellMult = gmst.find("fAIRangeMagicSpellMult")->getFloat();
|
static const float fAIRangeMagicSpellMult = gmst.find("fAIRangeMagicSpellMult")->mValue.getFloat();
|
||||||
|
|
||||||
float mult = fAIMagicSpellMult;
|
float mult = fAIMagicSpellMult;
|
||||||
|
|
||||||
|
|
|
@ -279,6 +279,25 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Spells::removeEffects(const std::string &id)
|
||||||
|
{
|
||||||
|
if (isSpellActive(id))
|
||||||
|
{
|
||||||
|
for (TContainer::iterator spell = mSpells.begin(); spell != mSpells.end(); ++spell)
|
||||||
|
{
|
||||||
|
if (spell->first == getSpell(id))
|
||||||
|
{
|
||||||
|
for (long unsigned int i = 0; i != spell->first->mEffects.mList.size(); i++)
|
||||||
|
{
|
||||||
|
spell->second.mPurgedEffects.insert(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mSpellsChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Spells::visitEffectSources(EffectSourceVisitor &visitor) const
|
void Spells::visitEffectSources(EffectSourceVisitor &visitor) const
|
||||||
{
|
{
|
||||||
if (mSpellsChanged) {
|
if (mSpellsChanged) {
|
||||||
|
|
|
@ -124,6 +124,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool hasBlightDisease() const;
|
bool hasBlightDisease() const;
|
||||||
|
|
||||||
|
void removeEffects(const std::string& id);
|
||||||
|
|
||||||
void visitEffectSources (MWMechanics::EffectSourceVisitor& visitor) const;
|
void visitEffectSources (MWMechanics::EffectSourceVisitor& visitor) const;
|
||||||
|
|
||||||
void readState (const ESM::SpellState& state);
|
void readState (const ESM::SpellState& state);
|
||||||
|
|
|
@ -50,11 +50,11 @@ namespace MWMechanics
|
||||||
float e1 = 0.1f * merchantStats.getAttribute(ESM::Attribute::Luck).getModified();
|
float e1 = 0.1f * merchantStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||||
float f1 = 0.2f * merchantStats.getAttribute(ESM::Attribute::Personality).getModified();
|
float f1 = 0.2f * merchantStats.getAttribute(ESM::Attribute::Personality).getModified();
|
||||||
|
|
||||||
float dispositionTerm = gmst.find("fDispositionMod")->getFloat() * (clampedDisposition - 50);
|
float dispositionTerm = gmst.find("fDispositionMod")->mValue.getFloat() * (clampedDisposition - 50);
|
||||||
float pcTerm = (dispositionTerm + a1 + b1 + c1) * playerStats.getFatigueTerm();
|
float pcTerm = (dispositionTerm + a1 + b1 + c1) * playerStats.getFatigueTerm();
|
||||||
float npcTerm = (d1 + e1 + f1) * merchantStats.getFatigueTerm();
|
float npcTerm = (d1 + e1 + f1) * merchantStats.getFatigueTerm();
|
||||||
float x = gmst.find("fBargainOfferMulti")->getFloat() * d
|
float x = gmst.find("fBargainOfferMulti")->mValue.getFloat() * d
|
||||||
+ gmst.find("fBargainOfferBase")->getFloat()
|
+ gmst.find("fBargainOfferBase")->mValue.getFloat()
|
||||||
+ int(pcTerm - npcTerm);
|
+ int(pcTerm - npcTerm);
|
||||||
|
|
||||||
int roll = Misc::Rng::rollDice(100) + 1;
|
int roll = Misc::Rng::rollDice(100) + 1;
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace MWMechanics
|
||||||
if (type != -1 && weapon->mData.mType != type)
|
if (type != -1 && weapon->mData.mType != type)
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
|
if (type == -1 && (weapon->mData.mType == ESM::Weapon::Arrow || weapon->mData.mType == ESM::Weapon::Bolt))
|
||||||
|
return 0.f;
|
||||||
|
|
||||||
float rating=0.f;
|
float rating=0.f;
|
||||||
float rangedMult=1.f;
|
float rangedMult=1.f;
|
||||||
|
|
||||||
|
@ -108,11 +111,19 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int skill = item.getClass().getEquipmentSkill(item);
|
if (actor.getClass().isNpc())
|
||||||
if (skill != -1)
|
|
||||||
{
|
{
|
||||||
int value = actor.getClass().getSkill(actor, skill);
|
int skill = item.getClass().getEquipmentSkill(item);
|
||||||
rating *= MWMechanics::getHitChance(actor, enemy, value) / 100.f;
|
if (skill != -1)
|
||||||
|
{
|
||||||
|
int value = actor.getClass().getSkill(actor, skill);
|
||||||
|
rating *= MWMechanics::getHitChance(actor, enemy, value) / 100.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::Creature> *ref = actor.get<ESM::Creature>();
|
||||||
|
rating *= MWMechanics::getHitChance(actor, enemy, ref->mBase->mData.mCombat) / 100.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rating * rangedMult;
|
return rating * rangedMult;
|
||||||
|
@ -149,9 +160,9 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->getFloat();
|
static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->mValue.getFloat();
|
||||||
static const float fAIMeleeArmorMult = gmst.find("fAIMeleeArmorMult")->getFloat();
|
static const float fAIMeleeArmorMult = gmst.find("fAIMeleeArmorMult")->mValue.getFloat();
|
||||||
static const float fAIRangeMeleeWeaponMult = gmst.find("fAIRangeMeleeWeaponMult")->getFloat();
|
static const float fAIRangeMeleeWeaponMult = gmst.find("fAIRangeMeleeWeaponMult")->mValue.getFloat();
|
||||||
|
|
||||||
if (weapon.isEmpty())
|
if (weapon.isEmpty())
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
|
@ -303,7 +303,7 @@ namespace MWPhysics
|
||||||
position.z() += halfExtents.z();
|
position.z() += halfExtents.z();
|
||||||
|
|
||||||
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fSwimHeightScale")->getFloat();
|
.find("fSwimHeightScale")->mValue.getFloat();
|
||||||
float swimlevel = waterlevel + halfExtents.z() - (physicActor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale);
|
float swimlevel = waterlevel + halfExtents.z() - (physicActor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale);
|
||||||
|
|
||||||
ActorTracer tracer;
|
ActorTracer tracer;
|
||||||
|
@ -339,7 +339,7 @@ namespace MWPhysics
|
||||||
osg::Vec3f stormDirection = MWBase::Environment::get().getWorld()->getStormDirection();
|
osg::Vec3f stormDirection = MWBase::Environment::get().getWorld()->getStormDirection();
|
||||||
float angleDegrees = osg::RadiansToDegrees(std::acos(stormDirection * velocity / (stormDirection.length() * velocity.length())));
|
float angleDegrees = osg::RadiansToDegrees(std::acos(stormDirection * velocity / (stormDirection.length() * velocity.length())));
|
||||||
static const float fStromWalkMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static const float fStromWalkMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fStromWalkMult")->getFloat();
|
.find("fStromWalkMult")->mValue.getFloat();
|
||||||
velocity *= 1.f-(fStromWalkMult * (angleDegrees/180.f));
|
velocity *= 1.f-(fStromWalkMult * (angleDegrees/180.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,7 +650,6 @@ namespace MWPhysics
|
||||||
|
|
||||||
osg::NodePath& nodePath = nodePathFound->second;
|
osg::NodePath& nodePath = nodePathFound->second;
|
||||||
osg::Matrixf matrix = osg::computeLocalToWorld(nodePath);
|
osg::Matrixf matrix = osg::computeLocalToWorld(nodePath);
|
||||||
osg::Vec3f scale = matrix.getScale();
|
|
||||||
matrix.orthoNormalize(matrix);
|
matrix.orthoNormalize(matrix);
|
||||||
|
|
||||||
btTransform transform;
|
btTransform transform;
|
||||||
|
@ -659,8 +658,8 @@ namespace MWPhysics
|
||||||
for (int j=0; j<3; ++j)
|
for (int j=0; j<3; ++j)
|
||||||
transform.getBasis()[i][j] = matrix(j,i); // NB column/row major difference
|
transform.getBasis()[i][j] = matrix(j,i); // NB column/row major difference
|
||||||
|
|
||||||
if (compound->getLocalScaling() * toBullet(scale) != compound->getChildShape(shapeIndex)->getLocalScaling())
|
// Note: we can not apply scaling here for now since we treat scaled shapes
|
||||||
compound->getChildShape(shapeIndex)->setLocalScaling(compound->getLocalScaling() * toBullet(scale));
|
// as new shapes (btScaledBvhTriangleMeshShape) with 1.0 scale for now
|
||||||
if (!(transform == compound->getChildTransform(shapeIndex)))
|
if (!(transform == compound->getChildTransform(shapeIndex)))
|
||||||
compound->updateChildTransform(shapeIndex, transform);
|
compound->updateChildTransform(shapeIndex, transform);
|
||||||
}
|
}
|
||||||
|
@ -883,8 +882,8 @@ namespace MWPhysics
|
||||||
// Use cone shape as fallback
|
// Use cone shape as fallback
|
||||||
const MWWorld::Store<ESM::GameSetting> &store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
btConeShape shape (osg::DegreesToRadians(store.find("fCombatAngleXY")->getFloat()/2.0f), queryDistance);
|
btConeShape shape (osg::DegreesToRadians(store.find("fCombatAngleXY")->mValue.getFloat()/2.0f), queryDistance);
|
||||||
shape.setLocalScaling(btVector3(1, 1, osg::DegreesToRadians(store.find("fCombatAngleZ")->getFloat()/2.0f) /
|
shape.setLocalScaling(btVector3(1, 1, osg::DegreesToRadians(store.find("fCombatAngleZ")->mValue.getFloat()/2.0f) /
|
||||||
shape.getRadius()));
|
shape.getRadius()));
|
||||||
|
|
||||||
// The shape origin is its center, so we have to move it forward by half the length. The
|
// The shape origin is its center, so we have to move it forward by half the length. The
|
||||||
|
|
|
@ -208,8 +208,11 @@ namespace
|
||||||
class RemoveFinishedCallbackVisitor : public RemoveVisitor
|
class RemoveFinishedCallbackVisitor : public RemoveVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool mHasMagicEffects;
|
||||||
|
|
||||||
RemoveFinishedCallbackVisitor()
|
RemoveFinishedCallbackVisitor()
|
||||||
: RemoveVisitor()
|
: RemoveVisitor()
|
||||||
|
, mHasMagicEffects(false)
|
||||||
, mEffectId(-1)
|
, mEffectId(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -234,11 +237,14 @@ namespace
|
||||||
{
|
{
|
||||||
// We should remove empty transformation nodes and finished callbacks here
|
// We should remove empty transformation nodes and finished callbacks here
|
||||||
MWRender::UpdateVfxCallback* vfxCallback = dynamic_cast<MWRender::UpdateVfxCallback*>(callback);
|
MWRender::UpdateVfxCallback* vfxCallback = dynamic_cast<MWRender::UpdateVfxCallback*>(callback);
|
||||||
bool finished = vfxCallback && vfxCallback->mFinished;
|
if (vfxCallback)
|
||||||
bool toRemove = vfxCallback && mEffectId >= 0 && vfxCallback->mParams.mEffectId == mEffectId;
|
|
||||||
if (finished || toRemove)
|
|
||||||
{
|
{
|
||||||
mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0)));
|
bool finished = vfxCallback->mFinished;
|
||||||
|
bool toRemove = mEffectId >= 0 && vfxCallback->mParams.mEffectId == mEffectId;
|
||||||
|
if (finished || toRemove)
|
||||||
|
mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0)));
|
||||||
|
else
|
||||||
|
mHasMagicEffects = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -610,6 +616,7 @@ namespace MWRender
|
||||||
, mTextKeyListener(NULL)
|
, mTextKeyListener(NULL)
|
||||||
, mHeadYawRadians(0.f)
|
, mHeadYawRadians(0.f)
|
||||||
, mHeadPitchRadians(0.f)
|
, mHeadPitchRadians(0.f)
|
||||||
|
, mHasMagicEffects(false)
|
||||||
, mAlpha(1.f)
|
, mAlpha(1.f)
|
||||||
{
|
{
|
||||||
for(size_t i = 0;i < sNumBlendMasks;i++)
|
for(size_t i = 0;i < sNumBlendMasks;i++)
|
||||||
|
@ -1321,7 +1328,7 @@ namespace MWRender
|
||||||
++stateiter;
|
++stateiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEffects(duration);
|
updateEffects();
|
||||||
|
|
||||||
if (mHeadController)
|
if (mHeadController)
|
||||||
{
|
{
|
||||||
|
@ -1633,6 +1640,9 @@ namespace MWRender
|
||||||
SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr<SceneUtil::ControllerSource>(params.mAnimTime));
|
SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr<SceneUtil::ControllerSource>(params.mAnimTime));
|
||||||
node->accept(assignVisitor);
|
node->accept(assignVisitor);
|
||||||
|
|
||||||
|
// Notify that this animation has attached magic effects
|
||||||
|
mHasMagicEffects = true;
|
||||||
|
|
||||||
overrideFirstRootTexture(texture, mResourceSystem, node);
|
overrideFirstRootTexture(texture, mResourceSystem, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1641,10 +1651,14 @@ namespace MWRender
|
||||||
RemoveFinishedCallbackVisitor visitor(effectId);
|
RemoveFinishedCallbackVisitor visitor(effectId);
|
||||||
mInsert->accept(visitor);
|
mInsert->accept(visitor);
|
||||||
visitor.remove();
|
visitor.remove();
|
||||||
|
mHasMagicEffects = visitor.mHasMagicEffects;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::getLoopingEffects(std::vector<int> &out) const
|
void Animation::getLoopingEffects(std::vector<int> &out) const
|
||||||
{
|
{
|
||||||
|
if (!mHasMagicEffects)
|
||||||
|
return;
|
||||||
|
|
||||||
FindVfxCallbacksVisitor visitor;
|
FindVfxCallbacksVisitor visitor;
|
||||||
mInsert->accept(visitor);
|
mInsert->accept(visitor);
|
||||||
|
|
||||||
|
@ -1657,13 +1671,19 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::updateEffects(float duration)
|
void Animation::updateEffects()
|
||||||
{
|
{
|
||||||
|
// We do not need to visit scene every frame.
|
||||||
|
// We can use a bool flag to check in spellcasting effect found.
|
||||||
|
if (!mHasMagicEffects)
|
||||||
|
return;
|
||||||
|
|
||||||
// TODO: objects without animation still will have
|
// TODO: objects without animation still will have
|
||||||
// transformation nodes with finished callbacks
|
// transformation nodes with finished callbacks
|
||||||
RemoveFinishedCallbackVisitor visitor;
|
RemoveFinishedCallbackVisitor visitor;
|
||||||
mInsert->accept(visitor);
|
mInsert->accept(visitor);
|
||||||
visitor.remove();
|
visitor.remove();
|
||||||
|
mHasMagicEffects = visitor.mHasMagicEffects;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Animation::upperBodyReady() const
|
bool Animation::upperBodyReady() const
|
||||||
|
|
|
@ -263,6 +263,7 @@ protected:
|
||||||
osg::ref_ptr<RotateController> mHeadController;
|
osg::ref_ptr<RotateController> mHeadController;
|
||||||
float mHeadYawRadians;
|
float mHeadYawRadians;
|
||||||
float mHeadPitchRadians;
|
float mHeadPitchRadians;
|
||||||
|
bool mHasMagicEffects;
|
||||||
|
|
||||||
osg::ref_ptr<SceneUtil::LightSource> mGlowLight;
|
osg::ref_ptr<SceneUtil::LightSource> mGlowLight;
|
||||||
osg::ref_ptr<GlowUpdater> mGlowUpdater;
|
osg::ref_ptr<GlowUpdater> mGlowUpdater;
|
||||||
|
@ -450,7 +451,7 @@ public:
|
||||||
void setLoopingEnabled(const std::string &groupname, bool enabled);
|
void setLoopingEnabled(const std::string &groupname, bool enabled);
|
||||||
|
|
||||||
/// This is typically called as part of runAnimation, but may be called manually if needed.
|
/// This is typically called as part of runAnimation, but may be called manually if needed.
|
||||||
void updateEffects(float duration);
|
void updateEffects();
|
||||||
|
|
||||||
/// Return a node with the specified name, or NULL if not existing.
|
/// Return a node with the specified name, or NULL if not existing.
|
||||||
/// @note The matching is case-insensitive.
|
/// @note The matching is case-insensitive.
|
||||||
|
|
|
@ -171,11 +171,12 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength)
|
||||||
return;
|
return;
|
||||||
osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans();
|
osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans();
|
||||||
|
|
||||||
float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->getFloat();
|
float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat();
|
||||||
float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->getFloat();
|
float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat();
|
||||||
float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength;
|
float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength;
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->launchProjectile(actor, *weapon, launchPos, orient, *weapon, speed, attackStrength);
|
MWWorld::Ptr weaponPtr = *weapon;
|
||||||
|
MWBase::Environment::get().getWorld()->launchProjectile(actor, weaponPtr, launchPos, orient, weaponPtr, speed, attackStrength);
|
||||||
|
|
||||||
showWeapon(false);
|
showWeapon(false);
|
||||||
|
|
||||||
|
@ -208,13 +209,15 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength)
|
||||||
return;
|
return;
|
||||||
osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans();
|
osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans();
|
||||||
|
|
||||||
float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->getFloat();
|
float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat();
|
||||||
float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->getFloat();
|
float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat();
|
||||||
float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength;
|
float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength;
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->launchProjectile(actor, *ammo, launchPos, orient, *weapon, speed, attackStrength);
|
MWWorld::Ptr weaponPtr = *weapon;
|
||||||
|
MWWorld::Ptr ammoPtr = *ammo;
|
||||||
|
MWBase::Environment::get().getWorld()->launchProjectile(actor, ammoPtr, launchPos, orient, weaponPtr, speed, attackStrength);
|
||||||
|
|
||||||
inv.remove(*ammo, 1, actor);
|
inv.remove(ammoPtr, 1, actor);
|
||||||
mAmmunition.reset();
|
mAmmunition.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,6 +548,7 @@ namespace MWScript
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
ptr.getClass().getCreatureStats (ptr).getActiveSpells().removeEffects(spellid);
|
ptr.getClass().getCreatureStats (ptr).getActiveSpells().removeEffects(spellid);
|
||||||
|
ptr.getClass().getCreatureStats (ptr).getSpells().removeEffects(spellid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,18 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
namespace Transformation
|
namespace Transformation
|
||||||
{
|
{
|
||||||
|
void moveStandingActors(const MWWorld::Ptr &ptr, const osg::Vec3f& diff)
|
||||||
|
{
|
||||||
|
std::vector<MWWorld::Ptr> actors;
|
||||||
|
MWBase::Environment::get().getWorld()->getActorsStandingOn (ptr, actors);
|
||||||
|
for (auto& actor : actors)
|
||||||
|
{
|
||||||
|
osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
|
||||||
|
actorPos += diff;
|
||||||
|
MWBase::Environment::get().getWorld()->moveObject(actor, actorPos.x(), actorPos.y(), actorPos.z());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<class R>
|
template<class R>
|
||||||
class OpSetScale : public Interpreter::Opcode0
|
class OpSetScale : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
|
@ -839,6 +851,9 @@ namespace MWScript
|
||||||
osg::Vec3f worldPos(ptr.getRefData().getPosition().asVec3());
|
osg::Vec3f worldPos(ptr.getRefData().getPosition().asVec3());
|
||||||
worldPos += diff;
|
worldPos += diff;
|
||||||
|
|
||||||
|
// We should move actors, standing on moving object, too.
|
||||||
|
// This approach can be used to create elevators.
|
||||||
|
moveStandingActors(ptr, diff);
|
||||||
MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x(), worldPos.y(), worldPos.z());
|
MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x(), worldPos.y(), worldPos.z());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -861,22 +876,21 @@ namespace MWScript
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
const float *objPos = ptr.getRefData().getPosition().pos;
|
const float *objPos = ptr.getRefData().getPosition().pos;
|
||||||
|
osg::Vec3f diff;
|
||||||
|
|
||||||
MWWorld::Ptr updated;
|
|
||||||
if (axis == "x")
|
if (axis == "x")
|
||||||
{
|
diff.x() += movement;
|
||||||
updated = MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0]+movement, objPos[1], objPos[2]);
|
|
||||||
}
|
|
||||||
else if (axis == "y")
|
else if (axis == "y")
|
||||||
{
|
diff.y() += movement;
|
||||||
updated = MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0], objPos[1]+movement, objPos[2]);
|
|
||||||
}
|
|
||||||
else if (axis == "z")
|
else if (axis == "z")
|
||||||
{
|
diff.z() += movement;
|
||||||
updated = MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0], objPos[1], objPos[2]+movement);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
throw std::runtime_error ("invalid movement axis: " + axis);
|
throw std::runtime_error ("invalid movement axis: " + axis);
|
||||||
|
|
||||||
|
// We should move actors, standing on moving object, too.
|
||||||
|
// This approach can be used to create elevators.
|
||||||
|
moveStandingActors(ptr, diff);
|
||||||
|
MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0]+diff.x(), objPos[1]+diff.y(), objPos[2]+diff.z());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1145,14 +1145,24 @@ bool OpenAL_Output::playSound(Sound *sound, Sound_Handle data, float offset)
|
||||||
|
|
||||||
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(),
|
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(),
|
||||||
sound->getIsLooping(), sound->getUseEnv());
|
sound->getIsLooping(), sound->getUseEnv());
|
||||||
|
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
||||||
alSourcef(source, AL_SEC_OFFSET, offset);
|
alSourcef(source, AL_SEC_OFFSET, offset);
|
||||||
if(getALError() != AL_NO_ERROR)
|
if(getALError() != AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
alSourceRewind(source);
|
||||||
|
alSourcei(source, AL_BUFFER, 0);
|
||||||
|
alGetError();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
|
||||||
alSourcePlay(source);
|
alSourcePlay(source);
|
||||||
if(getALError() != AL_NO_ERROR)
|
if(getALError() != AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
alSourceRewind(source);
|
||||||
|
alSourcei(source, AL_BUFFER, 0);
|
||||||
|
alGetError();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
mFreeSources.pop_front();
|
mFreeSources.pop_front();
|
||||||
sound->mHandle = MAKE_PTRID(source);
|
sound->mHandle = MAKE_PTRID(source);
|
||||||
|
@ -1175,14 +1185,24 @@ bool OpenAL_Output::playSound3D(Sound *sound, Sound_Handle data, float offset)
|
||||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
||||||
sound->getRealVolume(), sound->getPitch(), sound->getIsLooping(),
|
sound->getRealVolume(), sound->getPitch(), sound->getIsLooping(),
|
||||||
sound->getUseEnv());
|
sound->getUseEnv());
|
||||||
|
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
||||||
alSourcef(source, AL_SEC_OFFSET, offset);
|
alSourcef(source, AL_SEC_OFFSET, offset);
|
||||||
if(getALError() != AL_NO_ERROR)
|
if(getALError() != AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
alSourceRewind(source);
|
||||||
|
alSourcei(source, AL_BUFFER, 0);
|
||||||
|
alGetError();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
|
||||||
alSourcePlay(source);
|
alSourcePlay(source);
|
||||||
if(getALError() != AL_NO_ERROR)
|
if(getALError() != AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
alSourceRewind(source);
|
||||||
|
alSourcei(source, AL_BUFFER, 0);
|
||||||
|
alGetError();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
mFreeSources.pop_front();
|
mFreeSources.pop_front();
|
||||||
sound->mHandle = MAKE_PTRID(source);
|
sound->mHandle = MAKE_PTRID(source);
|
||||||
|
@ -1197,9 +1217,8 @@ void OpenAL_Output::finishSound(Sound *sound)
|
||||||
ALuint source = GET_PTRID(sound->mHandle);
|
ALuint source = GET_PTRID(sound->mHandle);
|
||||||
sound->mHandle = 0;
|
sound->mHandle = 0;
|
||||||
|
|
||||||
// Rewind the stream instead of stopping it, this puts the source into an AL_INITIAL state,
|
// Rewind the stream to put the source back into an AL_INITIAL state, for
|
||||||
// which works around a bug in the MacOS OpenAL implementation which would otherwise think
|
// the next time it's used.
|
||||||
// the initial queue already played when it hasn't.
|
|
||||||
alSourceRewind(source);
|
alSourceRewind(source);
|
||||||
alSourcei(source, AL_BUFFER, 0);
|
alSourcei(source, AL_BUFFER, 0);
|
||||||
getALError();
|
getALError();
|
||||||
|
@ -1302,9 +1321,8 @@ void OpenAL_Output::finishStream(Stream *sound)
|
||||||
sound->mHandle = 0;
|
sound->mHandle = 0;
|
||||||
mStreamThread->remove(stream);
|
mStreamThread->remove(stream);
|
||||||
|
|
||||||
// Rewind the stream instead of stopping it, this puts the source into an AL_INITIAL state,
|
// Rewind the stream to put the source back into an AL_INITIAL state, for
|
||||||
// which works around a bug in the MacOS OpenAL implementation which would otherwise think
|
// the next time it's used.
|
||||||
// the initial queue already played when it hasn't.
|
|
||||||
alSourceRewind(source);
|
alSourceRewind(source);
|
||||||
alSourcei(source, AL_BUFFER, 0);
|
alSourcei(source, AL_BUFFER, 0);
|
||||||
getALError();
|
getALError();
|
||||||
|
|
|
@ -139,10 +139,10 @@ namespace MWSound
|
||||||
Sound_Buffer *SoundManager::insertSound(const std::string &soundId, const ESM::Sound *sound)
|
Sound_Buffer *SoundManager::insertSound(const std::string &soundId, const ESM::Sound *sound)
|
||||||
{
|
{
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
static const float fAudioDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMinDistance")->getFloat();
|
static const float fAudioDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMinDistance")->mValue.getFloat();
|
||||||
static const float fAudioDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMaxDistance")->getFloat();
|
static const float fAudioDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMaxDistance")->mValue.getFloat();
|
||||||
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
|
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->mValue.getFloat();
|
||||||
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->getFloat();
|
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->mValue.getFloat();
|
||||||
float volume, min, max;
|
float volume, min, max;
|
||||||
|
|
||||||
volume = static_cast<float>(pow(10.0, (sound->mData.mVolume / 255.0*3348.0 - 3348.0) / 2000.0));
|
volume = static_cast<float>(pow(10.0, (sound->mData.mVolume / 255.0*3348.0 - 3348.0) / 2000.0));
|
||||||
|
@ -296,10 +296,10 @@ namespace MWSound
|
||||||
Stream *SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal)
|
Stream *SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal)
|
||||||
{
|
{
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
|
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->mValue.getFloat();
|
||||||
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->getFloat();
|
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->mValue.getFloat();
|
||||||
static const float fAudioVoiceDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioVoiceDefaultMinDistance")->getFloat();
|
static const float fAudioVoiceDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioVoiceDefaultMinDistance")->mValue.getFloat();
|
||||||
static const float fAudioVoiceDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioVoiceDefaultMaxDistance")->getFloat();
|
static const float fAudioVoiceDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioVoiceDefaultMaxDistance")->mValue.getFloat();
|
||||||
static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f);
|
static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f);
|
||||||
static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance);
|
static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance);
|
||||||
|
|
||||||
|
|
|
@ -1130,7 +1130,7 @@ namespace MWWorld
|
||||||
void clearCorpse(const MWWorld::Ptr& ptr)
|
void clearCorpse(const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
const MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
|
const MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr);
|
||||||
static const float fCorpseClearDelay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fCorpseClearDelay")->getFloat();
|
static const float fCorpseClearDelay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fCorpseClearDelay")->mValue.getFloat();
|
||||||
if (creatureStats.isDead() &&
|
if (creatureStats.isDead() &&
|
||||||
creatureStats.isDeathAnimationFinished() &&
|
creatureStats.isDeathAnimationFinished() &&
|
||||||
!ptr.getClass().isPersistent(ptr) &&
|
!ptr.getClass().isPersistent(ptr) &&
|
||||||
|
@ -1144,7 +1144,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
if (mState == State_Loaded)
|
if (mState == State_Loaded)
|
||||||
{
|
{
|
||||||
static const int iMonthsToRespawn = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iMonthsToRespawn")->getInt();
|
static const int iMonthsToRespawn = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iMonthsToRespawn")->mValue.getInteger();
|
||||||
if (MWBase::Environment::get().getWorld()->getTimeStamp() - mLastRespawn > 24*30*iMonthsToRespawn)
|
if (MWBase::Environment::get().getWorld()->getTimeStamp() - mLastRespawn > 24*30*iMonthsToRespawn)
|
||||||
{
|
{
|
||||||
mLastRespawn = MWBase::Environment::get().getWorld()->getTimeStamp();
|
mLastRespawn = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||||
|
|
|
@ -289,8 +289,8 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
|
||||||
const MWWorld::Store<ESM::GameSetting> &store = world->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &store = world->getStore().get<ESM::GameSetting>();
|
||||||
MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor);
|
MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor);
|
||||||
|
|
||||||
static float fUnarmoredBase1 = store.find("fUnarmoredBase1")->getFloat();
|
static float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat();
|
||||||
static float fUnarmoredBase2 = store.find("fUnarmoredBase2")->getFloat();
|
static float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat();
|
||||||
int unarmoredSkill = stats.getSkill(ESM::Skill::Unarmored).getModified();
|
int unarmoredSkill = stats.getSkill(ESM::Skill::Unarmored).getModified();
|
||||||
|
|
||||||
float unarmoredRating = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill);
|
float unarmoredRating = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill);
|
||||||
|
@ -958,7 +958,7 @@ void MWWorld::InventoryStore::rechargeItems(float duration)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
static float fMagicItemRechargePerSecond = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
static float fMagicItemRechargePerSecond = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
"fMagicItemRechargePerSecond")->getFloat();
|
"fMagicItemRechargePerSecond")->mValue.getFloat();
|
||||||
|
|
||||||
if (it->first->getCellRef().getEnchantmentCharge() <= it->second)
|
if (it->first->getCellRef().getEnchantmentCharge() <= it->second)
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace MWWorld
|
||||||
MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer());
|
MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer());
|
||||||
MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer());
|
MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer());
|
||||||
MWMechanics::DynamicStat<float> health = creatureStats.getDynamic(0);
|
MWMechanics::DynamicStat<float> health = creatureStats.getDynamic(0);
|
||||||
creatureStats.setHealth(int(health.getBase() / gmst.find("fWereWolfHealth")->getFloat()));
|
creatureStats.setHealth(int(health.getBase() / gmst.find("fWereWolfHealth")->mValue.getFloat()));
|
||||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||||
npcStats.setSkill(i, mSaveSkills[i]);
|
npcStats.setSkill(i, mSaveSkills[i]);
|
||||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||||
|
@ -89,7 +89,7 @@ namespace MWWorld
|
||||||
MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer());
|
MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer());
|
||||||
MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer());
|
MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer());
|
||||||
MWMechanics::DynamicStat<float> health = creatureStats.getDynamic(0);
|
MWMechanics::DynamicStat<float> health = creatureStats.getDynamic(0);
|
||||||
creatureStats.setHealth(int(health.getBase() * gmst.find("fWereWolfHealth")->getFloat()));
|
creatureStats.setHealth(int(health.getBase() * gmst.find("fWereWolfHealth")->mValue.getFloat()));
|
||||||
for(size_t i = 0;i < ESM::Attribute::Length;++i)
|
for(size_t i = 0;i < ESM::Attribute::Length;++i)
|
||||||
{
|
{
|
||||||
// Oh, Bethesda. It's "Intelligence".
|
// Oh, Bethesda. It's "Intelligence".
|
||||||
|
@ -97,7 +97,7 @@ namespace MWWorld
|
||||||
ESM::Attribute::sAttributeNames[i]);
|
ESM::Attribute::sAttributeNames[i]);
|
||||||
|
|
||||||
MWMechanics::AttributeValue value = npcStats.getAttribute(i);
|
MWMechanics::AttributeValue value = npcStats.getAttribute(i);
|
||||||
value.setBase(int(gmst.find(name)->getFloat()));
|
value.setBase(int(gmst.find(name)->mValue.getFloat()));
|
||||||
npcStats.setAttribute(i, value);
|
npcStats.setAttribute(i, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ namespace MWWorld
|
||||||
ESM::Skill::sSkillNames[i]);
|
ESM::Skill::sSkillNames[i]);
|
||||||
|
|
||||||
MWMechanics::SkillValue value = npcStats.getSkill(i);
|
MWMechanics::SkillValue value = npcStats.getSkill(i);
|
||||||
value.setBase(int(gmst.find(name)->getFloat()));
|
value.setBase(int(gmst.find(name)->mValue.getFloat()));
|
||||||
npcStats.setSkill(i, value);
|
npcStats.setSkill(i, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
osg::Quat orient = it->mNode->getAttitude();
|
osg::Quat orient = it->mNode->getAttitude();
|
||||||
static float fTargetSpellMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static float fTargetSpellMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fTargetSpellMaxSpeed")->getFloat();
|
.find("fTargetSpellMaxSpeed")->mValue.getFloat();
|
||||||
float speed = fTargetSpellMaxSpeed * it->mSpeed;
|
float speed = fTargetSpellMaxSpeed * it->mSpeed;
|
||||||
osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
|
osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
|
||||||
direction.normalize();
|
direction.normalize();
|
||||||
|
|
|
@ -1039,7 +1039,7 @@ inline void WeatherManager::addWeather(const std::string& name,
|
||||||
float dlFactor, float dlOffset,
|
float dlFactor, float dlOffset,
|
||||||
const std::string& particleEffect)
|
const std::string& particleEffect)
|
||||||
{
|
{
|
||||||
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->getFloat();
|
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->mValue.getFloat();
|
||||||
|
|
||||||
Weather weather(name, fallback, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect);
|
Weather weather(name, fallback, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect);
|
||||||
|
|
||||||
|
|
|
@ -211,7 +211,7 @@ namespace MWWorld
|
||||||
mStore.setUp(true);
|
mStore.setUp(true);
|
||||||
mStore.movePlayerRecord();
|
mStore.movePlayerRecord();
|
||||||
|
|
||||||
mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->getFloat();
|
mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->mValue.getFloat();
|
||||||
|
|
||||||
mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering, mFallback, mStore));
|
mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering, mFallback, mStore));
|
||||||
|
|
||||||
|
@ -1179,7 +1179,7 @@ namespace MWWorld
|
||||||
if (mActivationDistanceOverride >= 0)
|
if (mActivationDistanceOverride >= 0)
|
||||||
return static_cast<float>(mActivationDistanceOverride);
|
return static_cast<float>(mActivationDistanceOverride);
|
||||||
|
|
||||||
static const int iMaxActivateDist = getStore().get<ESM::GameSetting>().find("iMaxActivateDist")->getInt();
|
static const int iMaxActivateDist = getStore().get<ESM::GameSetting>().find("iMaxActivateDist")->mValue.getInteger();
|
||||||
return static_cast<float>(iMaxActivateDist);
|
return static_cast<float>(iMaxActivateDist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1941,11 +1941,11 @@ namespace MWWorld
|
||||||
|
|
||||||
// Sink the camera while sneaking
|
// Sink the camera while sneaking
|
||||||
bool sneaking = player.getClass().getCreatureStats(getPlayerPtr()).getStance(MWMechanics::CreatureStats::Stance_Sneak);
|
bool sneaking = player.getClass().getCreatureStats(getPlayerPtr()).getStance(MWMechanics::CreatureStats::Stance_Sneak);
|
||||||
bool inair = !isOnGround(player);
|
|
||||||
bool swimming = isSwimming(player);
|
bool swimming = isSwimming(player);
|
||||||
|
bool flying = isFlying(player);
|
||||||
|
|
||||||
static const float i1stPersonSneakDelta = getStore().get<ESM::GameSetting>().find("i1stPersonSneakDelta")->getFloat();
|
static const float i1stPersonSneakDelta = getStore().get<ESM::GameSetting>().find("i1stPersonSneakDelta")->mValue.getFloat();
|
||||||
if (sneaking && !(swimming || inair))
|
if (sneaking && !swimming && !flying)
|
||||||
mRendering->getCamera()->setSneakOffset(i1stPersonSneakDelta);
|
mRendering->getCamera()->setSneakOffset(i1stPersonSneakDelta);
|
||||||
else
|
else
|
||||||
mRendering->getCamera()->setSneakOffset(0.f);
|
mRendering->getCamera()->setSneakOffset(0.f);
|
||||||
|
@ -2726,6 +2726,11 @@ namespace MWWorld
|
||||||
return !actors.empty();
|
return !actors.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector<MWWorld::Ptr> &actors)
|
||||||
|
{
|
||||||
|
mPhysics->getActorsStandingOn(object, actors);
|
||||||
|
}
|
||||||
|
|
||||||
bool World::getPlayerCollidingWith (const MWWorld::ConstPtr& object)
|
bool World::getPlayerCollidingWith (const MWWorld::ConstPtr& object)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = getPlayerPtr();
|
MWWorld::Ptr player = getPlayerPtr();
|
||||||
|
@ -3189,7 +3194,7 @@ namespace MWWorld
|
||||||
if (!actor.isEmpty() && actor != MWMechanics::getPlayer() && !manualSpell)
|
if (!actor.isEmpty() && actor != MWMechanics::getPlayer() && !manualSpell)
|
||||||
stats.getAiSequence().getCombatTargets(targetActors);
|
stats.getAiSequence().getCombatTargets(targetActors);
|
||||||
|
|
||||||
const float fCombatDistance = getStore().get<ESM::GameSetting>().find("fCombatDistance")->getFloat();
|
const float fCombatDistance = getStore().get<ESM::GameSetting>().find("fCombatDistance")->mValue.getFloat();
|
||||||
|
|
||||||
osg::Vec3f hitPosition = actor.getRefData().getPosition().asVec3();
|
osg::Vec3f hitPosition = actor.getRefData().getPosition().asVec3();
|
||||||
|
|
||||||
|
@ -3307,10 +3312,34 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
void World::launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength)
|
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength)
|
||||||
{
|
{
|
||||||
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength);
|
// An initial position of projectile can be outside shooter's collision box, so any object between shooter and launch position will be ignored.
|
||||||
|
// To avoid this issue, we should check for impact immediately before launch the projectile.
|
||||||
|
// So we cast a 1-yard-length ray from shooter to launch position and check if there are collisions in this area.
|
||||||
|
// TODO: as a better solutuon we should handle projectiles during physics update, not during world update.
|
||||||
|
const osg::Vec3f sourcePos = worldPos + orient * osg::Vec3f(0,-1,0) * 64.f;
|
||||||
|
|
||||||
|
// Early out if the launch position is underwater
|
||||||
|
bool underwater = MWBase::Environment::get().getWorld()->isUnderwater(MWMechanics::getPlayer().getCell(), worldPos);
|
||||||
|
if (underwater)
|
||||||
|
{
|
||||||
|
mRendering->emitWaterRipple(worldPos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result.
|
||||||
|
std::vector<MWWorld::Ptr> targetActors;
|
||||||
|
if (!actor.isEmpty() && actor.getClass().isActor() && actor != MWMechanics::getPlayer())
|
||||||
|
actor.getClass().getCreatureStats(actor).getAiSequence().getCombatTargets(targetActors);
|
||||||
|
|
||||||
|
// Check for impact, if yes, handle hit, if not, launch projectile
|
||||||
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(sourcePos, worldPos, actor, targetActors, 0xff, MWPhysics::CollisionType_Projectile);
|
||||||
|
if (result.mHit)
|
||||||
|
MWMechanics::projectileHit(actor, result.mHitObject, bow, projectile, result.mHitPos, attackStrength);
|
||||||
|
else
|
||||||
|
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed, attackStrength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::launchMagicBolt (const std::string &spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection)
|
void World::launchMagicBolt (const std::string &spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection)
|
||||||
|
@ -3653,8 +3682,8 @@ namespace MWWorld
|
||||||
int bounty = player.getClass().getNpcStats(player).getBounty();
|
int bounty = player.getClass().getNpcStats(player).getBounty();
|
||||||
int playerGold = player.getClass().getContainerStore(player).count(ContainerStore::sGoldId);
|
int playerGold = player.getClass().getContainerStore(player).count(ContainerStore::sGoldId);
|
||||||
|
|
||||||
float fCrimeGoldDiscountMult = getStore().get<ESM::GameSetting>().find("fCrimeGoldDiscountMult")->getFloat();
|
float fCrimeGoldDiscountMult = getStore().get<ESM::GameSetting>().find("fCrimeGoldDiscountMult")->mValue.getFloat();
|
||||||
float fCrimeGoldTurnInMult = getStore().get<ESM::GameSetting>().find("fCrimeGoldTurnInMult")->getFloat();
|
float fCrimeGoldTurnInMult = getStore().get<ESM::GameSetting>().find("fCrimeGoldTurnInMult")->mValue.getFloat();
|
||||||
|
|
||||||
int discount = static_cast<int>(bounty * fCrimeGoldDiscountMult);
|
int discount = static_cast<int>(bounty * fCrimeGoldDiscountMult);
|
||||||
int turnIn = static_cast<int>(bounty * fCrimeGoldTurnInMult);
|
int turnIn = static_cast<int>(bounty * fCrimeGoldTurnInMult);
|
||||||
|
@ -3719,7 +3748,7 @@ namespace MWWorld
|
||||||
mPlayer->recordCrimeId();
|
mPlayer->recordCrimeId();
|
||||||
confiscateStolenItems(player);
|
confiscateStolenItems(player);
|
||||||
|
|
||||||
int iDaysinPrisonMod = getStore().get<ESM::GameSetting>().find("iDaysinPrisonMod")->getInt();
|
int iDaysinPrisonMod = getStore().get<ESM::GameSetting>().find("iDaysinPrisonMod")->mValue.getInteger();
|
||||||
mDaysInPrison = std::max(1, bounty / iDaysinPrisonMod);
|
mDaysInPrison = std::max(1, bounty / iDaysinPrisonMod);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -3777,7 +3806,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
const ESM::CreatureLevList* list = getStore().get<ESM::CreatureLevList>().find(creatureList);
|
const ESM::CreatureLevList* list = getStore().get<ESM::CreatureLevList>().find(creatureList);
|
||||||
|
|
||||||
int iNumberCreatures = getStore().get<ESM::GameSetting>().find("iNumberCreatures")->getInt();
|
int iNumberCreatures = getStore().get<ESM::GameSetting>().find("iNumberCreatures")->mValue.getInteger();
|
||||||
int numCreatures = 1 + Misc::Rng::rollDice(iNumberCreatures); // [1, iNumberCreatures]
|
int numCreatures = 1 + Misc::Rng::rollDice(iNumberCreatures); // [1, iNumberCreatures]
|
||||||
|
|
||||||
for (int i=0; i<numCreatures; ++i)
|
for (int i=0; i<numCreatures; ++i)
|
||||||
|
|
|
@ -684,6 +684,7 @@ namespace MWWorld
|
||||||
End of tes3mp addition
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector<MWWorld::Ptr> &actors); ///< get a list of actors standing on \a object
|
||||||
bool getPlayerStandingOn (const MWWorld::ConstPtr& object) override; ///< @return true if the player is standing on \a object
|
bool getPlayerStandingOn (const MWWorld::ConstPtr& object) override; ///< @return true if the player is standing on \a object
|
||||||
bool getActorStandingOn (const MWWorld::ConstPtr& object) override; ///< @return true if any actor is standing on \a object
|
bool getActorStandingOn (const MWWorld::ConstPtr& object) override; ///< @return true if any actor is standing on \a object
|
||||||
bool getPlayerCollidingWith(const MWWorld::ConstPtr& object) override; ///< @return true if the player is colliding with \a object
|
bool getPlayerCollidingWith(const MWWorld::ConstPtr& object) override; ///< @return true if the player is colliding with \a object
|
||||||
|
@ -766,8 +767,8 @@ namespace MWWorld
|
||||||
void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) override;
|
void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) override;
|
||||||
|
|
||||||
void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override;
|
void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override;
|
||||||
void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) override;
|
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) override;
|
||||||
|
|
||||||
void applyLoopingParticles(const MWWorld::Ptr& ptr) override;
|
void applyLoopingParticles(const MWWorld::Ptr& ptr) override;
|
||||||
|
|
||||||
|
|
|
@ -306,10 +306,22 @@ namespace Compiler
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
std::string lowerCase = Misc::StringUtils::lowerCase(name);
|
std::string lowerCase = Misc::StringUtils::lowerCase(name);
|
||||||
|
bool isKeyword = false;
|
||||||
for (; sKeywords[i]; ++i)
|
for (; sKeywords[i]; ++i)
|
||||||
if (lowerCase==sKeywords[i])
|
if (lowerCase==sKeywords[i])
|
||||||
|
{
|
||||||
|
isKeyword = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Russian localization and some mods use a quirk - add newline character directly
|
||||||
|
// to compiled bytecode via HEX-editor to implement multiline messageboxes.
|
||||||
|
// Of course, original editor will not compile such script.
|
||||||
|
// Allow messageboxes to bybass the "incomplete string or name" error.
|
||||||
|
if (lowerCase == "messagebox")
|
||||||
|
enableIgnoreNewlines();
|
||||||
|
else if (isKeyword)
|
||||||
|
mIgnoreNewline = false;
|
||||||
|
|
||||||
if (sKeywords[i])
|
if (sKeywords[i])
|
||||||
{
|
{
|
||||||
|
@ -357,9 +369,14 @@ namespace Compiler
|
||||||
// }
|
// }
|
||||||
else if (c=='\n')
|
else if (c=='\n')
|
||||||
{
|
{
|
||||||
error = true;
|
if (mIgnoreNewline)
|
||||||
mErrorHandler.error ("incomplete string or name", mLoc);
|
mErrorHandler.warning ("string contains newline character, make sure that it is intended", mLoc);
|
||||||
break;
|
else
|
||||||
|
{
|
||||||
|
error = true;
|
||||||
|
mErrorHandler.error ("incomplete string or name", mLoc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(c=='"' && name.empty()))
|
else if (!(c=='"' && name.empty()))
|
||||||
|
@ -502,6 +519,11 @@ namespace Compiler
|
||||||
if (get (c) && c!='=') // <== is a allowed as an alternative to <= :(
|
if (get (c) && c!='=') // <== is a allowed as an alternative to <= :(
|
||||||
putback (c);
|
putback (c);
|
||||||
}
|
}
|
||||||
|
else if (c == '<' || c == '>') // Treat <> and << as <
|
||||||
|
{
|
||||||
|
special = S_cmpLT;
|
||||||
|
mErrorHandler.warning (std::string("invalid operator <") + c + ", treating it as <", mLoc);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
putback (c);
|
putback (c);
|
||||||
|
@ -525,6 +547,11 @@ namespace Compiler
|
||||||
if (get (c) && c!='=') // >== is a allowed as an alternative to >= :(
|
if (get (c) && c!='=') // >== is a allowed as an alternative to >= :(
|
||||||
putback (c);
|
putback (c);
|
||||||
}
|
}
|
||||||
|
else if (c == '<' || c == '>') // Treat >< and >> as >
|
||||||
|
{
|
||||||
|
special = S_cmpGT;
|
||||||
|
mErrorHandler.warning (std::string("invalid operator >") + c + ", treating it as >", mLoc);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
putback (c);
|
putback (c);
|
||||||
|
@ -578,7 +605,7 @@ namespace Compiler
|
||||||
const Extensions *extensions)
|
const Extensions *extensions)
|
||||||
: mErrorHandler (errorHandler), mStream (inputStream), mExtensions (extensions),
|
: mErrorHandler (errorHandler), mStream (inputStream), mExtensions (extensions),
|
||||||
mPutback (Putback_None), mPutbackCode(0), mPutbackInteger(0), mPutbackFloat(0),
|
mPutback (Putback_None), mPutbackCode(0), mPutbackInteger(0), mPutbackFloat(0),
|
||||||
mStrictKeywords (false), mTolerantNames (false)
|
mStrictKeywords (false), mTolerantNames (false), mIgnoreNewline(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,6 +658,11 @@ namespace Compiler
|
||||||
mExtensions->listKeywords (keywords);
|
mExtensions->listKeywords (keywords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scanner::enableIgnoreNewlines()
|
||||||
|
{
|
||||||
|
mIgnoreNewline = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Scanner::enableStrictKeywords()
|
void Scanner::enableStrictKeywords()
|
||||||
{
|
{
|
||||||
mStrictKeywords = true;
|
mStrictKeywords = true;
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace Compiler
|
||||||
TokenLoc mPutbackLoc;
|
TokenLoc mPutbackLoc;
|
||||||
bool mStrictKeywords;
|
bool mStrictKeywords;
|
||||||
bool mTolerantNames;
|
bool mTolerantNames;
|
||||||
|
bool mIgnoreNewline;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -126,6 +127,11 @@ namespace Compiler
|
||||||
void listKeywords (std::vector<std::string>& keywords);
|
void listKeywords (std::vector<std::string>& keywords);
|
||||||
///< Append all known keywords to \a keywords.
|
///< Append all known keywords to \a keywords.
|
||||||
|
|
||||||
|
/// Treat newline character as a part of script command.
|
||||||
|
///
|
||||||
|
/// \attention This mode lasts only until the next keyword is reached.
|
||||||
|
void enableIgnoreNewlines();
|
||||||
|
|
||||||
/// Do not accept keywords in quotation marks anymore.
|
/// Do not accept keywords in quotation marks anymore.
|
||||||
///
|
///
|
||||||
/// \attention This mode lasts only until the next newline is reached.
|
/// \attention This mode lasts only until the next newline is reached.
|
||||||
|
|
|
@ -22,21 +22,6 @@ namespace ESM
|
||||||
mValue.write (esm, ESM::Variant::Format_Gmst);
|
mValue.write (esm, ESM::Variant::Format_Gmst);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GameSetting::getInt() const
|
|
||||||
{
|
|
||||||
return mValue.getInteger();
|
|
||||||
}
|
|
||||||
|
|
||||||
float GameSetting::getFloat() const
|
|
||||||
{
|
|
||||||
return mValue.getFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GameSetting::getString() const
|
|
||||||
{
|
|
||||||
return mValue.getString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameSetting::blank()
|
void GameSetting::blank()
|
||||||
{
|
{
|
||||||
mValue.setType (ESM::VT_None);
|
mValue.setType (ESM::VT_None);
|
||||||
|
|
|
@ -28,17 +28,6 @@ struct GameSetting
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
||||||
/// \todo remove the get* functions (redundant, since mValue has equivalent functions now).
|
|
||||||
|
|
||||||
int getInt() const;
|
|
||||||
///< Throws an exception if GMST is not of type int or float.
|
|
||||||
|
|
||||||
float getFloat() const;
|
|
||||||
///< Throws an exception if GMST is not of type int or float.
|
|
||||||
|
|
||||||
std::string getString() const;
|
|
||||||
///< Throwns an exception if GMST is not of type string.
|
|
||||||
|
|
||||||
void save(ESMWriter &esm, bool isDeleted = false) const;
|
void save(ESMWriter &esm, bool isDeleted = false) const;
|
||||||
|
|
||||||
void blank();
|
void blank();
|
||||||
|
|
|
@ -274,43 +274,46 @@ short MagicEffect::getResistanceEffect(short effect)
|
||||||
// Source https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attribute
|
// Source https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attribute
|
||||||
|
|
||||||
// <Effect, Effect providing resistance against first effect>
|
// <Effect, Effect providing resistance against first effect>
|
||||||
std::map<short, short> effects;
|
static std::map<short, short> effects;
|
||||||
effects[DisintegrateArmor] = Sanctuary;
|
if (effects.empty())
|
||||||
effects[DisintegrateWeapon] = Sanctuary;
|
|
||||||
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[DrainAttribute+i] = ResistMagicka;
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[DamageAttribute+i] = ResistMagicka;
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[AbsorbAttribute+i] = ResistMagicka;
|
|
||||||
for (int i=0; i<10; ++i)
|
|
||||||
effects[WeaknessToFire+i] = ResistMagicka;
|
|
||||||
|
|
||||||
effects[Burden] = ResistMagicka;
|
|
||||||
effects[Charm] = ResistMagicka;
|
|
||||||
effects[Silence] = ResistMagicka;
|
|
||||||
effects[Blind] = ResistMagicka;
|
|
||||||
effects[Sound] = ResistMagicka;
|
|
||||||
|
|
||||||
for (int i=0; i<2; ++i)
|
|
||||||
{
|
{
|
||||||
effects[CalmHumanoid+i] = ResistMagicka;
|
effects[DisintegrateArmor] = Sanctuary;
|
||||||
effects[FrenzyHumanoid+i] = ResistMagicka;
|
effects[DisintegrateWeapon] = Sanctuary;
|
||||||
effects[DemoralizeHumanoid+i] = ResistMagicka;
|
|
||||||
effects[RallyHumanoid+i] = ResistMagicka;
|
for (int i=0; i<5; ++i)
|
||||||
|
effects[DrainAttribute+i] = ResistMagicka;
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
effects[DamageAttribute+i] = ResistMagicka;
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
effects[AbsorbAttribute+i] = ResistMagicka;
|
||||||
|
for (int i=0; i<10; ++i)
|
||||||
|
effects[WeaknessToFire+i] = ResistMagicka;
|
||||||
|
|
||||||
|
effects[Burden] = ResistMagicka;
|
||||||
|
effects[Charm] = ResistMagicka;
|
||||||
|
effects[Silence] = ResistMagicka;
|
||||||
|
effects[Blind] = ResistMagicka;
|
||||||
|
effects[Sound] = ResistMagicka;
|
||||||
|
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
effects[CalmHumanoid+i] = ResistMagicka;
|
||||||
|
effects[FrenzyHumanoid+i] = ResistMagicka;
|
||||||
|
effects[DemoralizeHumanoid+i] = ResistMagicka;
|
||||||
|
effects[RallyHumanoid+i] = ResistMagicka;
|
||||||
|
}
|
||||||
|
|
||||||
|
effects[TurnUndead] = ResistMagicka;
|
||||||
|
|
||||||
|
effects[FireDamage] = ResistFire;
|
||||||
|
effects[FrostDamage] = ResistFrost;
|
||||||
|
effects[ShockDamage] = ResistShock;
|
||||||
|
effects[Vampirism] = ResistCommonDisease;
|
||||||
|
effects[Corprus] = ResistCorprusDisease;
|
||||||
|
effects[Poison] = ResistPoison;
|
||||||
|
effects[Paralyze] = ResistParalysis;
|
||||||
}
|
}
|
||||||
|
|
||||||
effects[TurnUndead] = ResistMagicka;
|
|
||||||
|
|
||||||
effects[FireDamage] = ResistFire;
|
|
||||||
effects[FrostDamage] = ResistFrost;
|
|
||||||
effects[ShockDamage] = ResistShock;
|
|
||||||
effects[Vampirism] = ResistCommonDisease;
|
|
||||||
effects[Corprus] = ResistCorprusDisease;
|
|
||||||
effects[Poison] = ResistPoison;
|
|
||||||
effects[Paralyze] = ResistParalysis;
|
|
||||||
|
|
||||||
if (effects.find(effect) != effects.end())
|
if (effects.find(effect) != effects.end())
|
||||||
return effects[effect];
|
return effects[effect];
|
||||||
else
|
else
|
||||||
|
@ -319,42 +322,44 @@ short MagicEffect::getResistanceEffect(short effect)
|
||||||
|
|
||||||
short MagicEffect::getWeaknessEffect(short effect)
|
short MagicEffect::getWeaknessEffect(short effect)
|
||||||
{
|
{
|
||||||
std::map<short, short> effects;
|
static std::map<short, short> effects;
|
||||||
|
if (effects.empty())
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[DrainAttribute+i] = WeaknessToMagicka;
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[DamageAttribute+i] = WeaknessToMagicka;
|
|
||||||
for (int i=0; i<5; ++i)
|
|
||||||
effects[AbsorbAttribute+i] = WeaknessToMagicka;
|
|
||||||
for (int i=0; i<10; ++i)
|
|
||||||
effects[WeaknessToFire+i] = WeaknessToMagicka;
|
|
||||||
|
|
||||||
effects[Burden] = WeaknessToMagicka;
|
|
||||||
effects[Charm] = WeaknessToMagicka;
|
|
||||||
effects[Silence] = WeaknessToMagicka;
|
|
||||||
effects[Blind] = WeaknessToMagicka;
|
|
||||||
effects[Sound] = WeaknessToMagicka;
|
|
||||||
|
|
||||||
for (int i=0; i<2; ++i)
|
|
||||||
{
|
{
|
||||||
effects[CalmHumanoid+i] = WeaknessToMagicka;
|
for (int i=0; i<5; ++i)
|
||||||
effects[FrenzyHumanoid+i] = WeaknessToMagicka;
|
effects[DrainAttribute+i] = WeaknessToMagicka;
|
||||||
effects[DemoralizeHumanoid+i] = WeaknessToMagicka;
|
for (int i=0; i<5; ++i)
|
||||||
effects[RallyHumanoid+i] = WeaknessToMagicka;
|
effects[DamageAttribute+i] = WeaknessToMagicka;
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
effects[AbsorbAttribute+i] = WeaknessToMagicka;
|
||||||
|
for (int i=0; i<10; ++i)
|
||||||
|
effects[WeaknessToFire+i] = WeaknessToMagicka;
|
||||||
|
|
||||||
|
effects[Burden] = WeaknessToMagicka;
|
||||||
|
effects[Charm] = WeaknessToMagicka;
|
||||||
|
effects[Silence] = WeaknessToMagicka;
|
||||||
|
effects[Blind] = WeaknessToMagicka;
|
||||||
|
effects[Sound] = WeaknessToMagicka;
|
||||||
|
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
effects[CalmHumanoid+i] = WeaknessToMagicka;
|
||||||
|
effects[FrenzyHumanoid+i] = WeaknessToMagicka;
|
||||||
|
effects[DemoralizeHumanoid+i] = WeaknessToMagicka;
|
||||||
|
effects[RallyHumanoid+i] = WeaknessToMagicka;
|
||||||
|
}
|
||||||
|
|
||||||
|
effects[TurnUndead] = WeaknessToMagicka;
|
||||||
|
|
||||||
|
effects[FireDamage] = WeaknessToFire;
|
||||||
|
effects[FrostDamage] = WeaknessToFrost;
|
||||||
|
effects[ShockDamage] = WeaknessToShock;
|
||||||
|
effects[Vampirism] = WeaknessToCommonDisease;
|
||||||
|
effects[Corprus] = WeaknessToCorprusDisease;
|
||||||
|
effects[Poison] = WeaknessToPoison;
|
||||||
|
|
||||||
|
effects[Paralyze] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
effects[TurnUndead] = WeaknessToMagicka;
|
|
||||||
|
|
||||||
effects[FireDamage] = WeaknessToFire;
|
|
||||||
effects[FrostDamage] = WeaknessToFrost;
|
|
||||||
effects[ShockDamage] = WeaknessToShock;
|
|
||||||
effects[Vampirism] = WeaknessToCommonDisease;
|
|
||||||
effects[Corprus] = WeaknessToCorprusDisease;
|
|
||||||
effects[Poison] = WeaknessToPoison;
|
|
||||||
|
|
||||||
effects[Paralyze] = -1;
|
|
||||||
|
|
||||||
if (effects.find(effect) != effects.end())
|
if (effects.find(effect) != effects.end())
|
||||||
return effects[effect];
|
return effects[effect];
|
||||||
else
|
else
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace
|
||||||
|
|
||||||
float v = 0.0f;
|
float v = 0.0f;
|
||||||
for(int i = 0;i < 3;++i)
|
for(int i = 0;i < 3;++i)
|
||||||
v += std::sin(fb*time*f[i] + o[1])*m[i];
|
v += std::sin(fb*time*f[i] + o[i])*m[i];
|
||||||
return v * s;
|
return v * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,17 +73,15 @@ namespace SceneUtil
|
||||||
float cycle_time;
|
float cycle_time;
|
||||||
float time_distortion;
|
float time_distortion;
|
||||||
|
|
||||||
const float pi = 3.14159265359;
|
|
||||||
|
|
||||||
if(mType == LT_Pulse || mType == LT_PulseSlow)
|
if(mType == LT_Pulse || mType == LT_PulseSlow)
|
||||||
{
|
{
|
||||||
cycle_time = 2.0f * pi;
|
cycle_time = 2.0f * osg::PI;
|
||||||
time_distortion = mType == LT_Pulse ? 20.0f : 4.f;
|
time_distortion = 3.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static const float fa = 0.785398f;
|
static const float fa = osg::PI / 4.0f;
|
||||||
static const float phase_wavelength = 120.0f * pi / fa;
|
static const float phase_wavelength = 120.0f * osg::PI / fa;
|
||||||
|
|
||||||
cycle_time = 500.0f;
|
cycle_time = 500.0f;
|
||||||
mPhase = std::fmod(mPhase + dt, phase_wavelength);
|
mPhase = std::fmod(mPhase + dt, phase_wavelength);
|
||||||
|
@ -94,12 +92,14 @@ namespace SceneUtil
|
||||||
if(mDirection > 0 && mDeltaCount > +cycle_time)
|
if(mDirection > 0 && mDeltaCount > +cycle_time)
|
||||||
{
|
{
|
||||||
mDirection = -1.0f;
|
mDirection = -1.0f;
|
||||||
mDeltaCount = 2.0f*cycle_time - mDeltaCount;
|
float extra = mDeltaCount - cycle_time;
|
||||||
|
mDeltaCount -= 2*extra;
|
||||||
}
|
}
|
||||||
if(mDirection < 0 && mDeltaCount < -cycle_time)
|
if(mDirection < 0 && mDeltaCount < -cycle_time)
|
||||||
{
|
{
|
||||||
mDirection = +1.0f;
|
mDirection = +1.0f;
|
||||||
mDeltaCount = -2.0f*cycle_time - mDeltaCount;
|
float extra = cycle_time - mDeltaCount;
|
||||||
|
mDeltaCount += 2*extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float fast = 4.0f/1.0f;
|
static const float fast = 4.0f/1.0f;
|
||||||
|
|
|
@ -8,6 +8,31 @@
|
||||||
#include "skeleton.hpp"
|
#include "skeleton.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline void accumulateMatrix(const osg::Matrixf& invBindMatrix, const osg::Matrixf& matrix, const float weight, osg::Matrixf& result)
|
||||||
|
{
|
||||||
|
osg::Matrixf m = invBindMatrix * matrix;
|
||||||
|
float* ptr = m.ptr();
|
||||||
|
float* ptrresult = result.ptr();
|
||||||
|
ptrresult[0] += ptr[0] * weight;
|
||||||
|
ptrresult[1] += ptr[1] * weight;
|
||||||
|
ptrresult[2] += ptr[2] * weight;
|
||||||
|
|
||||||
|
ptrresult[4] += ptr[4] * weight;
|
||||||
|
ptrresult[5] += ptr[5] * weight;
|
||||||
|
ptrresult[6] += ptr[6] * weight;
|
||||||
|
|
||||||
|
ptrresult[8] += ptr[8] * weight;
|
||||||
|
ptrresult[9] += ptr[9] * weight;
|
||||||
|
ptrresult[10] += ptr[10] * weight;
|
||||||
|
|
||||||
|
ptrresult[12] += ptr[12] * weight;
|
||||||
|
ptrresult[13] += ptr[13] * weight;
|
||||||
|
ptrresult[14] += ptr[14] * weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -141,28 +166,6 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void accumulateMatrix(const osg::Matrixf& invBindMatrix, const osg::Matrixf& matrix, float weight, osg::Matrixf& result)
|
|
||||||
{
|
|
||||||
osg::Matrixf m = invBindMatrix * matrix;
|
|
||||||
float* ptr = m.ptr();
|
|
||||||
float* ptrresult = result.ptr();
|
|
||||||
ptrresult[0] += ptr[0] * weight;
|
|
||||||
ptrresult[1] += ptr[1] * weight;
|
|
||||||
ptrresult[2] += ptr[2] * weight;
|
|
||||||
|
|
||||||
ptrresult[4] += ptr[4] * weight;
|
|
||||||
ptrresult[5] += ptr[5] * weight;
|
|
||||||
ptrresult[6] += ptr[6] * weight;
|
|
||||||
|
|
||||||
ptrresult[8] += ptr[8] * weight;
|
|
||||||
ptrresult[9] += ptr[9] * weight;
|
|
||||||
ptrresult[10] += ptr[10] * weight;
|
|
||||||
|
|
||||||
ptrresult[12] += ptr[12] * weight;
|
|
||||||
ptrresult[13] += ptr[13] * weight;
|
|
||||||
ptrresult[14] += ptr[14] * weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigGeometry::cull(osg::NodeVisitor* nv)
|
void RigGeometry::cull(osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
if (!mSkeleton)
|
if (!mSkeleton)
|
||||||
|
@ -173,7 +176,8 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!mSkeleton->getActive() && mLastFrameNumber != 0) || mLastFrameNumber == nv->getTraversalNumber())
|
unsigned int traversalNumber = nv->getTraversalNumber();
|
||||||
|
if (mLastFrameNumber == traversalNumber || (mLastFrameNumber != 0 && !mSkeleton->getActive()))
|
||||||
{
|
{
|
||||||
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
||||||
nv->pushOntoNodePath(&geom);
|
nv->pushOntoNodePath(&geom);
|
||||||
|
@ -181,10 +185,10 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
|
||||||
nv->popFromNodePath();
|
nv->popFromNodePath();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mLastFrameNumber = nv->getTraversalNumber();
|
mLastFrameNumber = traversalNumber;
|
||||||
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
osg::Geometry& geom = *getGeometry(mLastFrameNumber);
|
||||||
|
|
||||||
mSkeleton->updateBoneMatrices(nv->getTraversalNumber());
|
mSkeleton->updateBoneMatrices(traversalNumber);
|
||||||
|
|
||||||
// skinning
|
// skinning
|
||||||
const osg::Vec3Array* positionSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getVertexArray());
|
const osg::Vec3Array* positionSrc = static_cast<osg::Vec3Array*>(mSourceGeometry->getVertexArray());
|
||||||
|
@ -195,34 +199,31 @@ void RigGeometry::cull(osg::NodeVisitor* nv)
|
||||||
osg::Vec3Array* normalDst = static_cast<osg::Vec3Array*>(geom.getNormalArray());
|
osg::Vec3Array* normalDst = static_cast<osg::Vec3Array*>(geom.getNormalArray());
|
||||||
osg::Vec4Array* tangentDst = static_cast<osg::Vec4Array*>(geom.getTexCoordArray(7));
|
osg::Vec4Array* tangentDst = static_cast<osg::Vec4Array*>(geom.getTexCoordArray(7));
|
||||||
|
|
||||||
for (Bone2VertexMap::const_iterator it = mBone2VertexMap.begin(); it != mBone2VertexMap.end(); ++it)
|
for (auto &pair : mBone2VertexMap)
|
||||||
{
|
{
|
||||||
osg::Matrixf resultMat (0, 0, 0, 0,
|
osg::Matrixf resultMat (0, 0, 0, 0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
|
|
||||||
for (std::vector<BoneWeight>::const_iterator weightIt = it->first.begin(); weightIt != it->first.end(); ++weightIt)
|
for (auto &weight : pair.first)
|
||||||
{
|
{
|
||||||
Bone* bone = weightIt->first.first;
|
accumulateMatrix(weight.first.second, weight.first.first->mMatrixInSkeletonSpace, weight.second, resultMat);
|
||||||
const osg::Matrix& invBindMatrix = weightIt->first.second;
|
|
||||||
float weight = weightIt->second;
|
|
||||||
const osg::Matrixf& boneMatrix = bone->mMatrixInSkeletonSpace;
|
|
||||||
accumulateMatrix(invBindMatrix, boneMatrix, weight, resultMat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGeomToSkelMatrix)
|
if (mGeomToSkelMatrix)
|
||||||
resultMat *= (*mGeomToSkelMatrix);
|
resultMat *= (*mGeomToSkelMatrix);
|
||||||
|
|
||||||
for (std::vector<unsigned short>::const_iterator vertexIt = it->second.begin(); vertexIt != it->second.end(); ++vertexIt)
|
for (auto &vertex : pair.second)
|
||||||
{
|
{
|
||||||
unsigned short vertex = *vertexIt;
|
|
||||||
(*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]);
|
(*positionDst)[vertex] = resultMat.preMult((*positionSrc)[vertex]);
|
||||||
if (normalDst)
|
if (normalDst)
|
||||||
(*normalDst)[vertex] = osg::Matrix::transform3x3((*normalSrc)[vertex], resultMat);
|
(*normalDst)[vertex] = osg::Matrixf::transform3x3((*normalSrc)[vertex], resultMat);
|
||||||
|
|
||||||
if (tangentDst)
|
if (tangentDst)
|
||||||
{
|
{
|
||||||
osg::Vec4f srcTangent = (*tangentSrc)[vertex];
|
const osg::Vec4f& srcTangent = (*tangentSrc)[vertex];
|
||||||
osg::Vec3f transformedTangent = osg::Matrix::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat);
|
osg::Vec3f transformedTangent = osg::Matrixf::transform3x3(osg::Vec3f(srcTangent.x(), srcTangent.y(), srcTangent.z()), resultMat);
|
||||||
(*tangentDst)[vertex] = osg::Vec4f(transformedTangent, srcTangent.w());
|
(*tangentDst)[vertex] = osg::Vec4f(transformedTangent, srcTangent.w());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,15 @@
|
||||||
#include "unrefqueue.hpp"
|
#include "unrefqueue.hpp"
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
//#include <osg/Timer>
|
//#include <osg/Timer>
|
||||||
|
|
||||||
//#include <components/debug/debuglog.hpp>
|
//#include <components/debug/debuglog.hpp>
|
||||||
#include <components/sceneutil/workqueue.hpp>
|
|
||||||
|
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
|
void UnrefWorkItem::doWork()
|
||||||
class UnrefWorkItem : public SceneUtil::WorkItem
|
|
||||||
{
|
{
|
||||||
public:
|
mObjects.clear();
|
||||||
std::deque<osg::ref_ptr<const osg::Referenced> > mObjects;
|
}
|
||||||
|
|
||||||
virtual void doWork()
|
|
||||||
{
|
|
||||||
//osg::Timer timer;
|
|
||||||
//size_t objcount = mObjects.size();
|
|
||||||
mObjects.clear();
|
|
||||||
//Log(Debug::Verbose) << "cleared " << objcount << " objects in " << timer.time_m();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
UnrefQueue::UnrefQueue()
|
UnrefQueue::UnrefQueue()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
#ifndef OPENMW_COMPONENTS_UNREFQUEUE_H
|
#ifndef OPENMW_COMPONENTS_UNREFQUEUE_H
|
||||||
#define OPENMW_COMPONENTS_UNREFQUEUE_H
|
#define OPENMW_COMPONENTS_UNREFQUEUE_H
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
#include <osg/Referenced>
|
#include <osg/Referenced>
|
||||||
|
|
||||||
|
#include <components/sceneutil/workqueue.hpp>
|
||||||
|
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
class WorkQueue;
|
class WorkQueue;
|
||||||
class UnrefWorkItem;
|
|
||||||
|
class UnrefWorkItem : public SceneUtil::WorkItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::deque<osg::ref_ptr<const osg::Referenced> > mObjects;
|
||||||
|
virtual void doWork();
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Handles unreferencing of objects through the WorkQueue. Typical use scenario
|
/// @brief Handles unreferencing of objects through the WorkQueue. Typical use scenario
|
||||||
/// would be the main thread pushing objects that are no longer needed, and the background thread deleting them.
|
/// would be the main thread pushing objects that are no longer needed, and the background thread deleting them.
|
||||||
|
|
|
@ -1383,9 +1383,9 @@ We add several new script instructions:
|
||||||
* PlayBackgroundMusic (t)
|
* PlayBackgroundMusic (t)
|
||||||
* PlaylistBackgroundMusic (pl)
|
* PlaylistBackgroundMusic (pl)
|
||||||
* StopBackgroundMusic
|
* StopBackgroundMusic
|
||||||
* PlayEventMusic (t, loop=0, force=0)
|
* PlayEventMusic (t, priority, loop=0, force=0)
|
||||||
* PlaylistEventMusic (pl, loop=0, force=0)
|
* PlaylistEventMusic (pl, priority, loop=0, force=0)
|
||||||
* StopEventMusic
|
* StopEventMusic (priority)
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
|
@ -1393,8 +1393,14 @@ Arguments:
|
||||||
* pl (string): a playlist (specified by its ID)
|
* pl (string): a playlist (specified by its ID)
|
||||||
* loop (integer): looping or not
|
* loop (integer): looping or not
|
||||||
* force (integer): Terminate any other running event music first. If this flag is 0 and there is already event music playing the new event music is ignored. Event music provided by content developers will usually not set this flag.
|
* force (integer): Terminate any other running event music first. If this flag is 0 and there is already event music playing the new event music is ignored. Event music provided by content developers will usually not set this flag.
|
||||||
|
* priority (integer): Priority for event music. If there are multiple instances of active event music only the one with the highest priority will play. There can only ever be one instance of event music for any priority level. If event music of higher priority stops and there is event music of lower priority the event music of lower priority starts to play.
|
||||||
|
|
||||||
Note: An attempt to play a track or playlist that is currently playing is ignored. In this case the track or playlist does not restart.
|
Note: An attempt to play a track or playlist that is currently playing is ignored. In this case the track or playlist does not restart. Changes in looping behaviour are considered though.
|
||||||
|
|
||||||
|
New games starting with a new format omwgame file can use priorities as the developer sees fit. For old games where automatic injection of scripts and music records take place we define the following priorities:
|
||||||
|
|
||||||
|
* 10: Combat music
|
||||||
|
* 0: Basic event music
|
||||||
|
|
||||||
### Transition of Existing System
|
### Transition of Existing System
|
||||||
|
|
||||||
|
|
|
@ -47,4 +47,33 @@ Installing game files via Steam on macOS: DISK WRITE ERROR
|
||||||
[other entries]
|
[other entries]
|
||||||
}
|
}
|
||||||
|
|
||||||
Restart the Steam client. The download should now proceed.
|
Restart the Steam client. The download should now proceed.
|
||||||
|
|
||||||
|
In-game textures show up as pink
|
||||||
|
################################
|
||||||
|
|
||||||
|
:Symptoms:
|
||||||
|
Some textures don't show up and are replaced by pink "filler" textures.
|
||||||
|
|
||||||
|
:Cause:
|
||||||
|
Textures shipped with Morrowind are compressed with S3TC, a texture compression algorithm that was patented in
|
||||||
|
the United States until October 2017. Software drivers and operating system distributions released before that date
|
||||||
|
may not include support for this algorithm.
|
||||||
|
|
||||||
|
:Fix:
|
||||||
|
Upgrade your graphics drivers and/or operating system to the latest version.
|
||||||
|
|
||||||
|
Music plays, but only a black screen is shown
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
:Symptoms:
|
||||||
|
When launching OpenMW, audio is heard but there is only a black screen.
|
||||||
|
|
||||||
|
:Cause:
|
||||||
|
This can occur when you did not import the Morrowind.ini file when the launcher asked for it.
|
||||||
|
|
||||||
|
:Fix:
|
||||||
|
To fix it, you need to delete the `launcher.cfg` file from your configuration path
|
||||||
|
([Path description on Wiki](https://wiki.openmw.org/index.php?title=Paths)), then start the launcher, select your
|
||||||
|
Morrowind installation, and when the launcher asks whether the `Morrowind.ini` file should be imported, make sure
|
||||||
|
to select "Yes".
|
Loading…
Reference in a new issue