Merge branch 'master' of git://github.com/OpenMW/openmw into appveyor

coverity_scan
Alexander "Ace" Olofsson 9 years ago
commit b3e985fca2

@ -2,6 +2,8 @@ os:
- linux
# - osx
language: cpp
sudo: required
dist: trusty
branches:
only:
- master
@ -18,8 +20,8 @@ addons:
name: "OpenMW/openmw"
description: "<Your project description here>"
notification_email: scrawl@baseoftrash.de
build_command_prepend: "cmake . -DBUILD_UNITTESTS=FALSE -DBUILD_OPENCS=FALSE"
build_command: "make"
build_command_prepend: "cmake . -DBUILD_UNITTESTS=FALSE"
build_command: "make -j2"
branch_pattern: coverity_scan
matrix:
include:
@ -38,7 +40,7 @@ before_script:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi
script:
- cd ./build
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j2; fi
- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j3; fi
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi

@ -113,6 +113,7 @@ Programmers
Stefan Galowicz (bogglez)
Stanislav Bobrov (Jiub)
Sylvain Thesnieres (Garvek)
t6
terrorfisch
Thomas Luppi (Digmaster)
Tom Mason (wheybags)

@ -1,22 +1,17 @@
#!/bin/sh
if [ "${ANALYZE}" ]; then
if [ $(lsb_release -sc) = "precise" ]; then
echo "yes" | sudo apt-add-repository ppa:ubuntu-toolchain-r/test
fi
echo "yes" | sudo add-apt-repository "deb http://llvm.org/apt/`lsb_release -sc`/ llvm-toolchain-`lsb_release -sc`-3.6 main"
wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add -
fi
echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
echo "yes" | sudo apt-add-repository ppa:openmw/openmw
echo "yes" | sudo apt-add-repository ppa:boost-latest/ppa
sudo apt-get update -qq
sudo apt-get install -qq libgtest-dev google-mock
sudo apt-get install -qq libboost-filesystem1.55-dev libboost-program-options1.55-dev libboost-system1.55-dev libboost-thread1.55-dev
sudo apt-get install -qq ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev
sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
sudo apt-get install -qq libbullet-dev libopenscenegraph-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
sudo apt-get install -qq cmake-data #workaround for broken osgqt cmake script in ubuntu 12.04
if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi
sudo mkdir /usr/src/gtest/build
cd /usr/src/gtest/build

@ -1,5 +1,6 @@
#!/bin/sh
free -m
mkdir build
cd build
export CODE_COVERAGE=1

@ -7,7 +7,7 @@ OpenMW is a recreation of the engine for the popular role-playing game Morrowind
OpenMW also comes with OpenMW-CS, a replacement for Morrowind's TES Construction Set.
* Version: 0.37.0
* Version: 0.38.0
* License: GPL (see docs/license/GPL3.txt for more information)
* Website: http://www.openmw.org
* IRC: #openmw on irc.freenode.net

@ -121,7 +121,7 @@ public:
{
mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel;
mContext->mPlayerBase = npc;
std::map<const int, float> empty;
std::map<int, float> empty;
// FIXME: player start spells and birthsign spells aren't listed here,
// need to fix openmw to account for this
for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin(); it != npc.mSpells.mList.end(); ++it)

