Merge branch 'master' into esxSelector

actorid
graffy76 11 years ago
commit 16d87ea1d1

51
.gitignore vendored

@ -1,24 +1,53 @@
build
*~
Doxygen
prebuilt
apps/openmw/config.hpp
Docs/mainpage.hpp
## make
CMakeFiles
*/CMakeFiles
CMakeCache.txt
moc_*.cxx
cmake_install.cmake
*.[ao]
CMakeLists.txt.user
Makefile
makefile
data
build
prebuilt
## doxygen
Doxygen
## ides/editors
*~
*.kdev4
CMakeLists.txt.user
*.swp
*.swo
*.kate-swp
.cproject
.project
.settings/
.settings
.directory
## resources
data
resources
/*.cfg
/*.desktop
/*.install
## binaries
/esmtool
/mwiniimport
/omwlauncher
/openmw
/opencs
## generated objects
apps/openmw/config.hpp
Docs/mainpage.hpp
moc_*.cxx
*.cxx_parameters
*qrc_launcher.cxx
*qrc_resources.cxx
*__*
*ui_datafilespage.h
*ui_graphicspage.h
*ui_mainwindow.h
*ui_playpage.h
*.[ao]
*.so

@ -77,6 +77,8 @@ namespace
ini.insert(loc, setting + "=" + val + "\r\n");
}
#define FIX(setting) add_setting(category, setting, get_setting(category, setting, inx), ini)
void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath)
{
std::string inx = read_to_string(inxPath);
@ -88,95 +90,94 @@ namespace
ini.erase(start, end-start);
std::string category;
std::string setting;
category = "General";
{
setting = "Werewolf FOV"; add_setting(category, setting, get_setting(category, setting, inx), ini);
FIX("Werewolf FOV");
}
category = "Moons";
{
setting = "Script Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
FIX("Script Color");
}
category = "Weather";
{
setting = "Snow Ripples"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Ripple Radius"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Ripples Per Flake"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Ripple Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Ripple Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Gravity Scale"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow High Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Low Kill"; add_setting(category, setting, get_setting(category, setting, inx), ini);
FIX("Snow Ripples");
FIX("Snow Ripple Radius");
FIX("Snow Ripples Per Flake");
FIX("Snow Ripple Scale");
FIX("Snow Ripple Speed");
FIX("Snow Gravity Scale");
FIX("Snow High Kill");
FIX("Snow Low Kill");
}
category = "Weather Blight";
{
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
FIX("Ambient Loop Sound ID");
}
category = "Weather Snow";
{
setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Diameter"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Height Min"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Height Max"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Snow Entrance Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Max Snowflakes"; add_setting(category, setting, get_setting(category, setting, inx), ini);
FIX("Sky Sunrise Color");
FIX("Sky Day Color");
FIX("Sky Sunset Color");
FIX("Sky Night Color");
FIX("Fog Sunrise Color");
FIX("Fog Day Color");
FIX("Fog Sunset Color");
FIX("Fog Night Color");
FIX("Ambient Sunrise Color");
FIX("Ambient Day Color");
FIX("Ambient Sunset Color");
FIX("Ambient Night Color");
FIX("Sun Sunrise Color");
FIX("Sun Day Color");
FIX("Sun Sunset Color");
FIX("Sun Night Color");
FIX("Sun Disc Sunset Color");
FIX("Transition Delta");
FIX("Land Fog Day Depth");
FIX("Land Fog Night Depth");
FIX("Clouds Maximum Percent");
FIX("Wind Speed");
FIX("Cloud Speed");
FIX("Glare View");
FIX("Cloud Texture");
FIX("Ambient Loop Sound ID");
FIX("Snow Threshold");
FIX("Snow Diameter");
FIX("Snow Height Min");
FIX("Snow Height Max");
FIX("Snow Entrance Speed");
FIX("Max Snowflakes");
}
category = "Weather Blizzard";
{
setting = "Sky Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sky Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sky Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sky Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Fog Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Fog Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Fog Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Fog Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Sunrise Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Day Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Night Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Sun Disc Sunset Color"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Transition Delta"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Land Fog Day Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Land Fog Night Depth"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Clouds Maximum Percent"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Wind Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Cloud Speed"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Glare View"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Cloud Texture"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Ambient Loop Sound ID"; add_setting(category, setting, get_setting(category, setting, inx), ini);
setting = "Storm Threshold"; add_setting(category, setting, get_setting(category, setting, inx), ini);
FIX("Sky Sunrise Color");
FIX("Sky Day Color");
FIX("Sky Sunset Color");
FIX("Sky Night Color");
FIX("Fog Sunrise Color");
FIX("Fog Day Color");
FIX("Fog Sunset Color");
FIX("Fog Night Color");
FIX("Ambient Sunrise Color");
FIX("Ambient Day Color");
FIX("Ambient Sunset Color");
FIX("Ambient Night Color");
FIX("Sun Sunrise Color");
FIX("Sun Day Color");
FIX("Sun Sunset Color");
FIX("Sun Night Color");
FIX("Sun Disc Sunset Color");
FIX("Transition Delta");
FIX("Land Fog Day Depth");
FIX("Land Fog Night Depth");
FIX("Clouds Maximum Percent");
FIX("Wind Speed");
FIX("Cloud Speed");
FIX("Glare View");
FIX("Cloud Texture");
FIX("Ambient Loop Sound ID");
FIX("Storm Threshold");
}
}
@ -268,6 +269,27 @@ namespace
strptime(time, "%d %B %Y", &tms);
return mktime(&tms);
}
// Some cds have cab files which have the Data Files subfolders outside the Data Files folder
void install_dfiles_outside(const bfs::path& from, const bfs::path& dFiles)
{
bfs::path fonts = findFile(from, "fonts", false);
if(fonts.string() != "")
installToPath(fonts, dFiles / "Fonts");
bfs::path music = findFile(from, "music", false);
if(music.string() != "")
installToPath(music, dFiles / "Music");
bfs::path sound = findFile(from, "sound", false);
if(sound.string() != "")
installToPath(sound, dFiles / "Sound");
bfs::path splash = findFile(from, "splash", false);
if(splash.string() != "")
installToPath(splash, dFiles / "Splash");
}
}
bool UnshieldThread::SetMorrowindPath(const std::string& path)
@ -365,6 +387,8 @@ bool UnshieldThread::extract()
installToPath(dFilesDir, outputDataFilesDir);
install_dfiles_outside(mwExtractPath, outputDataFilesDir);
// Videos are often kept uncompressed on the cd
bfs::path videosPath = findFile(mMorrowindPath.parent_path(), "video", false);
if(videosPath.string() != "")
@ -399,6 +423,8 @@ bool UnshieldThread::extract()
installToPath(dFilesDir, outputDataFilesDir);
install_dfiles_outside(tbExtractPath, outputDataFilesDir);
// Mt GOTY CD has Sounds in a seperate folder from the rest of the data files
bfs::path soundsPath = findFile(tbExtractPath, "sounds", false);
if(soundsPath.string() != "")
@ -426,6 +452,8 @@ bool UnshieldThread::extract()
bfs::path dFilesDir = findFile(bmExtractPath, "bloodmoon.esm").parent_path();
installToPath(dFilesDir, outputDataFilesDir);
install_dfiles_outside(bmExtractPath, outputDataFilesDir);
// My GOTY CD contains a folder within cab files called Tribunal patch,
// which contains Tribunal.esm

@ -59,7 +59,8 @@ opencs_hdrs_noqt (view/doc
opencs_units (view/world
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
cellcreator referenceablecreator referencecreator
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
scenetoolmode
)
opencs_units_noqt (view/world

@ -34,7 +34,7 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row,
{
string = data.toString();
}
else if (data.type()==QVariant::Int || data.type()==QVariant::UInt ||
else if ((data.type()==QVariant::Int || data.type()==QVariant::UInt) &&
CSMWorld::Columns::hasEnums (static_cast<CSMWorld::Columns::ColumnId> (mColumnId)))
{
int value = data.toInt();
@ -47,8 +47,10 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row,
}
else if (data.type()==QVariant::Bool)
{
string = data.toBool() ? "true" : " false";
string = data.toBool() ? "true" : "false";
}
else if (mText.empty() && !data.isValid())
return true;
else
return false;

@ -17,7 +17,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row,
const std::map<int, int>::const_iterator iter = columns.find (mColumnId);
if (iter==columns.end())
throw std::logic_error ("invalid column in test value test");
throw std::logic_error ("invalid column in value node test");
if (iter->second==-1)
return true;
@ -27,7 +27,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row,
QVariant data = table.data (index);
if (data.type()!=QVariant::Double && data.type()!=QVariant::Bool && data.type()!=QVariant::Int &&
data.type()!=QVariant::UInt)
data.type()!=QVariant::UInt && data.type()!=static_cast<QVariant::Type> (QMetaType::Float))
return false;
double value = data.toDouble();
@ -68,7 +68,7 @@ std::string CSMFilter::ValueNode::toString (bool numericColumns) const
<< CSMWorld::Columns::getName (static_cast<CSMWorld::Columns::ColumnId> (mColumnId))
<< "\"";
stream << ", \"";
stream << ", ";
if (mLower==mUpper && mLowerType!=Type_Infinite && mUpperType!=Type_Infinite)
stream << mLower;

@ -51,7 +51,7 @@ namespace CSMWorld
{ ColumnId_FactionIndex, "Faction Index" },
{ ColumnId_Charges, "Charges" },
{ ColumnId_Enchantment, "Enchantment" },
{ ColumnId_Value, "Coin Value" },
{ ColumnId_CoinValue, "Coin Value" },
{ ColumnId_Teleport, "Teleport" },
{ ColumnId_TeleportCell, "Teleport Cell" },
{ ColumnId_LockLevel, "Lock Level" },

@ -45,113 +45,113 @@ namespace CSMWorld
ColumnId_Charges = 32,
ColumnId_Enchantment = 33,
ColumnId_CoinValue = 34,
ColumnId_Teleport = 25,
ColumnId_TeleportCell = 26,
ColumnId_LockLevel = 27,
ColumnId_Key = 28,
ColumnId_Trap = 29,
ColumnId_BeastRace = 30,
ColumnId_AutoCalc = 31,
ColumnId_StarterSpell = 32,
ColumnId_AlwaysSucceeds = 33,
ColumnId_SleepForbidden = 34,
ColumnId_InteriorWater = 35,
ColumnId_InteriorSky = 36,
ColumnId_Model = 37,
ColumnId_Script = 38,
ColumnId_Icon = 39,
ColumnId_Weight = 40,
ColumnId_EnchantmentPoints = 31,
ColumnId_Quality = 32,
ColumnId_Ai = 33,
ColumnId_AiHello = 34,
ColumnId_AiFlee = 35,
ColumnId_AiFight = 36,
ColumnId_AiAlarm = 37,
ColumnId_BuysWeapons = 38,
ColumnId_BuysArmor = 39,
ColumnId_BuysClothing = 40,
ColumnId_BuysBooks = 41,
ColumnId_BuysIngredients = 42,
ColumnId_BuysLockpicks = 43,
ColumnId_BuysProbes = 44,
ColumnId_BuysLights = 45,
ColumnId_BuysApparati = 46,
ColumnId_BuysRepairItems = 47,
ColumnId_BuysMiscItems = 48,
ColumnId_BuysPotions = 49,
ColumnId_BuysMagicItems = 50,
ColumnId_SellsSpells = 51,
ColumnId_Trainer = 52,
ColumnId_Spellmaking = 53,
ColumnId_EnchantingService = 54,
ColumnId_RepairService = 55,
ColumnId_ApparatusType = 56,
ColumnId_ArmorType = 57,
ColumnId_Health = 58,
ColumnId_ArmorValue = 59,
ColumnId_Scroll = 60,
ColumnId_ClothingType = 61,
ColumnId_WeightCapacity = 62,
ColumnId_OrganicContainer = 63,
ColumnId_Respawn = 64,
ColumnId_CreatureType = 65,
ColumnId_SoulPoints = 66,
ColumnId_OriginalCreature = 67,
ColumnId_Biped = 68,
ColumnId_HasWeapon = 69,
ColumnId_NoMovement = 70,
ColumnId_Swims = 71,
ColumnId_Flies = 72,
ColumnId_Walks = 73,
ColumnId_Essential = 74,
ColumnId_SkeletonBlood = 75,
ColumnId_MetalBlood = 76,
ColumnId_OpenSound = 77,
ColumnId_CloseSound = 78,
ColumnId_Duration = 79,
ColumnId_Radius = 80,
ColumnId_Colour = 81,
ColumnId_Sound = 82,
ColumnId_Dynamic = 83,
ColumnId_Portable = 84,
ColumnId_NegativeLight = 85,
ColumnId_Flickering = 86,
ColumnId_SlowFlickering = 87,
ColumnId_Pulsing = 88,
ColumnId_SlowPulsing = 89,
ColumnId_Fire = 90,
ColumnId_OffByDefault = 91,
ColumnId_IsKey = 92,
ColumnId_Race = 93,
ColumnId_Class = 94,
Columnid_Hair = 95,
ColumnId_Head = 96,
ColumnId_Female = 97,
ColumnId_WeaponType = 98,
ColumnId_WeaponSpeed = 99,
ColumnId_WeaponReach = 100,
ColumnId_MinChop = 101,
ColumnId_MaxChip = 102,
Columnid_MinSlash = 103,
ColumnId_MaxSlash = 104,
ColumnId_MinThrust = 105,
ColumnId_MaxThrust = 106,
ColumnId_Magical = 107,
ColumnId_Silver = 108,
ColumnId_Filter = 109,
ColumnId_PositionXPos = 110,
ColumnId_PositionYPos = 111,
ColumnId_PositionZPos = 112,
ColumnId_PositionXRot = 113,
ColumnId_PositionYRot = 114,
ColumnId_PositionZRot = 115,
ColumnId_DoorPositionXPos = 116,
ColumnId_DoorPositionYPos = 117,
ColumnId_DoorPositionZPos = 118,
ColumnId_DoorPositionXRot = 119,
ColumnId_DoorPositionYRot = 120,
ColumnId_DoorPositionZRot = 121,
ColumnId_Teleport = 35,
ColumnId_TeleportCell = 36,
ColumnId_LockLevel = 37,
ColumnId_Key = 38,
ColumnId_Trap = 39,
ColumnId_BeastRace = 40,
ColumnId_AutoCalc = 41,
ColumnId_StarterSpell = 42,
ColumnId_AlwaysSucceeds = 43,
ColumnId_SleepForbidden = 44,
ColumnId_InteriorWater = 45,
ColumnId_InteriorSky = 46,
ColumnId_Model = 47,
ColumnId_Script = 48,
ColumnId_Icon = 49,
ColumnId_Weight = 50,
ColumnId_EnchantmentPoints = 51,
ColumnId_Quality = 52,
ColumnId_Ai = 53,
ColumnId_AiHello = 54,
ColumnId_AiFlee = 55,
ColumnId_AiFight = 56,
ColumnId_AiAlarm = 57,
ColumnId_BuysWeapons = 58,
ColumnId_BuysArmor = 59,
ColumnId_BuysClothing = 60,
ColumnId_BuysBooks = 61,
ColumnId_BuysIngredients = 62,
ColumnId_BuysLockpicks = 63,
ColumnId_BuysProbes = 64,
ColumnId_BuysLights = 65,
ColumnId_BuysApparati = 66,
ColumnId_BuysRepairItems = 67,
ColumnId_BuysMiscItems = 68,
ColumnId_BuysPotions = 69,
ColumnId_BuysMagicItems = 70,
ColumnId_SellsSpells = 71,
ColumnId_Trainer = 72,
ColumnId_Spellmaking = 73,
ColumnId_EnchantingService = 74,
ColumnId_RepairService = 75,
ColumnId_ApparatusType = 76,
ColumnId_ArmorType = 77,
ColumnId_Health = 78,
ColumnId_ArmorValue = 79,
ColumnId_Scroll = 80,
ColumnId_ClothingType = 81,
ColumnId_WeightCapacity = 82,
ColumnId_OrganicContainer = 83,
ColumnId_Respawn = 84,
ColumnId_CreatureType = 85,
ColumnId_SoulPoints = 86,
ColumnId_OriginalCreature = 87,
ColumnId_Biped = 88,
ColumnId_HasWeapon = 89,
ColumnId_NoMovement = 90,
ColumnId_Swims = 91,
ColumnId_Flies = 92,
ColumnId_Walks = 93,
ColumnId_Essential = 94,
ColumnId_SkeletonBlood = 95,
ColumnId_MetalBlood = 96,
ColumnId_OpenSound = 97,
ColumnId_CloseSound = 98,
ColumnId_Duration = 99,
ColumnId_Radius = 100,
ColumnId_Colour = 101,
ColumnId_Sound = 102,
ColumnId_Dynamic = 103,
ColumnId_Portable = 104,
ColumnId_NegativeLight = 105,
ColumnId_Flickering = 106,
ColumnId_SlowFlickering = 107,
ColumnId_Pulsing = 108,
ColumnId_SlowPulsing = 109,
ColumnId_Fire = 110,
ColumnId_OffByDefault = 111,
ColumnId_IsKey = 112,
ColumnId_Race = 113,
ColumnId_Class = 114,
Columnid_Hair = 115,
ColumnId_Head = 116,
ColumnId_Female = 117,
ColumnId_WeaponType = 118,
ColumnId_WeaponSpeed = 119,
ColumnId_WeaponReach = 120,
ColumnId_MinChop = 121,
ColumnId_MaxChip = 122,
Columnid_MinSlash = 123,
ColumnId_MaxSlash = 124,
ColumnId_MinThrust = 125,
ColumnId_MaxThrust = 126,
ColumnId_Magical = 127,
ColumnId_Silver = 128,
ColumnId_Filter = 129,
ColumnId_PositionXPos = 130,
ColumnId_PositionYPos = 131,
ColumnId_PositionZPos = 132,
ColumnId_PositionXRot = 133,
ColumnId_PositionYRot = 134,
ColumnId_PositionZRot = 135,
ColumnId_DoorPositionXPos = 136,
ColumnId_DoorPositionYPos = 137,
ColumnId_DoorPositionZPos = 138,
ColumnId_DoorPositionXRot = 139,
ColumnId_DoorPositionYRot = 140,
ColumnId_DoorPositionZRot = 141,
// Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values.

@ -87,6 +87,7 @@ namespace
static const TypeData sIndexArg[] =
{
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", 0 },
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
};

@ -86,10 +86,11 @@ namespace CSMWorld
Type_Reference,
Type_RegionMap,
Type_Filter,
Type_Filters
Type_Filters,
Type_Scene
};
enum { NumberOfTypes = Type_Filters+1 };
enum { NumberOfTypes = Type_Scene+1 };
private:

@ -1,6 +0,0 @@
#include "ocspropertywidget.hpp"
OcsPropertyWidget::OcsPropertyWidget(QObject *parent) :
QObject(parent)
{
}

@ -1,18 +0,0 @@
#ifndef OCSPROPERTYWIDGET_HPP
#define OCSPROPERTYWIDGET_HPP
#include <QObject>
class OcsPropertyWidget : public QObject
{
Q_OBJECT
public:
explicit OcsPropertyWidget(QObject *parent = 0);
signals:
public slots:
};
#endif // OCSPROPERTYWIDGET_HPP

@ -65,7 +65,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
if (path.parent_path().string()==mLocalData.string())
{
// path already points to the local data directory
message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str());
message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str());
mResultPath = path;
mValid = true;
}
@ -74,7 +74,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
// path points somewhere else or is a leaf name.
path = mLocalData / path.filename();
message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str());
message = QString::fromUtf8 (("Will be saved as: " + path.string()).c_str());
mResultPath = path;
mValid = true;

@ -115,6 +115,10 @@ void CSVDoc::View::setupWorldMenu()
world->addSeparator(); // items that don't represent single record lists follow here
QAction *scene = new QAction (tr ("Scene"), this);
connect (scene, SIGNAL (triggered()), this, SLOT (addSceneSubView()));
world->addAction (scene);
QAction *regionMap = new QAction (tr ("Region Map"), this);
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
world->addAction (regionMap);
@ -403,6 +407,11 @@ void CSVDoc::View::addFiltersSubView()
addSubView (CSMWorld::UniversalId::Type_Filters);
}
void CSVDoc::View::addSceneSubView()
{
addSubView (CSMWorld::UniversalId::Type_Scene);
}
void CSVDoc::View::abortOperation (int type)
{
mDocument->abortOperation (type);

@ -164,6 +164,8 @@ namespace CSVDoc
void addFiltersSubView();
void addSceneSubView();
void toggleShowStatusBar (bool show);
};
}

@ -0,0 +1,82 @@
#include "scenesubview.hpp"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include "../../model/doc/document.hpp"
#include "../filter/filterbox.hpp"
#include "tablebottombox.hpp"
#include "creator.hpp"
#include "scenetoolbar.hpp"
#include "scenetoolmode.hpp"
CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: SubView (id)
{
QVBoxLayout *layout = new QVBoxLayout;
layout->setContentsMargins (QMargins (0, 0, 0, 0));
layout->addWidget (mBottom =
new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id,
this), 0);
QHBoxLayout *layout2 = new QHBoxLayout;
layout2->setContentsMargins (QMargins (0, 0, 0, 0));
SceneToolbar *toolbar = new SceneToolbar (48, this);
// test
SceneToolMode *tool = new SceneToolMode (toolbar);
tool->addButton (":door.png", "a");
tool->addButton (":GMST.png", "b");
tool->addButton (":Info.png", "c");
toolbar->addTool (tool);
toolbar->addTool (new SceneToolMode (toolbar));
toolbar->addTool (new SceneToolMode (toolbar));
toolbar->addTool (new SceneToolMode (toolbar));
layout2->addWidget (toolbar, 0);
/// \todo replace with rendering widget
QPalette palette2 (palette());
palette2.setColor (QPalette::Background, Qt::white);
QLabel *placeholder = new QLabel ("Here goes the 3D scene", this);
placeholder->setAutoFillBackground (true);
placeholder->setPalette (palette2);
placeholder->setAlignment (Qt::AlignHCenter);
layout2->addWidget (placeholder, 1);
layout->insertLayout (0, layout2, 1);
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
layout->insertWidget (0, filterBox);
QWidget *widget = new QWidget;
widget->setLayout (layout);
setWidget (widget);
}
void CSVWorld::SceneSubView::setEditLock (bool locked)
{
}
void CSVWorld::SceneSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
{
}
void CSVWorld::SceneSubView::setStatusBar (bool show)
{
mBottom->setStatusBar (show);
}

@ -0,0 +1,37 @@
#ifndef CSV_WORLD_SCENESUBVIEW_H
#define CSV_WORLD_SCENESUBVIEW_H
#include "../doc/subview.hpp"
class QModelIndex;
namespace CSMDoc
{
class Document;
}
namespace CSVWorld
{
class Table;
class TableBottomBox;
class CreatorFactoryBase;
class SceneSubView : public CSVDoc::SubView
{
Q_OBJECT
TableBottomBox *mBottom;
public:
SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
virtual void setEditLock (bool locked);
virtual void updateEditorSetting (const QString& key, const QString& value);
virtual void setStatusBar (bool show);
};
}
#endif

@ -0,0 +1,17 @@
#include "scenetool.hpp"
#include "scenetoolbar.hpp"
CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent)
{
setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
setFixedSize (parent->getButtonSize(), parent->getButtonSize());
connect (this, SIGNAL (clicked()), this, SLOT (openRequest()));
}
void CSVWorld::SceneTool::openRequest()
{
showPanel (parentWidget()->mapToGlobal (pos()));
}

@ -0,0 +1,27 @@
#ifndef CSV_WORLD_SCENETOOL_H
#define CSV_WORLD_SCENETOOL_H
#include <QPushButton>
namespace CSVWorld
{
class SceneToolbar;
///< \brief Tool base class
class SceneTool : public QPushButton
{
Q_OBJECT
public:
SceneTool (SceneToolbar *parent);
virtual void showPanel (const QPoint& position) = 0;
private slots:
void openRequest();
};
}
#endif

@ -0,0 +1,29 @@
#include "scenetoolbar.hpp"
#include <QVBoxLayout>
#include "scenetool.hpp"
CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent)
: QWidget (parent), mButtonSize (buttonSize)
{
setFixedWidth (mButtonSize);
mLayout = new QVBoxLayout (this);
mLayout->setAlignment (Qt::AlignTop);
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
setLayout (mLayout);
}
void CSVWorld::SceneToolbar::addTool (SceneTool *tool)
{
mLayout->addWidget (tool, 0, Qt::AlignTop);
}
int CSVWorld::SceneToolbar::getButtonSize() const
{
return mButtonSize;
}

@ -0,0 +1,29 @@
#ifndef CSV_WORLD_SCENETOOLBAR_H
#define CSV_WORLD_SCENETOOLBAR_H
#include <QWidget>
class QVBoxLayout;
namespace CSVWorld
{
class SceneTool;
class SceneToolbar : public QWidget
{
Q_OBJECT
QVBoxLayout *mLayout;
int mButtonSize;
public:
SceneToolbar (int buttonSize, QWidget *parent = 0);
void addTool (SceneTool *tool);
int getButtonSize() const;
};
}
#endif

@ -0,0 +1,56 @@
#include "scenetoolmode.hpp"
#include <QHBoxLayout>
#include <QFrame>
#include <QSignalMapper>
#include "scenetoolbar.hpp"
CSVWorld::SceneToolMode::SceneToolMode (SceneToolbar *parent)
: SceneTool (parent), mButtonSize (parent->getButtonSize())
{
mPanel = new QFrame (this, Qt::Popup);
mLayout = new QHBoxLayout (mPanel);
mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
mPanel->setLayout (mLayout);
}
void CSVWorld::SceneToolMode::showPanel (const QPoint& position)
{
mPanel->move (position);
mPanel->show();
}
void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::string& id)
{
QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel);
button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
button->setFixedSize (mButtonSize, mButtonSize);
mLayout->addWidget (button);
mButtons.insert (std::make_pair (button, id));
connect (button, SIGNAL (clicked()), this, SLOT (selected()));
if (mButtons.size()==1)
setIcon (button->icon());
}
void CSVWorld::SceneToolMode::selected()
{
std::map<QPushButton *, std::string>::const_iterator iter =
mButtons.find (dynamic_cast<QPushButton *> (sender()));
if (iter!=mButtons.end())
{
mPanel->hide();
setIcon (iter->first->icon());
emit modeChanged (iter->second);
}
}

@ -0,0 +1,42 @@
#ifndef CSV_WORLD_SCENETOOL_MODE_H
#define CSV_WORLD_SCENETOOL_MODE_H
#include "scenetool.hpp"
#include <map>
class QHBoxLayout;
namespace CSVWorld
{
class SceneToolbar;
///< \brief Mode selector tool
class SceneToolMode : public SceneTool
{
Q_OBJECT
QWidget *mPanel;
QHBoxLayout *mLayout;
std::map<QPushButton *, std::string> mButtons; // widget, id
int mButtonSize;
public:
SceneToolMode (SceneToolbar *parent);
virtual void showPanel (const QPoint& position);
void addButton (const std::string& icon, const std::string& id);
signals:
void modeChanged (const std::string& id);
private slots:
void selected();
};
}
#endif

@ -13,6 +13,7 @@
#include "cellcreator.hpp"
#include "referenceablecreator.hpp"
#include "referencecreator.hpp"
#include "scenesubview.hpp"
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
{
@ -62,4 +63,5 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
new CSVDoc::SubViewFactoryWithCreator<TableSubView,
CreatorFactory<CSVFilter::FilterCreator> >);
manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory<SceneSubView>);
}

@ -399,8 +399,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding);
mEnvironment.setWindowManager (window);
if (mNewGame)
mEnvironment.getWindowManager()->setNewGame(true);
// Create the world
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins,
@ -410,6 +408,10 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
input->setPlayer(&mEnvironment.getWorld()->getPlayer());
window->initUI();
if (mNewGame)
// still redundant work here: recreate CharacterCreation(),
// double update visibility etc.
window->setNewGame(true);
window->renderWorldMap();
//Load translation data

@ -324,6 +324,7 @@ namespace MWBase
virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0;
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
virtual bool isSwimming(const MWWorld::Ptr &object) const = 0;
///Is the head of the creature underwater?
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
@ -389,6 +390,12 @@ namespace MWBase
/// Returns true if teleport spell effects are allowed.
virtual bool isTeleportingEnabled() const = 0;
/// Enables or disables use of levitation spell effect.
virtual void enableLevitation(bool enable) = 0;
/// Returns true if levitation spell effect is allowed.
virtual bool isLevitationEnabled() const = 0;
/// Turn actor into werewolf or normal form.
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;

@ -16,12 +16,34 @@
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp"
#include "../mwworld/customdata.hpp"
#include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
namespace
{
struct CustomData : public MWWorld::CustomData
{
float mTime;
///< Time remaining
CustomData(MWWorld::Ptr ptr)
{
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
mTime = ref->mBase->mData.mTime;
}
///< Constructs this CustomData from the base values for Ptr.
virtual MWWorld::CustomData *clone() const
{
return new CustomData (*this);
}
};
}
namespace MWClass
{
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -182,6 +204,21 @@ namespace MWClass
return action;
}
void Light::setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const
{
ensureCustomData(ptr);
float &timeRemaining = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
timeRemaining = duration;
}
float Light::getRemainingUsageTime (const MWWorld::Ptr& ptr) const
{
ensureCustomData(ptr);
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
}
MWWorld::Ptr
Light::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
@ -191,6 +228,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
}
void Light::ensureCustomData (const MWWorld::Ptr& ptr) const
{
if (!ptr.getRefData().getCustomData())
ptr.getRefData().setCustomData(new CustomData(ptr));
}
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
{
return npcServices & ESM::NPC::Lights;

@ -10,6 +10,8 @@ namespace MWClass
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
void ensureCustomData (const MWWorld::Ptr& ptr) const;
public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -56,6 +58,12 @@ namespace MWClass
const;
///< Generate action for using via inventory menu
virtual void setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const;
///< Sets the remaining duration of the object.
virtual float getRemainingUsageTime (const MWWorld::Ptr& ptr) const;
///< Returns the remaining duration of the object.
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual float getWeight (const MWWorld::Ptr& ptr) const;

@ -7,6 +7,7 @@
#include <OgreSceneNode.h>
#include <components/esm/loadmgef.hpp>
#include <components/esm/loadnpc.hpp>
#include "../mwbase/environment.hpp"
@ -396,9 +397,10 @@ namespace MWClass
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
MWBase::Environment::get().getSoundManager()->playSound3D(victim, "critical damage", 1.0f, 1.0f);
}
weapon.getCellRef().mCharge -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())),
weapon.getCellRef().mCharge);
if (!MWBase::Environment::get().getWorld()->getGodModeState())
weapon.getCellRef().mCharge -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge);
}
healthdmg = true;
}
@ -769,6 +771,37 @@ namespace MWClass
return x;
}
float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const
{
MWBase::World *world = MWBase::Environment::get().getWorld();
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
const float fallDistanceMin = gmst.find("fFallDamageDistanceMin")->getFloat();
if (fallHeight >= fallDistanceMin)
{
const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Jump)).mMagnitude;
const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat();
const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat();
const float fallDistanceBase = gmst.find("fFallDistanceBase")->getFloat();
const float fallDistanceMult = gmst.find("fFallDistanceMult")->getFloat();
float x = fallHeight - fallDistanceMin;
x -= (1.5 * acrobaticsSkill) + jumpSpellBonus;
x = std::max(0.0f, x);
float a = fallAcroBase + fallAcroMult * (100 - acrobaticsSkill);
x = fallDistanceBase + fallDistanceMult * x;
x *= a;
return x;
}
return 0;
}
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
{
ensureCustomData (ptr);

@ -97,6 +97,9 @@ namespace MWClass
virtual float getJump(const MWWorld::Ptr &ptr) const;
///< Return jump velocity (not accounting for movement)
virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const;
///< Return amount of health points lost when falling
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
///< Return desired movement.

@ -23,6 +23,7 @@ namespace MWGui
, mLastWallpaperChangeTime(0.f)
, mFirstLoad(true)
, mProgress(0)
, mVSyncWasEnabled(false)
{
getWidget(mLoadingText, "LoadingText");
getWidget(mProgressBar, "ProgressBar");
@ -67,6 +68,14 @@ namespace MWGui
void LoadingScreen::loadingOn()
{
// Temporarily turn off VSync, we want to do actual loading rather than waiting for the screen to sync.
// Threaded loading would be even better, of course - especially because some drivers force VSync to on and we can't change it.
// In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/
mVSyncWasEnabled = mWindow->isVSyncEnabled();
#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0)
mWindow->setVSyncEnabled(false);
#endif
setVisible(true);
if (mFirstLoad)
@ -83,6 +92,12 @@ namespace MWGui
void LoadingScreen::loadingOff()
{
// Re-enable vsync now.
// In Ogre 1.8, the swapBuffers argument is useless and setVSyncEnabled is bugged with GLX, nothing we can do :/
#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0)
mWindow->setVSyncEnabled(mVSyncWasEnabled);
#endif
setVisible(false);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading);
@ -212,7 +227,8 @@ namespace MWGui
// caused a sync / flush and would be expensive).
// We're doing this so we can do some actual loading while the GPU is busy with the render.
// This means the render is lagging a frame behind, but this is hardly noticable.
mWindow->swapBuffers(false); // never Vsync, makes no sense here
mWindow->swapBuffers();
mWindow->update(false);
if (!hasCompositor)

@ -57,6 +57,8 @@ namespace MWGui
Ogre::StringVector mResources;
bool mVSyncWasEnabled;
void changeWallpaper();
void draw();

@ -14,6 +14,7 @@ namespace MWGui
mMessageBoxSpeed = 0.1;
mInterMessageBoxe = NULL;
mStaticMessageBox = NULL;
mLastButtonPressed = -1;
}
void MessageBoxManager::onFrame (float frameDuration)
@ -62,6 +63,7 @@ namespace MWGui
}
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
mLastButtonPressed = mInterMessageBoxe->readPressedButton();
delete mInterMessageBoxe;
mInterMessageBoxe = NULL;
MWBase::Environment::get().getInputManager()->changeInputMode(
@ -107,6 +109,7 @@ namespace MWGui
}
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
mLastButtonPressed = -1;
return true;
}
@ -154,11 +157,9 @@ namespace MWGui
int MessageBoxManager::readPressedButton ()
{
if(mInterMessageBoxe != NULL)
{
return mInterMessageBoxe->readPressedButton();
}
return -1;
int pressed = mLastButtonPressed;
mLastButtonPressed = -1;
return pressed;
}
@ -421,9 +422,7 @@ namespace MWGui
int InteractiveMessageBox::readPressedButton ()
{
int pressed = mButtonPressed;
mButtonPressed = -1;
return pressed;
return mButtonPressed;
}
}

@ -56,6 +56,7 @@ namespace MWGui
MessageBox* mStaticMessageBox;
std::vector<MessageBoxManagerTimer> mTimers;
float mMessageBoxSpeed;
int mLastButtonPressed;
};
class MessageBox : public OEngine::GUI::Layout

@ -363,8 +363,12 @@ namespace MWGui
else if (_sender == mVSyncButton)
{
Settings::Manager::setBool("vsync", "Video", newState);
// Ogre::Window::setVSyncEnabled is bugged in 1.8
#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0)
MWBase::Environment::get().getWindowManager()->
messageBox("VSync will be applied after a restart", std::vector<std::string>());
#endif
apply();
}
else
{

@ -2,6 +2,9 @@
#include <boost/lexical_cast.hpp>
#include <sstream>
#include <iomanip>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
@ -169,13 +172,34 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->getGameSettingString(
ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")";
if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
ESM::MagicEffect::MagnitudeDisplayType displayType = effect->getMagnitudeDisplayType();
if (displayType == ESM::MagicEffect::MDT_TimesInt)
{
std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", "");
std::stringstream formatter;
formatter << std::fixed << std::setprecision(1) << " " << (effectIt->mMagnitude / 10.0f) << timesInt;
sourcesDescription += formatter.str();
}
else if ( displayType != ESM::MagicEffect::MDT_None )
{
std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "");
std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "");
sourcesDescription += ": " + boost::lexical_cast<std::string>(effectIt->mMagnitude);
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt);
if ( displayType == ESM::MagicEffect::MDT_Percentage )
sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", "");
else if ( displayType == ESM::MagicEffect::MDT_Feet )
sourcesDescription += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", "");
else if ( displayType == ESM::MagicEffect::MDT_Level )
{
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ?
MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", "") :
MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", "") );
}
else // ESM::MagicEffect::MDT_Points
{
sourcesDescription += " " + ((effectIt->mMagnitude > 1) ?
MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "") :
MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "") );
}
}
}

@ -2,6 +2,9 @@
#include <boost/lexical_cast.hpp>
#include <sstream>
#include <iomanip>
#include <MyGUI_ProgressBar.h>
#include <MyGUI_ImageBox.h>
#include <MyGUI_ControllerManager.h>
@ -405,6 +408,10 @@ namespace MWGui
std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "");
std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", "");
std::string pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", "");
std::string ft = MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", "");
std::string lvl = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", "");
std::string lvls = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", "");
std::string to = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "") + " ";
std::string sec = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", "");
std::string secs = " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", "");
@ -421,13 +428,32 @@ namespace MWGui
spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], "");
}
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
{
if (mEffectParams.mMagnMin == mEffectParams.mMagnMax)
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts);
else
{
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts;
if (mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) {
ESM::MagicEffect::MagnitudeDisplayType displayType = magicEffect->getMagnitudeDisplayType();
if ( displayType == ESM::MagicEffect::MDT_TimesInt ) {
std::string timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", "");
std::stringstream formatter;
formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f);
if (mEffectParams.mMagnMin != mEffectParams.mMagnMax)
formatter << to << (mEffectParams.mMagnMax / 10.0f);
formatter << timesInt;
spellLine += formatter.str();
}
else if ( displayType != ESM::MagicEffect::MDT_None ) {
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin);
if (mEffectParams.mMagnMin != mEffectParams.mMagnMax)
spellLine += to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax);
if ( displayType == ESM::MagicEffect::MDT_Percentage )
spellLine += pct;
else if ( displayType == ESM::MagicEffect::MDT_Feet )
spellLine += " " + ft;
else if ( displayType == ESM::MagicEffect::MDT_Level )
spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? lvl : lvls );
else // ESM::MagicEffect::MDT_Points
spellLine += " " + ((mEffectParams.mMagnMin == 1 && mEffectParams.mMagnMax == 1) ? pt : pts );
}
}

@ -61,20 +61,23 @@ namespace MWGui
const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre,
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
Translation::Storage& translationDataStorage, ToUTF8::FromType encoding)
: mGuiManager(NULL)
, mConsoleOnlyScripts(consoleOnlyScripts)
: mConsoleOnlyScripts(consoleOnlyScripts)
, mGuiManager(NULL)
, mRendering(ogre)
, mHud(NULL)
, mMap(NULL)
, mMenu(NULL)
, mStatsWindow(NULL)
, mToolTips(NULL)
, mStatsWindow(NULL)
, mMessageBoxManager(NULL)
, mConsole(NULL)
, mJournal(NULL)
, mDialogueWindow(NULL)
, mBookWindow(NULL)
, mContainerWindow(NULL)
, mDragAndDrop(NULL)
, mInventoryWindow(NULL)
, mScrollWindow(NULL)
, mBookWindow(NULL)
, mCountDialog(NULL)
, mTradeWindow(NULL)
, mSpellBuyingWindow(NULL)
@ -83,27 +86,37 @@ namespace MWGui
, mConfirmationDialog(NULL)
, mAlchemyWindow(NULL)
, mSpellWindow(NULL)
, mQuickKeysMenu(NULL)
, mLoadingScreen(NULL)
, mCharGen(NULL)
, mLevelupDialog(NULL)
, mWaitDialog(NULL)
, mSpellCreationDialog(NULL)
, mEnchantingDialog(NULL)
, mTrainingWindow(NULL)
, mMerchantRepair(NULL)
, mRepair(NULL)
, mSoulgemDialog(NULL)
, mRepair(NULL)
, mCompanionWindow(NULL)
, mTranslationDataStorage (translationDataStorage)
, mSoftwareCursor(NULL)
, mCharGen(NULL)
, mInputBlocker(NULL)
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
, mHudEnabled(true)
, mCursorVisible(true)
, mPlayerName()
, mPlayerRaceId()
, mPlayerAttributes()
, mPlayerMajorSkills()
, mPlayerMinorSkills()
, mPlayerMajorSkills()
, mPlayerSkillValues()
, mPlayerHealth()
, mPlayerMagicka()
, mPlayerFatigue()
, mGui(NULL)
, mGuiModes()
, mCursorManager(NULL)
, mGarbageDialogs()
, mShown(GW_ALL)
, mForceHidden(GW_None)
@ -113,13 +126,7 @@ namespace MWGui
, mFPS(0.0f)
, mTriangleCount(0)
, mBatchCount(0)
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
, mHudEnabled(true)
, mTranslationDataStorage (translationDataStorage)
, mCursorManager(NULL)
, mUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI"))
, mCursorVisible(true)
{
// Set up the GUI system
mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath);

@ -468,6 +468,41 @@ namespace MWInput
bool InputManager::keyPressed( const SDL_KeyboardEvent &arg )
{
// Cut, copy & paste
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
if (focus)
{
MyGUI::EditBox* edit = focus->castType<MyGUI::EditBox>(false);
if (edit && !edit->getEditReadOnly())
{
if (arg.keysym.sym == SDLK_v && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
{
char* text = SDL_GetClipboardText();
if (text)
{
edit->addText(MyGUI::UString(text));
SDL_free(text);
}
}
if (arg.keysym.sym == SDLK_x && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
{
std::string text = edit->getTextSelection();
if (text.length())
{
SDL_SetClipboardText(text.c_str());
edit->deleteTextSelection();
}
}
if (arg.keysym.sym == SDLK_c && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
{
std::string text = edit->getTextSelection();
if (text.length())
SDL_SetClipboardText(text.c_str());
}
}
}
mInputBinder->keyPressed (arg);
if(arg.keysym.sym == SDLK_RETURN

@ -31,18 +31,24 @@ namespace MWMechanics
calculateDynamicStats (ptr);
calculateCreatureStatModifiers (ptr);
// AI
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
{
// AI
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
creatureStats.getAiSequence().execute (ptr);
// fatigue restoration
calculateRestoration(ptr, duration);
}
}
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
{
if(!paused)
{
updateDrowning(ptr, duration);
updateEquippedLight(ptr, duration);
}
}
void Actors::adjustMagicEffects (const MWWorld::Ptr& creature)
@ -93,39 +99,29 @@ namespace MWMechanics
void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration)
{
CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
if (normalizedEncumbrance > 1)
normalizedEncumbrance = 1;
if (duration == 3600)
{
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0;
// the actor is sleeping, restore health and magicka
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0;
DynamicStat<float> health = stats.getHealth();
health.setCurrent (health.getCurrent() + 0.1 * endurance);
stats.setHealth (health);
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
float fFatigueReturnBase = store.get<ESM::GameSetting>().find("fFatigueReturnBase")->getFloat ();
float fFatigueReturnMult = store.get<ESM::GameSetting>().find("fFatigueReturnMult")->getFloat ();
float fEndFatigueMult = store.get<ESM::GameSetting>().find("fEndFatigueMult")->getFloat ();
float capacity = MWWorld::Class::get(ptr).getCapacity(ptr);
float encumbrance = MWWorld::Class::get(ptr).getEncumbrance(ptr);
float normalizedEncumbrance = (capacity == 0 ? 1 : encumbrance/capacity);
if (normalizedEncumbrance > 1)
normalizedEncumbrance = 1;
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
x *= fEndFatigueMult * endurance;
DynamicStat<float> fatigue = stats.getFatigue();
fatigue.setCurrent (fatigue.getCurrent() + 3600 * x);
stats.setFatigue (fatigue);
if (!stunted)
{
float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat ();
float fRestMagicMult = settings.find("fRestMagicMult")->getFloat ();
DynamicStat<float> magicka = stats.getMagicka();
magicka.setCurrent (magicka.getCurrent()
@ -133,6 +129,19 @@ namespace MWMechanics
stats.setMagicka (magicka);
}
}
// restore fatigue
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
float fEndFatigueMult = settings.find("fEndFatigueMult")->getFloat ();
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
x *= fEndFatigueMult * endurance;
DynamicStat<float> fatigue = stats.getFatigue();
fatigue.setCurrent (fatigue.getCurrent() + duration * x);
stats.setFatigue (fatigue);
}
void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr)
@ -196,6 +205,49 @@ namespace MWMechanics
stats.setTimeToStartDrowning(20);
}
void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration)
{
//If holding a light...
MWWorld::InventoryStore &inventoryStore = MWWorld::Class::get(ptr).getInventoryStore(ptr);
MWWorld::ContainerStoreIterator heldIter =
inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(heldIter.getType() == MWWorld::ContainerStore::Type_Light)
{
// Use time from the player's light
bool isPlayer = ptr.getRefData().getHandle()=="player";
if(isPlayer)
{
float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter);
// -1 is infinite light source. Other negative values are treated as 0.
if(timeRemaining != -1.0f)
{
timeRemaining -= duration;
if(timeRemaining > 0.0f)
heldIter->getClass().setRemainingUsageTime(*heldIter, timeRemaining);
else
{
heldIter->getRefData().setCount(0); // remove it
return;
}
}
}
// Both NPC and player lights extinguish in water.
if(MWBase::Environment::get().getWorld()->isSwimming(ptr))
{
heldIter->getRefData().setCount(0); // remove it
// ...But, only the player makes a sound.
if(isPlayer)
MWBase::Environment::get().getSoundManager()->playSound("torch out",
1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoEnv);
}
}
}
Actors::Actors() : mDuration (0) {}
void Actors::addActor (const MWWorld::Ptr& ptr)
@ -276,7 +328,8 @@ namespace MWMechanics
}
// If it's the player and God Mode is turned on, keep it alive
if(iter->first.getRefData().getHandle()=="player" && MWBase::Environment::get().getWorld()->getGodModeState())
if(iter->first.getRefData().getHandle()=="player" &&
MWBase::Environment::get().getWorld()->getGodModeState())
{
MWMechanics::DynamicStat<float> stat(stats.getHealth());

@ -44,6 +44,8 @@ namespace MWMechanics
void updateDrowning (const MWWorld::Ptr& ptr, float duration);
void updateEquippedLight (const MWWorld::Ptr& ptr, float duration);
public:
Actors();

@ -767,10 +767,25 @@ void CharacterController::update(float duration)
}
if(sneak || inwater || flying)
{
vec.z = 0.0f;
mFallHeight = mPtr.getRefData().getPosition().pos[2];
}
if(!onground && !flying && !inwater)
{
// The player is in the air (either getting up —ascending part of jump— or falling).
if (world->isSlowFalling(mPtr))
{
// SlowFalling spell effect is active, do not keep previous fall height
mFallHeight = mPtr.getRefData().getPosition().pos[2];
}
else
{
mFallHeight = std::max(mFallHeight, mPtr.getRefData().getPosition().pos[2]);
}
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
forcestateupdate = (mJumpState != JumpState_Falling);
@ -794,6 +809,8 @@ void CharacterController::update(float duration)
}
else if(vec.z > 0.0f && mJumpState == JumpState_None)
{
// The player has started a jump.
float z = cls.getJump(mPtr);
if(vec.x == 0 && vec.y == 0)
vec = Ogre::Vector3(0.0f, 0.0f, z);
@ -803,13 +820,49 @@ void CharacterController::update(float duration)
vec = Ogre::Vector3(lat.x, lat.y, 1.0f) * z * 0.707f;
}
//decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult;
// advance acrobatics
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0);
// decrease fatigue
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
const float fatigueJumpBase = gmst.find("fFatigueJumpBase")->getFloat();
const float fatigueJumpMult = gmst.find("fFatigueJumpMult")->getFloat();
const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr);
const int fatigueDecrease = fatigueJumpBase + (1 - normalizedEncumbrance) * fatigueJumpMult;
DynamicStat<float> fatigue = cls.getCreatureStats(mPtr).getFatigue();
fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease);
cls.getCreatureStats(mPtr).setFatigue(fatigue);
}
else if(mJumpState == JumpState_Falling)
{
// The player is landing.
forcestateupdate = true;
mJumpState = JumpState_Landing;
vec.z = 0.0f;
float healthLost = cls.getFallDamage(mPtr, mFallHeight - mPtr.getRefData().getPosition().pos[2]);
if (healthLost > 0.0f)
{
const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm();
// inflict fall damages
DynamicStat<float> health = cls.getCreatureStats(mPtr).getHealth();
int realHealthLost = healthLost * (1.0f - 0.25 * fatigueTerm);
health.setCurrent(health.getCurrent() - realHealthLost);
cls.getCreatureStats(mPtr).setHealth(health);
// report acrobatics progression
cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1);
const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified();
if (healthLost > (acrobaticsSkill * fatigueTerm))
{
//TODO: actor falls over
}
}
mFallHeight = mPtr.getRefData().getPosition().pos[2];
}
else
{

@ -3,6 +3,8 @@
#include <OgreVector3.h>
#include <components/esm/loadmgef.hpp>
#include "../mwworld/ptr.hpp"
namespace MWWorld
@ -154,6 +156,9 @@ class CharacterController
float mSecondsOfSwimming;
float mSecondsOfRunning;
// used for acrobatics progress and fall damages
float mFallHeight;
std::string mAttackType; // slash, chop or thrust
void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false);

@ -187,6 +187,12 @@ namespace MWRender
rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
}
void Camera::setSneakOffset()
{
if(mAnimation)
mAnimation->addFirstPersonOffset(Ogre::Vector3(0.f, 0.f, -9.8f));
}
float Camera::getYaw()
{
if(mVanity.enabled || mPreviewMode)

@ -79,6 +79,12 @@ namespace MWRender
void togglePreviewMode(bool enable);
/// \brief Lowers the camera for sneak.
/// As animation is tied to the camera, this needs
/// to be set each frame after the animation is
/// applied.
void setSneakOffset();
bool isFirstPerson() const
{ return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); }

@ -84,7 +84,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
mWeapon(inv.end()),
mShield(inv.end()),
mViewMode(viewMode),
mShowWeapons(false)
mShowWeapons(false),
mFirstPersonOffset(0.f, 0.f, 0.f)
{
mNpc = mPtr.get<ESM::NPC>()->mBase;
@ -392,6 +393,11 @@ void NpcAnimation::updateParts(bool forceupdate)
}
}
void NpcAnimation::addFirstPersonOffset(const Ogre::Vector3 &offset)
{
mFirstPersonOffset += offset;
}
class SetObjectGroup {
int mGroup;
@ -448,7 +454,12 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
float pitch = mCamera->getPitch();
Ogre::Node *node = baseinst->getBone("Bip01 Neck");
node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD);
// This has to be done before this function ends;
// updateSkeletonInstance, below, touches the hands.
node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD);
}
mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame.
for(size_t i = 0;i < ESM::PRT_Count;i++)
{

@ -64,6 +64,8 @@ private:
int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty
int mPartPriorities[ESM::PRT_Count];
Ogre::Vector3 mFirstPersonOffset;
void updateNpcBase();
NifOgre::ObjectList insertBoundedPart(const std::string &model, int group, const std::string &bonename);
@ -89,6 +91,11 @@ public:
void updateParts(bool forceupdate = false);
/// \brief Applies a translation to the arms and hands.
/// This may be called multiple times before the animation
/// is updated to add additional offsets.
void addFirstPersonOffset(const Ogre::Vector3 &offset);
/// Rebuilds the NPC, updating their root model, animation sources, and equipment.
void rebuild();
};

@ -354,6 +354,15 @@ void RenderingManager::update (float duration, bool paused)
mCamera->setCameraDistance(test.second * orig.distance(dest), false, false);
}
// Sink the camera while sneaking
bool isSneaking = MWWorld::Class::get(player).getStance(player, MWWorld::Class::Sneak);
bool isInAir = !world->isOnGround(player);
bool isSwimming = world->isSwimming(player);
if(isSneaking && !(isSwimming || isInAir))
mCamera->setSneakOffset();
mOcclusionQuery->update(duration);
mVideoPlayer->update ();
@ -760,6 +769,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
|| it->second == "resolution y"
|| it->second == "fullscreen"))
changeRes = true;
else if (it->first == "Video" && it->second == "vsync")
{
// setVSyncEnabled is bugged in 1.8
#if OGRE_VERSION >= (1 << 16 | 9 << 8 | 0)
mRendering.getWindow()->setVSyncEnabled(Settings::Manager::getBool("vsync", "Video"));
#endif
}
else if (it->second == "field of view" && it->first == "General")
mRendering.setFov(Settings::Manager::getFloat("field of view", "General"));
else if ((it->second == "texture filtering" && it->first == "General")

@ -352,5 +352,7 @@ op 0x200021c: SetWerewolfAcrobaticsExplicit
op 0x200021d: ShowVars
op 0x200021e: ShowVarsExplicit
op 0x200021f: ToggleGodMode
op 0x2000220: DisableLevitation
op 0x2000221: EnableLevitation
opcodes 0x2000220-0x3ffffff unused
opcodes 0x2000222-0x3ffffff unused

@ -635,7 +635,18 @@ namespace MWScript
world->enableTeleporting(Enable);
}
};
template <bool Enable>
class OpEnableLevitation : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
world->enableLevitation(Enable);
}
};
template <class R>
class OpShowVars : public Interpreter::Opcode0
@ -789,6 +800,8 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Misc::opcodeShowVars, new OpShowVars<ImplicitRef>);
interpreter.installSegment5 (Compiler::Misc::opcodeShowVarsExplicit, new OpShowVars<ExplicitRef>);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleGodMode, new OpToggleGodMode);
interpreter.installSegment5 (Compiler::Misc::opcodeDisableLevitation, new OpEnableLevitation<false>);
interpreter.installSegment5 (Compiler::Misc::opcodeEnableLevitation, new OpEnableLevitation<true>);
}
}
}

@ -132,6 +132,16 @@ namespace MWWorld
throw std::runtime_error ("class does not support unlocking");
}
void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const
{
throw std::runtime_error ("class does not support time-based uses");
}
float Class::getRemainingUsageTime (const Ptr& ptr) const
{
throw std::runtime_error ("class does not support time-based uses");
}
std::string Class::getScript (const Ptr& ptr) const
{
return "";
@ -167,6 +177,11 @@ namespace MWWorld
throw std::runtime_error ("class does not support enchanting");
}
float Class::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const
{
return 0;
}
MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
{
throw std::runtime_error ("movement settings not supported by class");

@ -156,6 +156,14 @@ namespace MWWorld
virtual void unlock (const Ptr& ptr) const;
///< Unlock object (default implementation: throw an exception)
virtual void setRemainingUsageTime (const Ptr& ptr, float duration) const;
///< Sets the remaining duration of the object, such as an equippable light
/// source. (default implementation: throw an exception)
virtual float getRemainingUsageTime (const Ptr& ptr) const;
///< Returns the remaining duration of the object, such as an equippable light
/// source. (default implementation: throw an exception)
virtual std::string getScript (const Ptr& ptr) const;
///< Return name of the script attached to ptr (default implementation: return an empty
/// string).
@ -175,6 +183,9 @@ namespace MWWorld
virtual float getJump(const MWWorld::Ptr &ptr) const;
///< Return jump velocity (not accounting for movement)
virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const;
///< Return amount of health points lost when falling
virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const;
///< Return desired movement.

@ -656,26 +656,38 @@ namespace MWWorld
return iterator(mSharedExt.end());
}
/// \todo implement appropriate index
// Return the northernmost cell in the easternmost column.
const ESM::Cell *searchExtByName(const std::string &id) const {
ESM::Cell *cell = 0;
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
for (; it != mSharedExt.end(); ++it) {
if (Misc::StringUtils::ciEqual((*it)->mName, id)) {
return *it;
if ( cell == 0 ||
( (*it)->mData.mX > cell->mData.mX ) ||
( (*it)->mData.mX == cell->mData.mX && (*it)->mData.mY > cell->mData.mY ) )
{
cell = *it;
}
}
}
return 0;
return cell;
}
/// \todo implement appropriate index
// Return the northernmost cell in the easternmost column.
const ESM::Cell *searchExtByRegion(const std::string &id) const {
ESM::Cell *cell = 0;
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
for (; it != mSharedExt.end(); ++it) {
if (Misc::StringUtils::ciEqual((*it)->mRegion, id)) {
return *it;
if ( cell == 0 ||
( (*it)->mData.mX > cell->mData.mX ) ||
( (*it)->mData.mX == cell->mData.mX && (*it)->mData.mY > cell->mData.mY ) )
{
cell = *it;
}
}
}
return 0;
return cell;
}
size_t getSize() const {

@ -225,8 +225,8 @@ namespace MWWorld
if (mEsm[0].getFormat() == 0)
ensureNeededRecords();
mStore.movePlayerRecord();
mStore.setUp();
mStore.movePlayerRecord();
mGlobalVariables = new Globals (mStore);
@ -1582,6 +1582,19 @@ namespace MWWorld
return false;
}
bool
World::isSlowFalling(const MWWorld::Ptr &ptr) const
{
if(!ptr.getClass().isActor())
return false;
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if(stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::SlowFall)).mMagnitude > 0)
return true;
return false;
}
bool World::isSubmerged(const MWWorld::Ptr &object) const
{
float *fpos = object.getRefData().getPosition().pos;
@ -1877,6 +1890,16 @@ namespace MWWorld
return mTeleportEnabled;
}
void World::enableLevitation(bool enable)
{
mLevitationEnabled = enable;
}
bool World::isLevitationEnabled() const
{
return mLevitationEnabled;
}
void World::setWerewolf(const MWWorld::Ptr& actor, bool werewolf)
{
MWMechanics::NpcStats& npcStats = Class::get(actor).getNpcStats(actor);

@ -116,6 +116,7 @@ namespace MWWorld
int mPlayIntro;
bool mTeleportEnabled;
bool mLevitationEnabled;
public:
@ -355,6 +356,7 @@ namespace MWWorld
virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
virtual bool isFlying(const MWWorld::Ptr &ptr) const;
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const;
///Is the head of the creature underwater?
virtual bool isSubmerged(const MWWorld::Ptr &object) const;
virtual bool isSwimming(const MWWorld::Ptr &object) const;
@ -438,6 +440,12 @@ namespace MWWorld
/// Returns true if teleport spell effects are allowed.
virtual bool isTeleportingEnabled() const;
/// Enables or disables use of levitation spell effect.
virtual void enableLevitation(bool enable);
/// Returns true if levitation spell effect is allowed.
virtual bool isLevitationEnabled() const;
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf);
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);

@ -260,6 +260,8 @@ namespace Compiler
extensions.registerInstruction ("sv", "", opcodeShowVars, opcodeShowVarsExplicit);
extensions.registerInstruction("tgm", "", opcodeToggleGodMode);
extensions.registerInstruction("togglegodmode", "", opcodeToggleGodMode);
extensions.registerInstruction ("disablelevitation", "", opcodeDisableLevitation);
extensions.registerInstruction ("enablelevitation", "", opcodeEnableLevitation);
}
}

@ -222,6 +222,8 @@ namespace Compiler
const int opcodeShowVars = 0x200021d;
const int opcodeShowVarsExplicit = 0x200021e;
const int opcodeToggleGodMode = 0x200021f;
const int opcodeDisableLevitation = 0x2000220;
const int opcodeEnableLevitation = 0x2000221;
}
namespace Sky

@ -274,5 +274,23 @@ short MagicEffect::effectStringToId(const std::string &effect)
return name->first;
}
MagicEffect::MagnitudeDisplayType MagicEffect::getMagnitudeDisplayType() const {
if ( mData.mFlags & NoMagnitude )
return MDT_None;
if ( mIndex == 84 )
return MDT_TimesInt;
if ( mIndex == 59 ||
( mIndex >= 64 && mIndex <= 66) )
return MDT_Feet;
if ( mIndex == 118 || mIndex == 119 )
return MDT_Level;
if ( ( mIndex >= 28 && mIndex <= 36 )
|| ( mIndex >= 90 && mIndex <= 99 )
|| mIndex == 40 || mIndex == 47
|| mIndex == 57 || mIndex == 68 )
return MDT_Percentage;
return MDT_Points;
}
}

@ -32,6 +32,15 @@ struct MagicEffect
Negative = 0x0800 // A harmful effect. Will determine whether
// eg. NPCs regard this spell as an attack. (same as 0x10?)
};
enum MagnitudeDisplayType
{
MDT_None,
MDT_Feet,
MDT_Level,
MDT_Percentage,
MDT_Points,
MDT_TimesInt
};
struct MEDTstruct
{
@ -47,6 +56,7 @@ struct MagicEffect
static const std::string &effectIdToString(short effectID);
static short effectStringToId(const std::string &effect);
MagnitudeDisplayType getMagnitudeDisplayType() const;
MEDTstruct mData;

@ -12,6 +12,7 @@ Marc Zinnschlag (Zini) - Lead Programmer/Project Manager
Adam Hogan (aurix)
Aleksandar Jovanov
Alex Haddad (rainChu)
Alex McKibben (WeirdSexy)
Alexander Nadeau (wareya)
Alexander Olofsson (Ace)

@ -30,9 +30,6 @@ namespace SFO
InputWrapper::~InputWrapper()
{
if(mSDLWindow != NULL)
SDL_DestroyWindow(mSDLWindow);
mSDLWindow = NULL;
}
void InputWrapper::capture(bool windowEventsOnly)

@ -9,6 +9,7 @@
<!-- Log window -->
<Widget type="EditBox" skin="MW_ConsoleLog" position="5 5 380 328" align="Stretch" name="list_History">
<Property key="MultiLine" value="1"/>
<Property key="ReadOnly" value="true"/>
</Widget>
<!-- Command line -->

@ -1 +0,0 @@
branch for issue912
Loading…
Cancel
Save