Merge remote-tracking branch 'scrawl/master'

deque
Marc Zinnschlag 11 years ago
commit e893d0d7d3

@ -362,9 +362,6 @@ endif()
if (CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
# Silence warnings in OGRE headers. Remove once OGRE got fixed!
SET(CMAKE_CXX_FLAGS "-Wno-ignored-qualifiers ${CMAKE_CXX_FLAGS}")
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)

@ -143,7 +143,7 @@ namespace MWBase
virtual bool isCellQuasiExterior() const = 0;
virtual Ogre::Vector2 getNorthVector (MWWorld::CellStore* cell) = 0;
///< get north vector (OGRE coordinates) for given interior cell
///< get north vector for given interior cell
virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector<DoorMarker>& out) = 0;
///< get a list of teleport door markers for a given cell, to be displayed on the local map

@ -276,7 +276,6 @@ namespace MWGui
{
// in choice, not allowed to escape, but give access to main menu to allow loading other saves
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
MWBase::Environment::get().getSoundManager()->pauseSounds (MWBase::SoundManager::Play_TypeSfx);
}
else
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();

@ -543,6 +543,9 @@ namespace MWGui
if (MWBase::Environment::get().getWindowManager()->getSpellWindow())
MWBase::Environment::get().getWindowManager()->getSpellWindow()->updateSpells();
MWBase::Environment::get().getMechanicsManager()->updateMagicEffects(
MWBase::Environment::get().getWorld()->getPlayerPtr());
mPreviewDirty = true;
}

@ -56,6 +56,43 @@ void ItemView::initialiseOverride()
mScrollView->setCanvasAlign(MyGUI::Align::Left | MyGUI::Align::Top);
}
void ItemView::layoutWidgets()
{
if (!mScrollView->getChildCount())
return;
int x = 0;
int y = 0;
int maxHeight = mScrollView->getSize().height - 58;
MyGUI::Widget* dragArea = mScrollView->getChildAt(0);
for (unsigned int i=0; i<dragArea->getChildCount(); ++i)
{
MyGUI::Widget* w = dragArea->getChildAt(i);
w->setPosition(x, y);
y += 42;
if (y > maxHeight)
{
x += 42;
y = 0;
}
}
x += 42;
MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height);
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mScrollView->setVisibleVScroll(false);
mScrollView->setVisibleHScroll(false);
mScrollView->setCanvasSize(size);
mScrollView->setVisibleVScroll(true);
mScrollView->setVisibleHScroll(true);
dragArea->setSize(size);
}
void ItemView::update()
{
while (mScrollView->getChildCount())
@ -64,10 +101,6 @@ void ItemView::update()
if (!mModel)
return;
int x = 0;
int y = 0;
int maxHeight = mScrollView->getSize().height - 58;
mModel->update();
MyGUI::Widget* dragArea = mScrollView->createWidget<MyGUI::Widget>("",0,0,mScrollView->getWidth(),mScrollView->getHeight(),
@ -80,9 +113,8 @@ void ItemView::update()
{
const ItemStack& item = mModel->getItem(i);
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
ItemWidget* itemWidget = dragArea->createWidget<ItemWidget>("MW_ItemIcon",
MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
itemWidget->setUserString("ToolTipType", "ItemModelIndex");
itemWidget->setUserData(std::make_pair(i, mModel));
ItemWidget::ItemState state = ItemWidget::None;
@ -104,25 +136,9 @@ void ItemView::update()
text->setTextShadow(true);
text->setTextShadowColour(MyGUI::Colour(0,0,0));
text->setCaption(getCountString(item.mCount));
y += 42;
if (y > maxHeight)
{
x += 42;
y = 0;
}
}
x += 42;
MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height);
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mScrollView->setVisibleVScroll(false);
mScrollView->setVisibleHScroll(false);
mScrollView->setCanvasSize(size);
mScrollView->setVisibleVScroll(true);
mScrollView->setVisibleHScroll(true);
dragArea->setSize(size);
layoutWidgets();
}
void ItemView::onSelectedItem(MyGUI::Widget *sender)
@ -149,7 +165,7 @@ void ItemView::setSize(const MyGUI::IntSize &_value)
bool changed = (_value.width != getWidth() || _value.height != getHeight());
Base::setSize(_value);
if (changed)
update();
layoutWidgets();
}
void ItemView::setSize(int _width, int _height)
@ -162,7 +178,7 @@ void ItemView::setCoord(const MyGUI::IntCoord &_value)
bool changed = (_value.width != getWidth() || _value.height != getHeight());
Base::setCoord(_value);
if (changed)
update();
layoutWidgets();
}
void ItemView::setCoord(int _left, int _top, int _width, int _height)