@ -1,6 +1,7 @@
#include "convertinventory.hpp"
#include <components/misc/stringops.hpp>
#include <cstdlib>
namespace ESSImport
{

@ -85,7 +85,7 @@ opencs_units (view/widget
opencs_units (view/render
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
previewwidget editmode instancemode
previewwidget editmode instancemode instanceselectionmode
)
opencs_units_noqt (view/render

@ -1,6 +1,6 @@
#include "messages.hpp"
CSMDoc::Message::Message() {}
CSMDoc::Message::Message() : mSeverity(Severity_Default){}
CSMDoc::Message::Message (const CSMWorld::UniversalId& id, const std::string& message,
const std::string& hint, Severity severity)

@ -39,9 +39,6 @@ namespace CSMDoc
{
public:
// \deprecated Use CSMDoc::Message directly instead.
typedef CSMDoc::Message Message;
typedef std::vector<Message> Collection;
typedef Collection::const_iterator Iterator;

@ -2,7 +2,9 @@
#include "operation.hpp"
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
CSMDoc::OperationHolder::OperationHolder (Operation *operation)
: mOperation(NULL)
, mRunning (false)
{
if (operation)
setOperation (operation);

@ -133,6 +133,8 @@ void CSMPrefs::State::declare()
declareBool ("show-linenum", "Show Line Numbers", true).
setTooltip ("Show line numbers to the left of the script editor window."
"The current row and column numbers of the text cursor are shown at the bottom.");
declareBool ("wrap-lines", "Wrap Lines", false).
setTooltip ("Wrap lines longer than width of script editor.");
declareBool ("mono-font", "Use monospace font", true);
EnumValue warningsNormal ("Normal", "Report warnings as warning");
declareEnum ("warnings", "Warning Mode", warningsNormal).

@ -182,7 +182,7 @@ int CSMTools::ReportModel::countErrors() const
{
int count = 0;
for (std::vector<CSMDoc::Messages::Message>::const_iterator iter (mRows.begin());
for (std::vector<CSMDoc::Message>::const_iterator iter (mRows.begin());
iter!=mRows.end(); ++iter)
if (iter->mSeverity==CSMDoc::Message::Severity_Error ||
iter->mSeverity==CSMDoc::Message::Severity_SeriousError)

@ -16,7 +16,7 @@ namespace CSMTools
{
Q_OBJECT
std::vector<CSMDoc::Messages::Message> mRows;
std::vector<CSMDoc::Message> mRows;
// Fixed columns
enum Columns

@ -14,7 +14,7 @@
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
const QVariant& new_, QUndoCommand* parent)
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false)
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false), mOldRecordState(CSMWorld::RecordBase::State_BaseOnly)
{
if (QAbstractProxyModel *proxy = dynamic_cast<QAbstractProxyModel *> (&model))
{

@ -22,11 +22,18 @@ bool CSVRender::Cell::removeObject (const std::string& id)
if (iter==mObjects.end())
return false;
delete iter->second;
mObjects.erase (iter);
removeObject (iter);
return true;
}
std::map<std::string, CSVRender::Object *>::iterator CSVRender::Cell::removeObject (
std::map<std::string, Object *>::iterator iter)
{
delete iter->second;
mObjects.erase (iter++);
return iter;
}
bool CSVRender::Cell::addObjects (int start, int end)
{
bool modified = false;
@ -161,8 +168,8 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
// perform update and remove where needed
bool modified = false;
for (std::map<std::string, Object *>::iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
std::map<std::string, Object *>::iterator iter = mObjects.begin();
while (iter!=mObjects.end())
{
if (iter->second->referenceDataChanged (topLeft, bottomRight))
modified = true;
@ -171,24 +178,31 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
if (iter2!=ids.end())
{
if (iter2->second)
bool deleted = iter2->second;
ids.erase (iter2);
if (deleted)
{
removeObject (iter->first);
iter = removeObject (iter);
modified = true;
continue;
}
ids.erase (iter2);
}
++iter;
}
// add new objects
for (std::map<std::string, bool>::iterator iter (ids.begin()); iter!=ids.end(); ++iter)
{
if (!iter->second)
{
mObjects.insert (std::make_pair (
iter->first, new Object (mData, mCellNode, iter->first, false)));
modified = true;
}
}
return modified;
}
@ -249,6 +263,28 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode)
}
}
void CSVRender::Cell::selectAllWithSameParentId (int elementMask)
{
std::set<std::string> ids;
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
{
if (iter->second->getSelected())
ids.insert (iter->second->getReferenceableId());
}
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
{
if (!iter->second->getSelected() &&
ids.find (iter->second->getReferenceableId())!=ids.end())
{
iter->second->setSelected (true);
}
}
}
void CSVRender::Cell::setCellArrows (int mask)
{
for (int i=0; i<4; ++i)
@ -276,3 +312,16 @@ bool CSVRender::Cell::isDeleted() const
{
return mDeleted;
}
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getSelection (unsigned int elementMask) const
{
std::vector<osg::ref_ptr<TagBase> > result;
if (elementMask & Mask_Reference)
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
if (iter->second->getSelected())
result.push_back (iter->second->getTag());
return result;
}

@ -31,6 +31,8 @@ namespace CSMWorld
namespace CSVRender
{
class TagBase;
class Cell
{
CSMWorld::Data& mData;
@ -47,6 +49,10 @@ namespace CSVRender
/// \return Was the object deleted?
bool removeObject (const std::string& id);
// Remove object and return iterator to next object.
std::map<std::string, Object *>::iterator removeObject (
std::map<std::string, Object *>::iterator iter);
/// Add objects from reference table that are within this cell.
///
/// \return Have any objects been added?
@ -93,12 +99,18 @@ namespace CSVRender
void setSelection (int elementMask, Selection mode);
// Select everything that references the same ID as at least one of the elements
// already selected
void selectAllWithSameParentId (int elementMask);
void setCellArrows (int mask);
/// Returns 0, 0 in case of an unpaged cell.
CSMWorld::CellCoordinates getCoordinates() const;
bool isDeleted() const;
std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask) const;
};
}

@ -9,16 +9,73 @@
#include "../../model/world/idtree.hpp"
#include "../../model/world/commands.hpp"
#include "../widget/scenetoolbar.hpp"
#include "../widget/scenetoolmode.hpp"
#include "mask.hpp"
#include "object.hpp"
#include "worldspacewidget.hpp"
#include "pagedworldspacewidget.hpp"
#include "instanceselectionmode.hpp"
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
: EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing",
parent)
parent), mSubMode (0), mSelectionMode (0)
{
}
void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
{
if (!mSubMode)
{
mSubMode = new CSVWidget::SceneToolMode (toolbar, "Edit Sub-Mode");
mSubMode->addButton (":placeholder", "move",
"Move selected instances"
"<ul><li>Use primary edit to move instances around freely</li>"
"<li>Use secondary edit to move instances around within the grid</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
mSubMode->addButton (":placeholder", "rotate",
"Rotate selected instances"
"<ul><li>Use primary edit to rotate instances freely</li>"
"<li>Use secondary edit to rotate instances within the grid</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
mSubMode->addButton (":placeholder", "scale",
"Scale selected instances"
"<ul><li>Use primary edit to scale instances freely</li>"
"<li>Use secondary edit to scale instances along the grid</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
}
if (!mSelectionMode)
mSelectionMode = new InstanceSelectionMode (toolbar, getWorldspaceWidget());
EditMode::activate (toolbar);
toolbar->addTool (mSubMode);
toolbar->addTool (mSelectionMode);
}
void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar)
{
if (mSelectionMode)
{
toolbar->removeTool (mSelectionMode);
delete mSelectionMode;
mSelectionMode = 0;
}
if (mSubMode)
{
toolbar->removeTool (mSubMode);
delete mSubMode;
mSubMode = 0;
}
EditMode::deactivate (toolbar);
}
void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag)

@ -3,16 +3,29 @@
#include "editmode.hpp"
namespace CSVWidget
{
class SceneToolMode;
}
namespace CSVRender
{
class InstanceSelectionMode;
class InstanceMode : public EditMode
{
Q_OBJECT
CSVWidget::SceneToolMode *mSubMode;
InstanceSelectionMode *mSelectionMode;
public:
InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0);
virtual void activate (CSVWidget::SceneToolbar *toolbar);
virtual void deactivate (CSVWidget::SceneToolbar *toolbar);
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag);
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag);

@ -0,0 +1,93 @@
#include "instanceselectionmode.hpp"
#include <QMenu>
#include <QAction>
#include "../../model/world/idtable.hpp"
#include "../../model/world/commands.hpp"
#include "worldspacewidget.hpp"
#include "object.hpp"
bool CSVRender::InstanceSelectionMode::createContextMenu (QMenu *menu)
{
if (menu)
{
menu->addAction (mSelectAll);
menu->addAction (mDeselectAll);
menu->addAction (mSelectSame);
menu->addAction (mDeleteSelection);
}
return true;
}
CSVRender::InstanceSelectionMode::InstanceSelectionMode (CSVWidget::SceneToolbar *parent,
WorldspaceWidget& worldspaceWidget)
: CSVWidget::SceneToolMode (parent, "Selection Mode"), mWorldspaceWidget (worldspaceWidget)
{
addButton (":placeholder", "cube-centre",
"Centred cube"
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection cube outwards</li>"
"<li>The selection cube is aligned to the word space axis</li>"
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
addButton (":placeholder", "cube-corner",
"Cube corner to corner"
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from one corner of the selection cube to the opposite corner</li>"
"<li>The selection cube is aligned to the word space axis</li>"
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
addButton (":placeholder", "sphere",
"Centred sphere"
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection sphere outwards</li>"
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
"</ul>"
"<font color=Red>Not implemented yet</font color>");
mSelectAll = new QAction ("Select all instances", this);
mDeselectAll = new QAction ("Clear selection", this);
mDeleteSelection = new QAction ("Delete selected instances", this);
mSelectSame = new QAction ("Extend selection to instances with same object ID", this);
connect (mSelectAll, SIGNAL (triggered ()), this, SLOT (selectAll()));
connect (mDeselectAll, SIGNAL (triggered ()), this, SLOT (clearSelection()));
connect (mDeleteSelection, SIGNAL (triggered ()), this, SLOT (deleteSelection()));
connect (mSelectSame, SIGNAL (triggered ()), this, SLOT (selectSame()));
}
void CSVRender::InstanceSelectionMode::selectAll()
{
mWorldspaceWidget.selectAll (Mask_Reference);
}
void CSVRender::InstanceSelectionMode::clearSelection()
{
mWorldspaceWidget.clearSelection (Mask_Reference);
}
void CSVRender::InstanceSelectionMode::deleteSelection()
{
std::vector<osg::ref_ptr<TagBase> > selection =
mWorldspaceWidget.getSelection (Mask_Reference);
CSMWorld::IdTable& referencesTable =
dynamic_cast<CSMWorld::IdTable&> (*mWorldspaceWidget.getDocument().getData().
getTableModel (CSMWorld::UniversalId::Type_References));
for (std::vector<osg::ref_ptr<TagBase> >::iterator iter (selection.begin());
iter!=selection.end(); ++iter)
{
CSMWorld::DeleteCommand *command = new CSMWorld::DeleteCommand (referencesTable,
static_cast<ObjectTag *> (iter->get())->mObject->getReferenceId());
mWorldspaceWidget.getDocument().getUndoStack().push (command);
}
}
void CSVRender::InstanceSelectionMode::selectSame()
{
mWorldspaceWidget.selectAllWithSameParentId (Mask_Reference);
}

@ -0,0 +1,46 @@
#ifndef CSV_RENDER_INSTANCE_SELECTION_MODE_H
#define CSV_RENDER_INSTANCE_SELECTION_MODE_H
#include "../widget/scenetoolmode.hpp"
class QAction;
namespace CSVRender
{
class WorldspaceWidget;
class InstanceSelectionMode : public CSVWidget::SceneToolMode
{
Q_OBJECT
WorldspaceWidget& mWorldspaceWidget;
QAction *mSelectAll;
QAction *mDeselectAll;
QAction *mDeleteSelection;
QAction *mSelectSame;
/// Add context menu items to \a menu.
///
/// \attention menu can be a 0-pointer
///
/// \return Have there been any menu items to be added (if menu is 0 and there
/// items to be added, the function must return true anyway.
virtual bool createContextMenu (QMenu *menu);
public:
InstanceSelectionMode (CSVWidget::SceneToolbar *parent, WorldspaceWidget& worldspaceWidget);
private slots:
void selectAll();
void clearSelection();
void deleteSelection();
void selectSame();
};
}
#endif

@ -187,6 +187,7 @@ CSVRender::Object::~Object()
clear();
mParentNode->removeChild(mBaseNode);
mParentNode->removeChild(mOutline);
}
void CSVRender::Object::setSelected(bool selected)
@ -284,3 +285,8 @@ std::string CSVRender::Object::getReferenceableId() const
{
return mReferenceableId;
}
osg::ref_ptr<CSVRender::TagBase> CSVRender::Object::getTag() const
{
return static_cast<CSVRender::TagBase *> (mBaseNode->getUserData());
}

@ -114,6 +114,8 @@ namespace CSVRender
std::string getReferenceId() const;
std::string getReferenceableId() const;
osg::ref_ptr<TagBase> getTag() const;
};
}

@ -509,6 +509,24 @@ void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask)
flagAsModified();
}
void CSVRender::PagedWorldspaceWidget::selectAll (int elementMask)
{
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter = mCells.begin();
iter!=mCells.end(); ++iter)
iter->second->setSelection (elementMask, Cell::Selection_All);
flagAsModified();
}
void CSVRender::PagedWorldspaceWidget::selectAllWithSameParentId (int elementMask)
{
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter = mCells.begin();
iter!=mCells.end(); ++iter)
iter->second->selectAllWithSameParentId (elementMask);
flagAsModified();
}
std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const
{
const int cellSize = 8192;
@ -520,6 +538,23 @@ std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point
return cellCoordinates.getId (mWorldspace);
}
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::PagedWorldspaceWidget::getSelection (
unsigned int elementMask) const
{
std::vector<osg::ref_ptr<CSVRender::TagBase> > result;
for (std::map<CSMWorld::CellCoordinates, Cell *>::const_iterator iter = mCells.begin();
iter!=mCells.end(); ++iter)
{
std::vector<osg::ref_ptr<CSVRender::TagBase> > cellResult =
iter->second->getSelection (elementMask);
result.insert (result.end(), cellResult.begin(), cellResult.end());
}
return result;
}
CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector (
CSVWidget::SceneToolbar *parent)
{

@ -98,8 +98,20 @@ namespace CSVRender
/// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask);
/// \param elementMask Elements to be affected by the select operation
virtual void selectAll (int elementMask);
// Select everything that references the same ID as at least one of the elements
// already selected
//
/// \param elementMask Elements to be affected by the select operation
virtual void selectAllWithSameParentId (int elementMask);
virtual std::string getCellId (const osg::Vec3f& point) const;
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
const;
protected:
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);

