door markers on the local map

actorid
scrawl 13 years ago
parent 34c30b132c
commit 5834b4baa5

@ -65,6 +65,12 @@ namespace MWBase
Render_Compositors
};
struct DoorMarker
{
std::string name;
float x, y; // world position
};
World() {}
virtual ~World() {}
@ -108,6 +114,15 @@ namespace MWBase
virtual Ogre::Vector2 getNorthVector (MWWorld::CellStore* cell) = 0;
///< get north vector (OGRE coordinates) for given interior cell
virtual std::vector<DoorMarker> getDoorMarkers (MWWorld::CellStore* cell) = 0;
///< get a list of teleport door markers for a given cell, to be displayed on the local map
virtual void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) = 0;
///< see MWRender::LocalMap::getInteriorMapPosition
virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior) = 0;
///< see MWRender::LocalMap::isPositionExplored
virtual MWWorld::Globals::Data& getGlobalVariable (const std::string& name) = 0;
virtual MWWorld::Globals::Data getGlobalVariable (const std::string& name) const = 0;

@ -60,7 +60,6 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
getWidget(mHealth, "Health");
getWidget(mMagicka, "Magicka");
getWidget(mStamina, "Stamina");
mHealthManaStaminaBaseLeft = mHealthFrame->getLeft();
MyGUI::Widget *healthFrame, *magickaFrame, *fatigueFrame;
@ -93,9 +92,10 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
getWidget(mMinimapBox, "MiniMapBox");
mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight();
mMinimapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
getWidget(mMinimap, "MiniMap");
getWidget(mCompass, "Compass");
getWidget(mMinimapButton, "MiniMapButton");
mMinimapButton->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
getWidget(mCellNameBox, "CellName");
getWidget(mWeaponSpellBox, "WeaponSpellName");

@ -50,6 +50,7 @@ namespace MWGui
MyGUI::ImageBox *mWeapImage, *mSpellImage;
MyGUI::ProgressPtr mWeapStatus, mSpellStatus;
MyGUI::Widget *mEffectBox, *mMinimapBox;
MyGUI::Button* mMinimapButton;
MyGUI::ImageBox* mEffect1;
MyGUI::ScrollView* mMinimap;
MyGUI::ImageBox* mCompass;

@ -1,9 +1,13 @@
#include "map_window.hpp"
#include "../mwbase/windowmanager.hpp"
#include <boost/lexical_cast.hpp>
#include <OgreVector2.h>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
using namespace MWGui;
LocalMapBase::LocalMapBase()
@ -92,10 +96,21 @@ void LocalMapBase::applyFogOfWar()
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
{
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
// clear all previous markers
for (unsigned int i=0; i< mLocalMap->getChildCount(); ++i)
{
if (mLocalMap->getChildAt(i)->getName ().substr (0, 6) == "Marker")
{
MyGUI::Gui::getInstance ().destroyWidget (mLocalMap->getChildAt(i));
}
}
for (int mx=0; mx<3; ++mx)
{
for (int my=0; my<3; ++my)
{
// map
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
@ -108,12 +123,79 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
box->setImageTexture(image);
else
box->setImageTexture("black.png");
// door markers
// interior map only consists of one cell, so handle the markers only once
if (interior && (mx != 2 || my != 2))
continue;
MWWorld::CellStore* cell;
if (interior)
cell = MWBase::Environment::get().getWorld ()->getInterior (mPrefix);
else
cell = MWBase::Environment::get().getWorld ()->getExterior (x+mx-1, y-(my-1));
std::vector<MWBase::World::DoorMarker> doors = MWBase::Environment::get().getWorld ()->getDoorMarkers (cell);
for (std::vector<MWBase::World::DoorMarker>::iterator it = doors.begin(); it != doors.end(); ++it)
{
MWBase::World::DoorMarker marker = *it;
// convert world coordinates to normalized cell coordinates
MyGUI::IntCoord widgetCoord;
float nX,nY;
int cellDx, cellDy;
if (!interior)
{
const int cellSize = 8192;
nX = (marker.x - cellSize * (x+mx-1)) / cellSize;
nY = 1 - (marker.y - cellSize * (y-(my-1))) / cellSize;
widgetCoord = MyGUI::IntCoord(nX * 512 - 3 + mx * 512, nY * 512 - 3 + my * 512, 7, 7);
}
else
{
Ogre::Vector2 position (marker.x, -marker.y);
MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
widgetCoord = MyGUI::IntCoord(nX * 512 - 3 + (1+cellDx-x) * 512, nY * 512 - 3 + (1+cellDy-y) * 512, 7, 7);
}
std::cout << "widgetCoord " << widgetCoord.left << " " << widgetCoord.top << " nX " << nX << " nY " << nY << " xy " << x << " " << y << std::endl;
static int counter = 0;
++counter;
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(counter));
markerWidget->setImageTexture ("textures\\door_icon.dds");
markerWidget->setImageCoord (MyGUI::IntCoord(0,0,7,7));
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTip");
markerWidget->setUserString("Caption_Text", marker.name);
markerWidget->setUserString("IsMarker", "true");
MarkerPosition markerPos;
markerPos.interior = interior;
markerPos.cellX = interior ? cellDx : x + mx - 1;
markerPos.cellY = interior ? cellDy : y + ((my - 1)*-1);
markerPos.nX = nX;
markerPos.nY = nY;
markerWidget->setUserData(markerPos);
}
}
}
mInterior = interior;
mCurX = x;
mCurY = y;
mChanged = false;
// fog of war
applyFogOfWar();
// set the compass texture again, because MyGUI determines sorting of ImageBox widgets