@ -35,6 +35,8 @@ namespace MWGui
private:
virtual void initialiseOverride();
void layoutWidgets();
virtual void setSize(const MyGUI::IntSize& _value);
virtual void setCoord(const MyGUI::IntCoord& _value);
void setSize(int _width, int _height);

@ -201,10 +201,6 @@ namespace
setBookMode ();
/// \todo Wiping the whole book layout each time the journal is opened is probably too costly for a large journal (eg 300+ pages).
/// There should be a way to keep the existing layout and append new entries to the end of it.
/// However, that still leaves the problem of having to add links to previously unknown, but now known topics, so
/// we maybe need to find another way to speed things up.
Book journalBook;
if (mModel->isEmpty ())
journalBook = createEmptyJournalBook ();

@ -92,7 +92,6 @@ namespace MWGui
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
if (name == "return")
{
MWBase::Environment::get().getSoundManager ()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu);
}
else if (name == "options")

@ -544,15 +544,9 @@ namespace MWGui
void MapWindow::open()
{
// force markers to foreground
for (unsigned int i=0; i<mGlobalMapOverlay->getChildCount (); ++i)
{
if (mGlobalMapOverlay->getChildAt (i)->getName().substr(0,4) == "Door")
mGlobalMapOverlay->getChildAt (i)->castType<MyGUI::Button>()->setImageResource("DoorMarker");
}
globalMapUpdatePlayer();
mPlayerArrowGlobal->setImageTexture ("");
mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds");
}

@ -32,7 +32,6 @@ namespace MWGui
, mHairIndex(0)
, mCurrentAngle(0)
, mPreviewDirty(true)
, mPreview(NULL)
{
// Centre dialog
center();
@ -115,7 +114,14 @@ namespace MWGui
updateSkills();
updateSpellPowers();
mPreview = new MWRender::RaceSelectionPreview();
mPreview.reset(NULL);
mPreviewImage->setImageTexture("");
const std::string textureName = "CharacterHeadPreview";
MyGUI::RenderManager::getInstance().destroyTexture(MyGUI::RenderManager::getInstance().getTexture(textureName));
mPreview.reset(new MWRender::RaceSelectionPreview());
mPreview->setup();
mPreview->update (0);
@ -129,7 +135,7 @@ namespace MWGui
index = proto.mHair.substr(proto.mHair.size() - 2, 2);
mHairIndex = boost::lexical_cast<int>(index) - 1;
mPreviewImage->setImageTexture ("CharacterHeadPreview");
mPreviewImage->setImageTexture (textureName);
mPreviewDirty = true;
}
@ -157,8 +163,7 @@ namespace MWGui
void RaceDialog::close()
{
delete mPreview;
mPreview = 0;
mPreview.reset(NULL);
}
// widget controls
@ -306,6 +311,10 @@ namespace MWGui
void RaceDialog::doRenderUpdate()
{
if (!mPreview.get())
return;
mPreview->onFrame();
if (mPreviewDirty)
{
mPreview->render();

@ -100,7 +100,7 @@ namespace MWGui
float mCurrentAngle;
MWRender::RaceSelectionPreview* mPreview;
std::auto_ptr<MWRender::RaceSelectionPreview> mPreview;
bool mPreviewDirty;
};

@ -689,12 +689,10 @@ namespace MWInput
if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) //No open GUIs, open up the MainMenu
{
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
MWBase::Environment::get().getSoundManager()->pauseSounds (MWBase::SoundManager::Play_TypeSfx);
}
else //Close current GUI
{
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
MWBase::Environment::get().getSoundManager()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
}
}