@ -108,11 +108,29 @@ void CSVRender::UnpagedWorldspaceWidget::clearSelection (int elementMask)
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::selectAll (int elementMask)
{
mCell->setSelection (elementMask, Cell::Selection_All);
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::selectAllWithSameParentId (int elementMask)
{
mCell->selectAllWithSameParentId (elementMask);
flagAsModified();
}
std::string CSVRender::UnpagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const
{
return mCellId;
}
std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::UnpagedWorldspaceWidget::getSelection (
unsigned int elementMask) const
{
return mCell->getSelection (elementMask);
}
void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight)
{

@ -46,8 +46,20 @@ namespace CSVRender
/// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask);
/// \param elementMask Elements to be affected by the select operation
virtual void selectAll (int elementMask);
// Select everything that references the same ID as at least one of the elements
// already selected
//
/// \param elementMask Elements to be affected by the select operation
virtual void selectAllWithSameParentId (int elementMask);
virtual std::string getCellId (const osg::Vec3f& point) const;
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
const;
private:
virtual void referenceableDataChanged (const QModelIndex& topLeft,

@ -33,8 +33,9 @@
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document),
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false),
mToolTipPos (-1, -1)
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mDragX(0), mDragY(0), mDragFactor(0),
mDragWheelFactor(0), mDragShiftFactor(0),
mToolTipPos (-1, -1), mShowToolTips(false), mToolTipDelay(0)
{
setAcceptDrops(true);

@ -127,6 +127,15 @@ namespace CSVRender
/// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask) = 0;
/// \param elementMask Elements to be affected by the select operation
virtual void selectAll (int elementMask) = 0;
// Select everything that references the same ID as at least one of the elements
// already selected
//
/// \param elementMask Elements to be affected by the select operation
virtual void selectAllWithSameParentId (int elementMask) = 0;
/// Return the next intersection point with scene elements matched by
/// \a interactionMask based on \a localPos and the camera vector.
/// If there is no such point, instead a point "in front" of \a localPos will be
@ -140,6 +149,9 @@ namespace CSVRender
virtual std::string getCellId (const osg::Vec3f& point) const = 0;
virtual std::vector<osg::ref_ptr<TagBase> > getSelection (unsigned int elementMask)
const = 0;
protected:
/// Visual elements in a scene

@ -7,3 +7,8 @@ CSVWidget::ModeButton::ModeButton (const QIcon& icon, const QString& tooltip, QW
void CSVWidget::ModeButton::activate (SceneToolbar *toolbar) {}
void CSVWidget::ModeButton::deactivate (SceneToolbar *toolbar) {}
bool CSVWidget::ModeButton::createContextMenu (QMenu *menu)
{
return false;
}

@ -3,6 +3,8 @@
#include "pushbutton.hpp"
class QMenu;
namespace CSVWidget
{
class SceneToolbar;
@ -22,6 +24,14 @@ namespace CSVWidget
/// Default-Implementation: do nothing
virtual void deactivate (SceneToolbar *toolbar);
/// Add context menu items to \a menu. Default-implementation: return false
///
/// \attention menu can be a 0-pointer
///
/// \return Have there been any menu items to be added (if menu is 0 and there
/// items to be added, the function must return true anyway.
virtual bool createContextMenu (QMenu *menu);
};
}

@ -3,10 +3,27 @@
#include <QHBoxLayout>
#include <QFrame>
#include <QSignalMapper>
#include <QMenu>
#include <QContextMenuEvent>
#include "scenetoolbar.hpp"
#include "modebutton.hpp"
void CSVWidget::SceneToolMode::contextMenuEvent (QContextMenuEvent *event)
{
QMenu menu (this);
if (createContextMenu (&menu))
menu.exec (event->globalPos());
}
bool CSVWidget::SceneToolMode::createContextMenu (QMenu *menu)
{
if (mCurrent)
return mCurrent->createContextMenu (menu);
return false;
}
void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode)
{
QString toolTip = mToolTip;
@ -15,6 +32,9 @@ void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode)
toolTip += "<p>(left click to change mode)";
if (createContextMenu (0))
toolTip += "<br>(right click to access context menu)";
setToolTip (toolTip);
}