@ -18,6 +18,15 @@ namespace MWGui
void toggleFogOfWar();
struct MarkerPosition
{
bool interior;
int cellX;
int cellY;
float nX;
float nY;
};
protected:
int mCurX, mCurY;
bool mInterior;

@ -12,6 +12,7 @@
#include "../mwworld/class.hpp"
#include "map_window.hpp"
#include "widgets.hpp"
using namespace MWGui;
@ -150,7 +151,19 @@ void ToolTips::onFrame(float frameDuration)
{
return;
}
else if (type == "ItemPtr")
// special handling for markers on the local map: the tooltip should only be visible
// if the marker is not hidden due to the fog of war.
if (focus->getUserString ("IsMarker") == "true")
{
LocalMapBase::MarkerPosition pos = *focus->getUserData<LocalMapBase::MarkerPosition>();
if (!MWBase::Environment::get().getWorld ()->isPositionExplored (pos.nX, pos.nY, pos.cellX, pos.cellY, pos.interior))
return;
}
if (type == "ItemPtr")
{
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
tooltipSize = getToolTipViaPtr(false);
@ -199,7 +212,8 @@ void ToolTips::onFrame(float frameDuration)
it != userStrings.end(); ++it)
{
if (it->first == "ToolTipType"
|| it->first == "ToolTipLayout")
|| it->first == "ToolTipLayout"
|| it->first == "IsMarker")
continue;

@ -270,6 +270,34 @@ void LocalMap::render(const float x, const float y,
mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd);
}
void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y)
{
pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle);
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
x = std::ceil((pos.x - min.x)/sSize)-1;
y = std::ceil((pos.y - min.y)/sSize)-1;
nX = (pos.x - min.x - sSize*x)/sSize;
nY = (pos.y - min.y - sSize*y)/sSize;
}
bool LocalMap::isPositionExplored (float nX, float nY, int x, int y, bool interior)
{
std::string texName = (interior ? mInteriorName + "_" : "Cell_") + coordStr(x, y);
if (mBuffers.find(texName) == mBuffers.end())
return false;
int texU = (sFogOfWarResolution-1) * nX;
int texV = (sFogOfWarResolution-1) * nY;
Ogre::uint32 clr = mBuffers[texName][texV * sFogOfWarResolution + texU];
uint8 alpha = (clr >> 24);
return alpha < 200;
}
void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation)
{
if (sFogOfWarSkip != 0)
@ -281,14 +309,12 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
// retrieve the x,y grid coordinates the player is in
int x,y;
Vector3 _pos(position.x, 0, position.z);
Vector2 pos(_pos.x, _pos.z);
float u,v;
if (mInterior)
{
pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle);
}
Vector2 pos(position.x, position.z);
if (mInterior)
getInteriorMapPosition(pos, u,v, x,y);
Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis();
@ -303,14 +329,10 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
}
else
{
x = std::ceil((pos.x - min.x)/sSize)-1;
y = std::ceil((pos.y - min.y)/sSize)-1;
MWBase::Environment::get().getWindowManager()->setInteriorMapTexture(x,y);
}
// convert from world coordinates to texture UV coordinates
float u,v;
std::string texBaseName;
if (!mInterior)
{
@ -320,9 +342,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
}
else
{
u = (pos.x - min.x - sSize*x)/sSize;
v = (pos.y - min.y - sSize*y)/sSize;
texBaseName = mInteriorName + "_";
}