@ -301,20 +301,31 @@ namespace MWMechanics
}
}
// start combat if we are in combat with any followers of this actor
const std::list<MWWorld::Ptr>& followers = getActorsFollowing(actor2);
// start combat if target actor is in combat with one of our followers
const std::list<MWWorld::Ptr>& followers = getActorsFollowing(actor1);
const CreatureStats& creatureStats2 = actor2.getClass().getCreatureStats(actor2);
for (std::list<MWWorld::Ptr>::const_iterator it = followers.begin(); it != followers.end(); ++it)
{
if (creatureStats.getAiSequence().isInCombat(*it))
// need to check both ways since player doesn't use AI packages
if (creatureStats2.getAiSequence().isInCombat(*it)
|| it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor2))
aggressive = true;
}
// start combat if we are in combat with someone this actor is following
const CreatureStats& creatureStats2 = actor2.getClass().getCreatureStats(actor2);
for (std::list<MWMechanics::AiPackage*>::const_iterator it = creatureStats2.getAiSequence().begin(); it != creatureStats2.getAiSequence().end(); ++it)
// start combat if target actor is in combat with someone we are following
for (std::list<MWMechanics::AiPackage*>::const_iterator it = creatureStats.getAiSequence().begin(); it != creatureStats.getAiSequence().end(); ++it)
{
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow &&
creatureStats.getAiSequence().isInCombat(dynamic_cast<MWMechanics::AiFollow*>(*it)->getTarget()))
aggressive = true;
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow)
{
MWWorld::Ptr followTarget = dynamic_cast<MWMechanics::AiFollow*>(*it)->getTarget();
if (followTarget.isEmpty())
continue;
// need to check both ways since player doesn't use AI packages
if (creatureStats2.getAiSequence().isInCombat(followTarget)
|| followTarget.getClass().getCreatureStats(followTarget).getAiSequence().isInCombat(actor2))
aggressive = true;
}
}
if(aggressive)
@ -1374,11 +1385,19 @@ namespace MWMechanics
{
const MWWorld::Class &cls = iter->first.getClass();
CreatureStats &stats = cls.getCreatureStats(iter->first);
if(!stats.isDead() && stats.getAiSequence().getTypeId() == AiPackage::TypeIdFollow)
if (stats.isDead())
continue;
for (std::list<MWMechanics::AiPackage*>::const_iterator it = stats.getAiSequence().begin(); it != stats.getAiSequence().end(); ++it)
{
MWMechanics::AiFollow* package = static_cast<MWMechanics::AiFollow*>(stats.getAiSequence().getActivePackage());
if(package->getFollowedActor() == actor.getCellRef().getRefId())
list.push_front(iter->first);
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow)
{
MWWorld::Ptr followTarget = dynamic_cast<MWMechanics::AiFollow*>(*it)->getTarget();
if (followTarget.isEmpty())
continue;
if (followTarget == actor)
list.push_back(iter->first);
}
}
}
return list;
@ -1439,4 +1458,10 @@ namespace MWMechanics
mActors.clear();
mDeathCount.clear();
}
void Actors::updateMagicEffects(const MWWorld::Ptr &ptr)
{
adjustMagicEffects(ptr);
calculateCreatureStatModifiers(ptr, 0.f);
}
}

@ -56,7 +56,7 @@ namespace MWMechanics
/// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently
/// paused we may want to do it manually (after equipping permanent enchantment)
void updateMagicEffects (const MWWorld::Ptr& ptr) { adjustMagicEffects(ptr); }
void updateMagicEffects (const MWWorld::Ptr& ptr);
void addActor (const MWWorld::Ptr& ptr, bool updateImmediately=false);
///< Register an actor for stats management