@ -6,6 +6,7 @@
#include <map>
class QHBoxLayout;
class QMenu;
namespace CSVWidget
{
@ -29,6 +30,17 @@ namespace CSVWidget
void adjustToolTip (const ModeButton *activeMode);
virtual void contextMenuEvent (QContextMenuEvent *event);
/// Add context menu items to \a menu. Default-implementation: Pass on request to
/// current mode button or return false, if there is no current mode button.
///
/// \attention menu can be a 0-pointer
///
/// \return Have there been any menu items to be added (if menu is 0 and there
/// items to be added, the function must return true anyway.
virtual bool createContextMenu (QMenu *menu);
public:
SceneToolMode (SceneToolbar *parent, const QString& toolTip);

@ -122,7 +122,7 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp
CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar);
toolbar->addTool (runTool);
toolbar->addTool (widget->makeEditModeSelector (toolbar));
toolbar->addTool (widget->makeEditModeSelector (toolbar), runTool);
return toolbar;
}

@ -38,9 +38,11 @@ bool CSVWorld::ScriptEdit::event (QEvent *event)
return QPlainTextEdit::event (event);
}
CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode,
QWidget* parent)
: QPlainTextEdit (parent),
CSVWorld::ScriptEdit::ScriptEdit(
const CSMDoc::Document& document,
ScriptHighlighter::Mode mode,
QWidget* parent
) : QPlainTextEdit(parent),
mChangeLocked(0),
mShowLineNum(false),
mLineNumberArea(0),
@ -48,10 +50,8 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli
mMonoFont(QFont("Monospace")),
mDocument(document),
mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive)
{
// setAcceptRichText (false);
setLineWrapMode (QPlainTextEdit::NoWrap);
wrapLines(false);
setTabStopWidth (4);
setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead
@ -194,15 +194,38 @@ bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
return !(string.contains(mWhiteListQoutes));
}
void CSVWorld::ScriptEdit::wrapLines(bool wrap)
{
if (wrap)
{
setLineWrapMode(QPlainTextEdit::WidgetWidth);
}
else
{
setLineWrapMode(QPlainTextEdit::NoWrap);
}
}
void CSVWorld::ScriptEdit::settingChanged(const CSMPrefs::Setting *setting)
{
// Determine which setting was changed.
if (mHighlighter->settingChanged(setting))
{
updateHighlighting();
}
else if (*setting == "Scripts/mono-font")
{
setFont(setting->isTrue() ? mMonoFont : mDefaultFont);
}
else if (*setting == "Scripts/show-linenum")
{
showLineNum(setting->isTrue());
}
else if (*setting == "Scripts/wrap-lines")
{
wrapLines(setting->isTrue());
}
}
void CSVWorld::ScriptEdit::idListChanged()
{

@ -22,6 +22,7 @@ namespace CSVWorld
{
class LineNumberArea;
/// \brief Editor for scripts.
class ScriptEdit : public QPlainTextEdit
{
Q_OBJECT
@ -77,6 +78,7 @@ namespace CSVWorld
virtual void resizeEvent(QResizeEvent *e);
private:
QVector<CSMWorld::UniversalId::Type> mAllowedTypes;
const CSMDoc::Document& mDocument;
const QRegExp mWhiteListQoutes;
@ -89,8 +91,14 @@ namespace CSVWorld
bool stringNeedsQuote(const std::string& id) const;
/// \brief Turn line wrapping in script editor on or off.
/// \param wrap Whether or not to wrap lines.
void wrapLines(bool wrap);
private slots:
/// \brief Update editor when related setting is changed.
/// \param setting Setting that was changed.
void settingChanged(const CSMPrefs::Setting *setting);
void idListChanged();

@ -1,20 +1,118 @@
#include "startscriptcreator.hpp"
CSVWorld::StartScriptCreator::StartScriptCreator(CSMWorld::Data &data, QUndoStack &undoStack, const CSMWorld::UniversalId &id, bool relaxedIdRules):
GenericCreator (data, undoStack, id, true)
{}
#include <QLabel>
#include "../../model/doc/document.hpp"
#include "../../model/world/columns.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/data.hpp"
#include "../../model/world/idcompletionmanager.hpp"
#include "../../model/world/idtable.hpp"
#include "../widget/droplineedit.hpp"
std::string CSVWorld::StartScriptCreator::getId() const
{
return mScript->text().toUtf8().constData();
}
CSMWorld::IdTable& CSVWorld::StartScriptCreator::getStartScriptsTable() const
{
return dynamic_cast<CSMWorld::IdTable&> (
*getData().getTableModel(getCollectionId())
);
}
void CSVWorld::StartScriptCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const
{
CSMWorld::IdTable& table = getStartScriptsTable();
int column = table.findColumnIndex(CSMWorld::Columns::ColumnId_Id);
// Set script ID to be added to start scripts table.
command.addValue(column, mScript->text());
}
CSVWorld::StartScriptCreator::StartScriptCreator(
CSMWorld::Data &data,
QUndoStack &undoStack,
const CSMWorld::UniversalId &id,
CSMWorld::IdCompletionManager& completionManager
) : GenericCreator(data, undoStack, id, true)
{
setManualEditing(false);
// Add script ID input label.
QLabel *label = new QLabel("Script ID", this);
insertBeforeButtons(label, false);
// Add script ID input with auto-completion.
CSMWorld::ColumnBase::Display displayType = CSMWorld::ColumnBase::Display_Script;
mScript = new CSVWidget::DropLineEdit(displayType, this);
mScript->setCompleter(completionManager.getCompleter(displayType).get());
insertBeforeButtons(mScript, true);
connect(mScript, SIGNAL (textChanged(const QString&)), this, SLOT (scriptChanged()));
}
void CSVWorld::StartScriptCreator::cloneMode(
const std::string& originId,
const CSMWorld::UniversalId::Type type)
{
CSVWorld::GenericCreator::cloneMode(originId, type);
// Look up cloned record in start scripts table and set script ID text.
CSMWorld::IdTable& table = getStartScriptsTable();
int column = table.findColumnIndex(CSMWorld::Columns::ColumnId_Id);
mScript->setText(table.data(table.getModelIndex(originId, column)).toString());
}
std::string CSVWorld::StartScriptCreator::getErrors() const
{
std::string errors;
std::string scriptId = getId();
errors = getIdValidatorResult();
if (errors.length() > 0)
return errors;
else if (getData().getScripts().searchId(getId()) == -1)
// Check user input for any errors.
std::string errors;
if (scriptId.empty())
{
errors = "No Script ID entered";
}
else if (getData().getScripts().searchId(scriptId) == -1)
{
errors = "Script ID not found";
else if (getData().getStartScripts().searchId(getId()) > -1 )
}
else if (getData().getStartScripts().searchId(scriptId) > -1)
{
errors = "Script with this ID already registered as Start Script";
}
return errors;
}
void CSVWorld::StartScriptCreator::focus()
{
mScript->setFocus();
}
void CSVWorld::StartScriptCreator::reset()
{
CSVWorld::GenericCreator::reset();
mScript->setText("");
}
void CSVWorld::StartScriptCreator::scriptChanged()
{
update();
}
CSVWorld::Creator *CSVWorld::StartScriptCreatorFactory::makeCreator(
CSMDoc::Document& document,
const CSMWorld::UniversalId& id) const
{
return new StartScriptCreator(
document.getData(),
document.getUndoStack(),
id,
document.getIdCompletionManager()
);
}

@ -3,23 +3,77 @@
#include "genericcreator.hpp"
namespace CSVWorld {
namespace CSMWorld
{
class IdCompletionManager;
class IdTable;
}
namespace CSVWidget
{
class DropLineEdit;
}
namespace CSVWorld
{
/// \brief Record creator for start scripts.
class StartScriptCreator : public GenericCreator
{
Q_OBJECT
CSVWidget::DropLineEdit *mScript;
private:
/// \return script ID entered by user.
virtual std::string getId() const;
/// \return reference to table containing start scripts.
CSMWorld::IdTable& getStartScriptsTable() const;
/// \brief Add user input to command for creating start script.
/// \param command Creation command to configure.
virtual void configureCreateCommand(CSMWorld::CreateCommand& command) const;
public:
StartScriptCreator(CSMWorld::Data& data, QUndoStack& undoStack,
const CSMWorld::UniversalId& id, bool relaxedIdRules = false);
StartScriptCreator(
CSMWorld::Data& data,
QUndoStack& undoStack,
const CSMWorld::UniversalId& id,
CSMWorld::IdCompletionManager& completionManager);
/// \brief Set script ID input widget to ID of record to be cloned.
/// \param originId Script ID to be cloned.
/// \param type Type of record to be cloned.
virtual void cloneMode(
const std::string& originId,
const CSMWorld::UniversalId::Type type);
/// \return Error description for current user input.
virtual std::string getErrors() const;
///< Return formatted error descriptions for the current state of the creator. if an empty
/// string is returned, there is no error.
};
}
/// \brief Set focus to script ID input widget.
virtual void focus();
/// \brief Clear script ID input widget.
virtual void reset();
private slots:
/// \brief Check user input for any errors.
void scriptChanged();
};
/// \brief Creator factory for start script record creator.
class StartScriptCreatorFactory : public CreatorFactoryBase
{
public:
virtual Creator *makeCreator(
CSMDoc::Document& document,
const CSMWorld::UniversalId& id) const;
};
}
#endif // STARTSCRIPTCREATOR_HPP

@ -52,7 +52,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<GenericCreator> >);
manager.add (CSMWorld::UniversalId::Type_StartScripts,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<StartScriptCreator> >);
new CSVDoc::SubViewFactoryWithCreator<TableSubView, StartScriptCreatorFactory>);
manager.add (CSMWorld::UniversalId::Type_Cells,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<CellCreator> >);
@ -136,8 +136,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
CreatorFactory<GenericCreator> > (false));
manager.add (CSMWorld::UniversalId::Type_StartScript,
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView,
CreatorFactory<StartScriptCreator> > (false));
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, StartScriptCreatorFactory>(false));
manager.add (CSMWorld::UniversalId::Type_Skill,
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, NullCreatorFactory > (false));