@ -58,6 +58,18 @@ namespace MWRender
*/
void saveFogOfWar(MWWorld::CellStore* cell);
/**
* Get the interior map texture index and normalized position
* on this texture, given a world position (in ogre coordinates)
*/
void getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y);
/**
* Check if a given position is explored by the player (i.e. not obscured by fog of war)
*/
bool isPositionExplored (float nX, float nY, int x, int y, bool interior);
private:
OEngine::Render::OgreRenderer* mRendering;
MWRender::RenderingManager* mRenderingManager;

@ -863,4 +863,14 @@ void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float
mPlayer->getSightAngles(pitch, yaw);
}
void RenderingManager::getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y)
{
return mLocalMap->getInteriorMapPosition (position, nX, nY, x, y);
}
bool RenderingManager::isPositionExplored (float nX, float nY, int x, int y, bool interior)
{
return mLocalMap->isPositionExplored(nX, nY, x, y, interior);
}
} // namespace

@ -184,6 +184,12 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
static bool waterShaderSupported();
virtual void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y);
///< see MWRender::LocalMap::getInteriorMapPosition
virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior);
///< see MWRender::LocalMap::isPositionExplored
protected:
virtual void windowResized(Ogre::RenderWindow* rw);
virtual void windowClosed(Ogre::RenderWindow* rw);

@ -1031,6 +1031,64 @@ namespace MWWorld
return d;
}
std::vector<World::DoorMarker> World::getDoorMarkers (CellStore* cell)
{
std::vector<World::DoorMarker> result;
MWWorld::CellRefList<ESM::Door> doors = cell->doors;
std::list< MWWorld::LiveCellRef<ESM::Door> > refList = doors.list;
for (std::list< MWWorld::LiveCellRef<ESM::Door> >::iterator it = refList.begin(); it != refList.end(); ++it)
{
MWWorld::LiveCellRef<ESM::Door> ref = *it;
if (ref.ref.teleport)
{
World::DoorMarker newMarker;
std::string dest;
if (ref.ref.destCell != "")
{
// door leads to an interior, use interior name
dest = ref.ref.destCell;
}
else
{
// door leads to exterior, use cell name (if any), otherwise translated region name
int x,y;
positionToIndex (ref.ref.doorDest.pos[0], ref.ref.doorDest.pos[1], x, y);
const ESM::Cell* cell = mStore.cells.findExt(x,y);
if (cell->name != "")
dest = cell->name;
else
{
const ESM::Region* region = mStore.regions.search(cell->region);
dest = region->name;
}
}
newMarker.name = dest;
ESM::Position pos = ref.mData.getPosition ();
newMarker.x = pos.pos[0];
newMarker.y = pos.pos[1];
result.push_back(newMarker);
}
}
return result;
}
void World::getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y)
{
mRendering->getInteriorMapPosition(position, nX, nY, x, y);
}
bool World::isPositionExplored (float nX, float nY, int x, int y, bool interior)
{
return mRendering->isPositionExplored(nX, nY, x, y, interior);
}
void World::setWaterHeight(const float height)
{
mRendering->setWaterHeight(height);

@ -140,6 +140,15 @@ namespace MWWorld
virtual Ogre::Vector2 getNorthVector (CellStore* cell);
///< get north vector (OGRE coordinates) for given interior cell
virtual std::vector<DoorMarker> getDoorMarkers (MWWorld::CellStore* cell);
///< get a list of teleport door markers for a given cell, to be displayed on the local map
virtual void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y);
///< see MWRender::LocalMap::getInteriorMapPosition
virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior);
///< see MWRender::LocalMap::isPositionExplored
virtual Globals::Data& getGlobalVariable (const std::string& name);
virtual Globals::Data getGlobalVariable (const std::string& name) const;

@ -76,18 +76,21 @@
</Widget>
<!-- Map box -->
<Widget type="Button" skin="" position="223 123 65 65" name="MiniMapBox" align="Right Bottom">
<Widget type="Widget" skin="" position="223 123 65 65" name="MiniMapBox" align="Right Bottom">
<Widget type="Widget" skin="HUD_Box" position="0 0 65 65" align="Center">
<Property key="NeedMouse" value="false"/>
<Widget type="ScrollView" skin="MW_MapView" position="2 2 61 61" align="Left Bottom" name="MiniMap">
<Property key="NeedMouse" value="false"/>
<Property key="CanvasSize" value="1536 1536"/>
<Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="ALIGN_BOTTOM ALIGN_LEFT" name="Compass">
<Property key="ImageTexture" value="textures\compass.dds"/>
</Widget>
<Widget type="Button" skin="" position="0 0 1536 1536" name="MiniMapButton" align="Right Bottom">
</Widget>
</Widget>
</Widget>
</Widget>

Loading…
Cancel
Save