@ -16,24 +16,33 @@
#include "steering.hpp"
MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z)
: mAlwaysFollow(false), mCommanded(false), mRemainingDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId("")
: mAlwaysFollow(false), mCommanded(false), mRemainingDuration(duration), mX(x), mY(y), mZ(z)
, mActorRefId(actorId), mCellId(""), mActorId(-1)
{
}
MWMechanics::AiFollow::AiFollow(const std::string &actorId,const std::string &cellId,float duration, float x, float y, float z)
: mAlwaysFollow(false), mCommanded(false), mRemainingDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId), mCellId(cellId)
: mAlwaysFollow(false), mCommanded(false), mRemainingDuration(duration), mX(x), mY(y), mZ(z)
, mActorRefId(actorId), mCellId(cellId), mActorId(-1)
{
}
MWMechanics::AiFollow::AiFollow(const std::string &actorId, bool commanded)
: mAlwaysFollow(true), mCommanded(commanded), mRemainingDuration(0), mX(0), mY(0), mZ(0), mActorId(actorId), mCellId("")
: mAlwaysFollow(true), mCommanded(commanded), mRemainingDuration(0), mX(0), mY(0), mZ(0)
, mActorRefId(actorId), mCellId(""), mActorId(-1)
{
}
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
{
const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mActorId, false); //The target to follow
MWWorld::Ptr target = getTarget();
if(target == MWWorld::Ptr()) return true; //Target doesn't exist
if (target.isEmpty())
return true; //Target doesn't exist
// Only the player can be actively followed. AiFollow packages with targets other than the player
// are only used for defining combat alliances, since NPCs will defend whoever they are following or being followed by.
if (target != MWBase::Environment::get().getWorld()->getPlayerPtr())
return false;
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
@ -86,7 +95,7 @@ bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
std::string MWMechanics::AiFollow::getFollowedActor()
{
return mActorId;
return mActorRefId;
}
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const
@ -110,7 +119,7 @@ void MWMechanics::AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) co
follow->mData.mX = mX;
follow->mData.mY = mY;
follow->mData.mZ = mZ;
follow->mTargetId = mActorId;
follow->mTargetId = mActorRefId;
follow->mRemainingDuration = mRemainingDuration;
follow->mCellId = mCellId;
follow->mAlwaysFollow = mAlwaysFollow;
@ -125,13 +134,31 @@ void MWMechanics::AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) co
MWMechanics::AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow)
: mAlwaysFollow(follow->mAlwaysFollow), mRemainingDuration(follow->mRemainingDuration)
, mX(follow->mData.mX), mY(follow->mData.mY), mZ(follow->mData.mZ)
, mActorId(follow->mTargetId), mCellId(follow->mCellId)
, mActorRefId(follow->mTargetId), mCellId(follow->mCellId)
, mCommanded(follow->mCommanded)
{
}
MWWorld::Ptr MWMechanics::AiFollow::getTarget() const
MWWorld::Ptr MWMechanics::AiFollow::getTarget()
{
return MWBase::Environment::get().getWorld()->searchPtr(mActorId, false);
if (mActorId == -2)
return MWWorld::Ptr();
if (mActorId == -1)
{
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mActorRefId, false);
if (target.isEmpty())
{
mActorId = -2;
return target;
}
else
mActorId = target.getClass().getCreatureStats(target).getActorId();
}
if (mActorId != -1)
return MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId);
else
return MWWorld::Ptr();
}

@ -31,7 +31,7 @@ namespace MWMechanics
AiFollow(const ESM::AiSequence::AiFollow* follow);
MWWorld::Ptr getTarget() const;
MWWorld::Ptr getTarget();
virtual AiFollow *clone() const;
@ -55,7 +55,8 @@ namespace MWMechanics
float mX;
float mY;
float mZ;
std::string mActorId;
std::string mActorRefId;
int mActorId;
std::string mCellId;
};
}

@ -35,6 +35,8 @@ namespace MWMechanics
void AiWander::init()
{
// NOTE: mDistance and mDuration must be set already
mCellX = std::numeric_limits<int>::max();
mCellY = std::numeric_limits<int>::max();
mXCell = 0;
@ -47,7 +49,7 @@ namespace MWMechanics
mRotate = false;
mTargetAngle = 0;
mSaidGreeting = Greet_None;
greetingTimer = 0;
mGreetingTimer = 0;
mHasReturnPosition = false;
mReturnPosition = Ogre::Vector3(0,0,0);
@ -430,19 +432,19 @@ namespace MWMechanics
{
if ((playerDistSqr <= helloDistance*helloDistance) && MWBase::Environment::get().getWorld()->getLOS(player, actor)
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, actor))
greetingTimer++;
mGreetingTimer++;
if (greetingTimer >= GREETING_SHOULD_START)
if (mGreetingTimer >= GREETING_SHOULD_START)
{
mSaidGreeting = Greet_InProgress;
MWBase::Environment::get().getDialogueManager()->say(actor, "hello");
greetingTimer = 0;
mGreetingTimer = 0;
}
}
if(mSaidGreeting == Greet_InProgress)
{
greetingTimer++;
mGreetingTimer++;
if(mWalking)
{
@ -470,10 +472,10 @@ namespace MWMechanics
}
}
if (greetingTimer >= GREETING_SHOULD_END)
if (mGreetingTimer >= GREETING_SHOULD_END)
{
mSaidGreeting = Greet_Done;
greetingTimer = 0;
mGreetingTimer = 0;
}
}
@ -680,8 +682,6 @@ namespace MWMechanics
AiWander::AiWander (const ESM::AiSequence::AiWander* wander)
{
init();
mDistance = wander->mData.mDistance;
mDuration = wander->mData.mDuration;
mStartTime = MWWorld::TimeStamp(wander->mStartTime);
@ -690,6 +690,8 @@ namespace MWMechanics
mIdle.push_back(wander->mData.mIdle[i]);
mRepeat = wander->mData.mShouldRepeat;
init();
}
}