@ -2,7 +2,6 @@
#include <QHeaderView>
#include <QAction>
#include <QApplication>
#include <QMenu>
#include <QContextMenuEvent>
#include <QString>
@ -12,7 +11,6 @@
#include "../../model/doc/document.hpp"
#include "../../model/world/data.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/infotableproxymodel.hpp"
#include "../../model/world/idtableproxymodel.hpp"
@ -20,13 +18,10 @@
#include "../../model/world/idtable.hpp"
#include "../../model/world/record.hpp"
#include "../../model/world/columns.hpp"
#include "../../model/world/tablemimedata.hpp"
#include "../../model/world/tablemimedata.hpp"
#include "../../model/world/commanddispatcher.hpp"
#include "../../model/prefs/state.hpp"
#include "recordstatusdelegate.hpp"
#include "tableeditidaction.hpp"
#include "util.hpp"
@ -231,7 +226,7 @@ void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event)
CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
bool createAndDelete, bool sorting, CSMDoc::Document& document)
: DragRecordTable(document), mCreateAction (0),
mCloneAction(0),mRecordStatusDisplay (0)
mCloneAction(0), mRecordStatusDisplay (0), mJumpToAddedRecord(false), mUnselectAfterJump(false)
{
mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id));
@ -339,8 +334,6 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
connect (mProxyModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (tableSizeUpdate()));
//connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
// this, SLOT (rowsInsertedEvent(const QModelIndex&, int, int)));
connect (mProxyModel, SIGNAL (rowAdded (const std::string &)),
this, SLOT (rowAdded (const std::string &)));