@ -36,6 +36,7 @@ namespace MWMechanics
AiWander (const ESM::AiSequence::AiWander* wander);
// NOTE: mDistance and mDuration must be set already
void init();
virtual AiPackage *clone() const;
@ -68,7 +69,7 @@ namespace MWMechanics
Greet_Done
};
GreetingState mSaidGreeting;
int greetingTimer;
int mGreetingTimer;
bool mHasReturnPosition; // NOTE: Could be removed if mReturnPosition was initialized to actor position,
// if we had the actor in the AiWander constructor...

@ -1430,9 +1430,12 @@ void ObjectAnimation::removeParticles()
{
for (unsigned int i=0; i<mObjectRoot->mParticles.size(); ++i)
{
mObjectRoot->mSceneMgr->destroyParticleSystem(mObjectRoot->mParticles[i]);
// Don't destroyParticleSystem, the ParticleSystemController is still holding a pointer to it.
// Don't setVisible, this could conflict with a VisController.
// The following will remove all spawned particles, then set the speed factor to zero so that no new ones will be spawned.
mObjectRoot->mParticles[i]->setSpeedFactor(0.f);
mObjectRoot->mParticles[i]->clear();
}
mObjectRoot->mParticles.clear();
}

@ -298,6 +298,9 @@ namespace MWRender
void RaceSelectionPreview::render()
{
mTexture->load();
if (!mRenderTarget)
setupRenderTarget();
mRenderTarget->update();
}

@ -31,6 +31,10 @@ namespace MWRender
{
}
GlobalMap::~GlobalMap()
{
Ogre::TextureManager::getSingleton().remove(mOverlayTexture->getName());
}
void GlobalMap::render (Loading::Listener* loadingListener)
{
@ -168,9 +172,8 @@ namespace MWRender
tex->load();
mOverlayTexture = Ogre::TextureManager::getSingleton().createManual("GlobalMapOverlay", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, Ogre::PF_A8B8G8R8, Ogre::TU_DYNAMIC_WRITE_ONLY);
Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, Ogre::PF_A8B8G8R8, Ogre::TU_DYNAMIC, this);
clear();
@ -194,9 +197,11 @@ namespace MWRender
void GlobalMap::exploreCell(int cellX, int cellY)
{
float originX = (cellX - mMinX) * 24;
const int size = 24;
float originX = (cellX - mMinX) * size;
// NB y + 1, because we want the top left corner, not bottom left where the origin of the cell is
float originY = mHeight - (cellY+1 - mMinY) * 24;
float originY = mHeight - (cellY+1 - mMinY) * size;
if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY)
return;
@ -204,31 +209,47 @@ namespace MWRender
Ogre::TexturePtr localMapTexture = Ogre::TextureManager::getSingleton().getByName("Cell_"
+ boost::lexical_cast<std::string>(cellX) + "_" + boost::lexical_cast<std::string>(cellY));
// mipmap version - can't get ogre to generate automips..
/*if (!localMapTexture.isNull())
{
assert(localMapTexture->getBuffer(0, 4)->getWidth() == 64); // 1024 / 2^4
mOverlayTexture->getBuffer()->blit(localMapTexture->getBuffer(0, 4), Ogre::Image::Box(0,0,64, 64),
Ogre::Image::Box(originX,originY,originX+24,originY+24));
}*/
if (!localMapTexture.isNull())
{
mOverlayTexture->load();
mOverlayTexture->getBuffer()->blit(localMapTexture->getBuffer(), Ogre::Image::Box(0,0,512,512),
Ogre::Image::Box(originX,originY,originX+24,originY+24));
Ogre::Image::Box(originX,originY,originX+size,originY+size));
Ogre::Image backup;
std::vector<Ogre::uchar> data;
data.resize(size*size*4, 0);
backup.loadDynamicImage(&data[0], size, size, Ogre::PF_A8B8G8R8);
localMapTexture->getBuffer()->blitToMemory(Ogre::Image::Box(0,0,512,512), backup.getPixelBox());
for (int x=0; x<size; ++x)
for (int y=0; y<size; ++y)
{
assert (originX+x < mOverlayImage.getWidth());
assert (originY+y < mOverlayImage.getHeight());
assert (x < int(backup.getWidth()));
assert (y < int(backup.getHeight()));
mOverlayImage.setColourAt(backup.getColourAt(x, y, 0), originX+x, originY+y, 0);
}
}
}
void GlobalMap::clear()
{
std::vector<Ogre::uint32> buffer;
// initialize to (0,0,0,0)
buffer.resize(mWidth * mHeight, 0);
Ogre::uchar* buffer = OGRE_ALLOC_T(Ogre::uchar, mWidth * mHeight * 4, Ogre::MEMCATEGORY_GENERAL);
memset(buffer, 0, mWidth * mHeight * 4);
Ogre::PixelBox pb(mWidth, mHeight, 1, Ogre::PF_A8B8G8R8, &buffer[0]);
mOverlayImage.loadDynamicImage(&buffer[0], mWidth, mHeight, 1, Ogre::PF_A8B8G8R8, true); // pass ownership of buffer to image
mOverlayTexture->getBuffer()->blitFromMemory(pb);
mOverlayTexture->load();
}
void GlobalMap::loadResource(Ogre::Resource *resource)
{
Ogre::Texture* tex = dynamic_cast<Ogre::Texture*>(resource);
Ogre::ConstImagePtrList list;
list.push_back(&mOverlayImage);
tex->_loadImages(list);
}
void GlobalMap::write(ESM::GlobalMap& map)
@ -238,9 +259,7 @@ namespace MWRender
map.mBounds.mMinY = mMinY;
map.mBounds.mMaxY = mMaxY;
Ogre::Image image;
mOverlayTexture->convertToImage(image);
Ogre::DataStreamPtr encoded = image.encode("png");
Ogre::DataStreamPtr encoded = mOverlayImage.encode("png");
map.mImageData.resize(encoded->size());
encoded->read(&map.mImageData[0], encoded->size());
}
@ -303,8 +322,15 @@ namespace MWRender
image.getHeight(), 0, Ogre::PF_A8B8G8R8);
tex->loadImage(image);
mOverlayTexture->load();
mOverlayTexture->getBuffer()->blit(tex->getBuffer(), srcBox, destBox);
if (srcBox.left == destBox.left && srcBox.right == destBox.right
&& srcBox.top == destBox.top && srcBox.bottom == destBox.bottom)
mOverlayImage = image;
else
mOverlayTexture->convertToImage(mOverlayImage);
Ogre::TextureManager::getSingleton().remove("@temp");
}
}

@ -18,10 +18,11 @@ namespace ESM
namespace MWRender
{
class GlobalMap
class GlobalMap : public Ogre::ManualResourceLoader
{
public:
GlobalMap(const std::string& cacheDir);
~GlobalMap();
void render(Loading::Listener* loadingListener);
@ -29,13 +30,13 @@ namespace MWRender
int getHeight() { return mHeight; }
void worldPosToImageSpace(float x, float z, float& imageX, float& imageY);
///< @param x x ogre coords
/// @param z z ogre coords
void cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY);
void exploreCell (int cellX, int cellY);
virtual void loadResource(Ogre::Resource* resource);
/// Clears the overlay
void clear();
@ -48,6 +49,7 @@ namespace MWRender
std::vector< std::pair<int,int> > mExploredCells;
Ogre::TexturePtr mOverlayTexture;
Ogre::Image mOverlayImage; // Backup in system memory
int mWidth;
int mHeight;

@ -324,6 +324,7 @@ void LocalMap::createFogOfWar(const std::string& texturePrefix)
buffer.resize(sFogOfWarResolution*sFogOfWarResolution, 0xFF000000);
// upload to the texture
tex->load();
memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &buffer[0], sFogOfWarResolution*sFogOfWarResolution*4);
tex->getBuffer()->unlock();

@ -61,8 +61,6 @@ namespace MWRender
* Set the position & direction of the player.
* @remarks This is used to draw a "fog of war" effect
* to hide areas on the map the player has not discovered yet.
* @param position (OGRE coordinates)
* @param camera orientation (OGRE coordinates)
*/
void updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation);
@ -74,7 +72,7 @@ namespace MWRender
/**
* Get the interior map texture index and normalized position
* on this texture, given a world position (in ogre coordinates)
* on this texture, given a world position
*/
void getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y);