@ -11,7 +11,6 @@
#include "../../model/world/universalid.hpp"
#include "dragrecordtable.hpp"
class QUndoStack;
class QAction;
namespace CSMDoc
@ -21,7 +20,6 @@ namespace CSMDoc
namespace CSMWorld
{
class Data;
class IdTableProxyModel;
class IdTableBase;
class CommandDispatcher;

@ -76,7 +76,7 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto
CSMDoc::Document& document,
const CSMWorld::UniversalId& id,
QWidget *parent)
: QWidget (parent), mShowStatusBar (false), mEditMode(EditMode_None), mHasPosition(false)
: QWidget (parent), mShowStatusBar (false), mEditMode(EditMode_None), mHasPosition(false), mRow(0), mColumn(0)
{
for (int i=0; i<4; ++i)
mStatusCount[i] = 0;

@ -24,7 +24,7 @@
#ifndef PR_SET_PTRACER
#define PR_SET_PTRACER 0x59616d61
#endif
#elif defined (__APPLE__)
#elif defined (__APPLE__) || defined (__FreeBSD__)
#include <signal.h>
#endif

@ -1556,7 +1556,7 @@ namespace MWMechanics
(target == getPlayer() &&
MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf")))
{
const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().search("iWerewolfFightMod");
const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("iWerewolfFightMod");
fight += iWerewolfFightMod->getInt();
}
}

@ -44,7 +44,7 @@ namespace MWMechanics
{
if (mSpells.find (spell)==mSpells.end())
{
std::map<const int, float> random;
std::map<int, float> random;
// Determine the random magnitudes (unless this is a castable spell, in which case
// they will be determined when the spell is cast)

@ -33,7 +33,7 @@ namespace MWMechanics
typedef const ESM::Spell* SpellKey;
typedef std::map<SpellKey, std::map<const int, float> > TContainer; // ID, <effect index, normalised random magnitude>
typedef std::map<SpellKey, std::map<int, float> > TContainer; // ID, <effect index, normalised random magnitude>
typedef TContainer::const_iterator TIterator;
struct CorprusStats

@ -42,6 +42,7 @@
#include "camera.hpp"
#include "water.hpp"
#include "terrainstorage.hpp"
#include "util.hpp"
namespace MWRender
{
@ -504,15 +505,6 @@ namespace MWRender
mutable bool mDone;
};
class NoTraverseCallback : public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
}
};
void RenderingManager::screenshot(osg::Image *image, int w, int h)
{
osg::ref_ptr<osg::Camera> rttCamera (new osg::Camera);

@ -17,6 +17,7 @@
#include <osg/MatrixTransform>
#include <osg/BlendFunc>
#include <osg/AlphaFunc>
#include <osg/observer_ptr>
#include <osgParticle/ParticleSystem>
#include <osgParticle/ParticleSystemUpdater>
@ -373,10 +374,15 @@ public:
else alpha = 1.f;
}
else if (mMeshType == 2)
{
if (geom->getColorArray())
{
osg::Vec4Array* origColors = static_cast<osg::Vec4Array*>(geom->getColorArray());
alpha = ((*origColors)[i].x() == 1.f) ? 1.f : 0.f;
}
else
alpha = 1.f;
}
(*colors)[i] = osg::Vec4f(0.f, 0.f, 0.f, alpha);
}