@ -784,6 +784,13 @@ namespace MWWorld
mMovementQueue.push_back(std::make_pair(ptr, movement));
}
void PhysicsSystem::clearQueuedMovement()
{
mMovementQueue.clear();
mCollisions.clear();
mStandingCollisions.clear();
}
const PtrVelocityList& PhysicsSystem::applyQueuedMovement(float dt)
{
// Collision events are only tracked for a single frame, so reset first

@ -85,8 +85,12 @@ namespace MWWorld
/// be overwritten. Valid until the next call to applyQueuedMovement.
void queueObjectMovement(const Ptr &ptr, const Ogre::Vector3 &velocity);
/// Apply all queued movements, then clear the list.
const PtrVelocityList& applyQueuedMovement(float dt);
/// Clear the queued movements list without applying.
void clearQueuedMovement();
/// Return true if \a actor has been standing on \a object in this frame
/// This will trigger whenever the object is directly below the actor.
/// It doesn't matter if the actor is stationary or moving.

@ -350,36 +350,59 @@ namespace MWWorld
void World::ensureNeededRecords()
{
if (!mStore.get<ESM::GameSetting>().search("sCompanionShare"))
{
ESM::GameSetting sCompanionShare;
sCompanionShare.mId = "sCompanionShare";
ESM::Variant value;
value.setType(ESM::VT_String);
value.setString("Companion Share");
sCompanionShare.mValue = value;
mStore.insertStatic(sCompanionShare);
}
if (!mStore.get<ESM::Global>().search("dayspassed"))
{
// vanilla Morrowind does not define dayspassed.
ESM::Global dayspassed;
dayspassed.mId = "dayspassed";
ESM::Variant value;
value.setType(ESM::VT_Long);
value.setInteger(1); // but the addons start counting at 1 :(
dayspassed.mValue = value;
mStore.insertStatic(dayspassed);
std::map<std::string, ESM::Variant> gmst;
// Companion (tribunal)
gmst["sCompanionShare"] = ESM::Variant("Companion Share");
gmst["sCompanionWarningMessage"] = ESM::Variant("Warning message");
gmst["sCompanionWarningButtonOne"] = ESM::Variant("Button 1");
gmst["sCompanionWarningButtonTwo"] = ESM::Variant("Button 2");
gmst["sCompanionShare"] = ESM::Variant("Companion Share");
gmst["sProfitValue"] = ESM::Variant("Profit Value");
gmst["sTeleportDisabled"] = ESM::Variant("Teleport disabled");
gmst["sLevitateDisabled"] = ESM::Variant("Levitate disabled");
// Missing in unpatched MW 1.0
gmst["sDifficulty"] = ESM::Variant("Difficulty");
gmst["fDifficultyMult"] = ESM::Variant(5.f);
gmst["sAuto_Run"] = ESM::Variant("Auto Run");
gmst["sServiceRefusal"] = ESM::Variant("Service Refusal");
gmst["sNeedOneSkill"] = ESM::Variant("Need one skill");
gmst["sNeedTwoSkills"] = ESM::Variant("Need two skills");
gmst["sEasy"] = ESM::Variant("Easy");
gmst["sHard"] = ESM::Variant("Hard");
gmst["sDeleteNote"] = ESM::Variant("Delete Note");
gmst["sEditNote"] = ESM::Variant("Edit Note");
// Werewolf (BM)
gmst["fWereWolfRunMult"] = ESM::Variant(1.f);
gmst["fWereWolfSilverWeaponDamageMult"] = ESM::Variant(1.f);
std::map<std::string, ESM::Variant> globals;
// vanilla Morrowind does not define dayspassed.
globals["dayspassed"] = ESM::Variant(1); // but the addons start counting at 1 :(
globals["WerewolfClawMult"] = ESM::Variant(1.f);
for (std::map<std::string, ESM::Variant>::iterator it = gmst.begin(); it != gmst.end(); ++it)
{
if (!mStore.get<ESM::GameSetting>().search(it->first))
{
ESM::GameSetting setting;
setting.mId = it->first;
setting.mValue = it->second;
mStore.insertStatic(setting);
}
}
if (!mStore.get<ESM::GameSetting>().search("fWereWolfRunMult"))
for (std::map<std::string, ESM::Variant>::iterator it = globals.begin(); it != globals.end(); ++it)
{
ESM::GameSetting fWereWolfRunMult;
fWereWolfRunMult.mId = "fWereWolfRunMult";
ESM::Variant value;
value.setType(ESM::VT_Float);
value.setFloat(1.f);
fWereWolfRunMult.mValue = value;
mStore.insertStatic(fWereWolfRunMult);
if (!mStore.get<ESM::Global>().search(it->first))
{
ESM::Global setting;
setting.mId = it->first;
setting.mValue = it->second;
mStore.insertStatic(setting);
}
}
}
@ -840,6 +863,8 @@ namespace MWWorld
void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
{
mPhysics->clearQueuedMovement();
if (mCurrentWorldSpace != cellName)
{
// changed worldspace
@ -855,6 +880,8 @@ namespace MWWorld
void World::changeToExteriorCell (const ESM::Position& position)
{
mPhysics->clearQueuedMovement();
if (mCurrentWorldSpace != "sys::default") // FIXME
{
// changed worldspace

@ -205,7 +205,7 @@ namespace MWWorld
virtual bool isCellQuasiExterior() const;
virtual Ogre::Vector2 getNorthVector (CellStore* cell);
///< get north vector (OGRE coordinates) for given interior cell
///< get north vector for given interior cell
virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector<DoorMarker>& out);
///< get a list of teleport door markers for a given cell, to be displayed on the local map

@ -83,7 +83,7 @@ public:
// indirectly to the load() method.
int mIdx;
void setIndex(const int index) {mIdx = index; mCtx.index = index;}
const int getIndex() {return mIdx;}
int getIndex() {return mIdx;}
void setGlobalReaderList(std::vector<ESMReader> *list) {mGlobalReaderList = list;}
std::vector<ESMReader> *getGlobalReaderList() {return mGlobalReaderList;}

@ -17,6 +17,30 @@ namespace
ESM::Variant::Variant() : mType (VT_None), mData (0) {}
ESM::Variant::Variant(const std::string &value)
{
mData = 0;
mType = VT_None;
setType(VT_String);
setString(value);
}
ESM::Variant::Variant(int value)
{
mData = 0;
mType = VT_None;
setType(VT_Long);
setInteger(value);
}
ESM::Variant::Variant(float value)
{
mData = 0;
mType = VT_None;
setType(VT_Float);
setFloat(value);
}
ESM::Variant::~Variant()
{
delete mData;

@ -38,6 +38,10 @@ namespace ESM
Variant();
Variant (const std::string& value);
Variant (int value);
Variant (float value);
~Variant();
Variant& operator= (const Variant& variant);
@ -83,4 +87,4 @@ namespace ESM
bool operator!= (const Variant& left, const Variant& right);
}
#endif
#endif

@ -118,9 +118,6 @@ ObjectScene::~ObjectScene()
void ObjectScene::setVisibilityFlags (unsigned int flags)
{
if (mSkelBase)
mSkelBase->setVisibilityFlags (flags);
for (std::vector<Ogre::Entity*>::iterator iter (mEntities.begin()); iter!=mEntities.end();
++iter)
(*iter)->setVisibilityFlags (flags);

@ -79,7 +79,7 @@ void Manager::saveUser(const std::string& file)
fout.close();
}
const std::string Manager::getString (const std::string& setting, const std::string& category)
std::string Manager::getString (const std::string& setting, const std::string& category)
{
if (mNewSettings.find(std::make_pair(category, setting)) != mNewSettings.end())
return mNewSettings[std::make_pair(category, setting)];
@ -92,17 +92,17 @@ const std::string Manager::getString (const std::string& setting, const std::str
return val;
}
const float Manager::getFloat (const std::string& setting, const std::string& category)
float Manager::getFloat (const std::string& setting, const std::string& category)
{
return Ogre::StringConverter::parseReal( getString(setting, category) );
}
const int Manager::getInt (const std::string& setting, const std::string& category)
int Manager::getInt (const std::string& setting, const std::string& category)
{
return Ogre::StringConverter::parseInt( getString(setting, category) );
}
const bool Manager::getBool (const std::string& setting, const std::string& category)
bool Manager::getBool (const std::string& setting, const std::string& category)
{
return Ogre::StringConverter::parseBool( getString(setting, category) );
}

@ -36,10 +36,10 @@ namespace Settings
static const CategorySettingVector apply();
///< returns the list of changed settings and then clears it
static const int getInt (const std::string& setting, const std::string& category);
static const float getFloat (const std::string& setting, const std::string& category);
static const std::string getString (const std::string& setting, const std::string& category);
static const bool getBool (const std::string& setting, const std::string& category);
static int getInt (const std::string& setting, const std::string& category);
static float getFloat (const std::string& setting, const std::string& category);
static std::string getString (const std::string& setting, const std::string& category);
static bool getBool (const std::string& setting, const std::string& category);
static void setInt (const std::string& setting, const std::string& category, const int value);
static void setFloat (const std::string& setting, const std::string& category, const float value);

Loading…
Cancel
Save