@ -1,6 +1,7 @@
#ifndef OPENMW_MWRENDER_UTIL_H
#define OPENMW_MWRENDER_UTIL_H
#include <osg/NodeCallback>
#include <osg/ref_ptr>
#include <string>
@ -16,9 +17,17 @@ namespace Resource
namespace MWRender
{
void overrideTexture(const std::string& texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Node> node);
// Node callback to entirely skip the traversal.
class NoTraverseCallback : public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
// no traverse()
}
};
}
#endif

@ -41,6 +41,7 @@
#include "vismask.hpp"
#include "ripplesimulation.hpp"
#include "renderbin.hpp"
#include "util.hpp"
namespace
{
@ -210,16 +211,6 @@ private:
osg::Plane mPlane;
};
// Node callback to entirely skip the traversal.
class NoTraverseCallback : public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
// no traverse()
}
};
/// Moves water mesh away from the camera slightly if the camera gets too close on the Z axis.
/// The offset works around graphics artifacts that occured with the GL_DEPTH_CLAMP when the camera gets extremely close to the mesh (seen on NVIDIA at least).
/// Must be added as a Cull callback.

@ -447,5 +447,7 @@ op 0x20002fe: RemoveFromLevItem
op 0x20002ff: SetFactionReaction
op 0x2000300: EnableLevelupMenu
op 0x2000301: ToggleScripts
op 0x2000302: Fixme
op 0x2000303: Fixme, explicit
opcodes 0x2000302-0x3ffffff unused
opcodes 0x2000304-0x3ffffff unused

@ -734,6 +734,18 @@ namespace MWScript
}
};
template <class R>
class OpFixme : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
MWBase::Environment::get().getWorld()->fixPosition(ptr);
}
};
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5(Compiler::Transformation::opcodeSetScale,new OpSetScale<ImplicitRef>);
@ -774,6 +786,8 @@ namespace MWScript
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngle, new OpGetStartingAngle<ImplicitRef>);
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngleExplicit, new OpGetStartingAngle<ExplicitRef>);
interpreter.installSegment5(Compiler::Transformation::opcodeResetActors, new OpResetActors);
interpreter.installSegment5(Compiler::Transformation::opcodeFixme, new OpFixme<ImplicitRef>);
interpreter.installSegment5(Compiler::Transformation::opcodeFixmeExplicit, new OpFixme<ExplicitRef>);
}
}
}

@ -5,6 +5,7 @@
#include "../mwscript/locals.hpp"
#include <string>
#include <osg/Vec3f>
namespace SceneUtil

@ -108,7 +108,11 @@ namespace MWWorld
}
private:
#ifdef HAVE_UNORDERED_MAP
typedef std::unordered_map<std::string, ContentLoader*> LoadersContainer;
#else
typedef std::tr1::unordered_map<std::string, ContentLoader*> LoadersContainer;
#endif
LoadersContainer mLoaders;
};
@ -433,7 +437,7 @@ namespace MWWorld
// Werewolf (BM)
gmst["fWereWolfRunMult"] = ESM::Variant(1.f);
gmst["fWereWolfSilverWeaponDamageMult"] = ESM::Variant(1.f);
gmst["iWerewolfFightMod"] = ESM::Variant(1);
std::map<std::string, ESM::Variant> globals;
// vanilla Morrowind does not define dayspassed.
@ -1311,6 +1315,7 @@ namespace MWWorld
actor.getRefData().setPosition(pos);
osg::Vec3f traced = mPhysics->traceDown(actor, dist*1.1f);
if (traced != pos.asVec3())
moveObject(actor, actor.getCell(), traced.x(), traced.y(), traced.z());
}
@ -1744,6 +1749,8 @@ namespace MWWorld
{
cellid.mWorldspace = ref.mRef.getDestCell();
cellid.mPaged = false;
cellid.mIndex.mX = 0;
cellid.mIndex.mY = 0;
}
else
{

@ -541,6 +541,7 @@ namespace Compiler
extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit);
extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit);
extensions.registerInstruction("resetactors","",opcodeResetActors);
extensions.registerInstruction("fixme","",opcodeFixme, opcodeFixmeExplicit);
extensions.registerInstruction("ra","",opcodeResetActors);
}
}

@ -498,6 +498,8 @@ namespace Compiler
const int opcodeMoveWorld = 0x2000208;
const int opcodeMoveWorldExplicit = 0x2000209;
const int opcodeResetActors = 0x20002f4;
const int opcodeFixme = 0x2000302;
const int opcodeFixmeExplicit = 0x2000303;
}
namespace User

@ -12,7 +12,7 @@ namespace ESM
{
std::string id = esm.getHString();
std::map<const int, float> random;
std::map<int, float> random;
while (esm.isNextSub("INDX"))
{
int index;
@ -73,8 +73,8 @@ namespace ESM
{
esm.writeHNString("SPEL", it->first);
const std::map<const int, float>& random = it->second;
for (std::map<const int, float>::const_iterator rIt = random.begin(); rIt != random.end(); ++rIt)
const std::map<int, float>& random = it->second;
for (std::map<int, float>::const_iterator rIt = random.begin(); rIt != random.end(); ++rIt)
{
esm.writeHNT("INDX", rIt->first);
esm.writeHNT("RAND", rIt->second);

@ -28,7 +28,7 @@ namespace ESM
float mMagnitude;
};
typedef std::map<std::string, std::map<const int, float> > TContainer;
typedef std::map<std::string, std::map<int, float> > TContainer;
TContainer mSpells;
std::map<std::string, std::vector<PermanentSpellEffectInfo> > mPermanentSpellEffects;

@ -1,6 +1,7 @@
#include "bulletshape.hpp"
#include <stdexcept>
#include <string>
#include <BulletCollision/CollisionShapes/btBoxShape.h>
#include <BulletCollision/CollisionShapes/btTriangleMesh.h>

@ -201,10 +201,22 @@ namespace Resource
}
catch (std::exception& e)
{
std::cerr << "Failed to load '" << name << "': " << e.what() << ", using marker_error.nif instead" << std::endl;
Files::IStreamPtr file = mVFS->get("meshes/marker_error.nif");
normalized = "meshes/marker_error.nif";
static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2" };
for (unsigned int i=0; i<sizeof(sMeshTypes)/sizeof(sMeshTypes[0]); ++i)
{
normalized = "meshes/marker_error." + std::string(sMeshTypes[i]);
if (mVFS->exists(normalized))
{
std::cerr << "Failed to load '" << name << "': " << e.what() << ", using marker_error." << sMeshTypes[i] << " instead" << std::endl;
Files::IStreamPtr file = mVFS->get(normalized);
loaded = load(file, normalized, mTextureManager, mNifFileManager);
break;
}
}
if (!loaded)
throw;
}
osgDB::Registry::instance()->getOrCreateSharedStateManager()->share(loaded.get());

@ -5,6 +5,7 @@
#include <osg/Group>
#include <osg/NodeVisitor>
#include <osg/observer_ptr>
namespace SceneUtil
{

@ -14,7 +14,7 @@
[Camera]
# Near clipping plane (>0.0, e.g. 0.01 to 18.0).
near clip = 5.0
near clip = 1
# Cull objects smaller than one pixel.
small feature culling = true

Loading…
Cancel
Save