diff options
author | Andrei Karas <akaras@inbox.ru> | 2011-01-02 01:48:38 +0200 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2011-01-02 02:41:24 +0200 |
commit | 3eeae12c498d1a4dbe969462d2ba841f77ee3ccb (patch) | |
tree | ff8eab35e732bc0749fc11677c8873a7b3a58704 /src/gui/minimap.cpp | |
download | mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.gz mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.bz2 mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.xz mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.zip |
Initial commit.
This code based on mana client http://www.gitorious.org/mana/mana
and my private repository.
Diffstat (limited to 'src/gui/minimap.cpp')
-rw-r--r-- | src/gui/minimap.cpp | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp new file mode 100644 index 000000000..6edefcfdd --- /dev/null +++ b/src/gui/minimap.cpp @@ -0,0 +1,292 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/minimap.h" + +#include "actorspritemanager.h" +#include "being.h" +#include "configuration.h" +#include "graphics.h" +#include "localplayer.h" +#include "log.h" +#include "map.h" + +#include "gui/userpalette.h" +#include "gui/setup.h" +#include "gui/viewport.h" + +#include "resources/image.h" +#include "resources/resourcemanager.h" + +#include "utils/gettext.h" + +#include <guichan/font.hpp> + +bool Minimap::mShow = true; + +Minimap::Minimap(): + Window(_("Map")), + mMapImage(0), + mWidthProportion(0.5), + mHeightProportion(0.5) +{ + setWindowName("Minimap"); + mShow = config.getValueBool(getWindowName() + "Show", true); + setDefaultSize(5, 25, 100, 100); + // set this to false as the minimap window size is changed + //depending on the map size + setResizable(false); + setupWindow->registerWindowForReset(this); + + setDefaultVisible(true); + setSaveVisible(true); + + setStickyButton(true); + setSticky(false); + + loadWindowState(); + setVisible(mShow, isSticky()); +} + +Minimap::~Minimap() +{ + config.setValue(getWindowName() + "Show", mShow); + + if (mMapImage) + mMapImage->decRef(); +} + +void Minimap::setMap(Map *map) +{ + std::string caption = ""; + std::string minimapName; + + if (map) + caption = map->getName(); + + if (caption.empty()) + caption = _("Map"); + + setCaption(caption); + + // Adapt the image + if (mMapImage) + { + mMapImage->decRef(); + mMapImage = 0; + } + + if (map) + { + std::string tempname = + "graphics/minimaps/" + map->getFilename() + ".png"; + ResourceManager *resman = ResourceManager::getInstance(); + + minimapName = map->getProperty("minimap"); + + if (minimapName.empty() && resman->exists(tempname)) + minimapName = tempname; + + mMapImage = resman->getImage(minimapName); + } + + if (mMapImage && map) + { + const int offsetX = 2 * getPadding(); + const int offsetY = getTitleBarHeight() + getPadding(); + const int titleWidth = getFont()->getWidth(getCaption()) + 15; + const int mapWidth = mMapImage->getWidth() < 100 ? + mMapImage->getWidth() + offsetX : 100; + const int mapHeight = mMapImage->getHeight() < 100 ? + mMapImage->getHeight() + offsetY : 100; + + setMinWidth(mapWidth > titleWidth ? mapWidth : titleWidth); + setMinHeight(mapHeight); + + mWidthProportion = static_cast<float>( + mMapImage->getWidth()) / static_cast<float>(map->getWidth()); + mHeightProportion = static_cast<float>( + mMapImage->getHeight()) / static_cast<float>(map->getHeight()); + + setMaxWidth(mMapImage->getWidth() > titleWidth ? + mMapImage->getWidth() + offsetX : titleWidth); + setMaxHeight(mMapImage->getHeight() + offsetY); + + setDefaultSize(getX(), getY(), getWidth(), getHeight()); + resetToDefaultSize(); + + if (mShow) + setVisible(true); + } + else + { + if (!isSticky()) + setVisible(false); + } +} + +void Minimap::toggle() +{ + setVisible(!isVisible(), isSticky()); + mShow = isVisible(); +} + +void Minimap::draw(gcn::Graphics *graphics) +{ + Window::draw(graphics); + + if (!userPalette || !player_node || !viewport) + return; + + Graphics *graph = static_cast<Graphics*>(graphics); + + const gcn::Rectangle a = getChildrenArea(); + + graphics->pushClipArea(a); + + int mapOriginX = 0; + int mapOriginY = 0; + + if (mMapImage) + { + if (mMapImage->getWidth() > a.width || + mMapImage->getHeight() > a.height) + { + const Vector &p = player_node->getPosition(); + mapOriginX = ((a.width) / 2) - static_cast<int>((p.x + + viewport->getCameraRelativeX()) * mWidthProportion) / 32; + mapOriginY = ((a.height) / 2) - static_cast<int>((p.y + + viewport->getCameraRelativeX()) * mHeightProportion) / 32; + + const int minOriginX = a.width - mMapImage->getWidth(); + const int minOriginY = a.height - mMapImage->getHeight(); + + if (mapOriginX < minOriginX) + mapOriginX = minOriginX; + if (mapOriginY < minOriginY) + mapOriginY = minOriginY; + if (mapOriginX > 0) + mapOriginX = 0; + if (mapOriginY > 0) + mapOriginY = 0; + } + + graph->drawImage(mMapImage, mapOriginX, mapOriginY); + } + + if (!actorSpriteManager) + return; + + const ActorSprites &actors = actorSpriteManager->getAll(); + + for (ActorSpritesConstIterator it = actors.begin(), it_end = actors.end(); + it != it_end; it++) + { + if (!(*it) || (*it)->getType() == ActorSprite::FLOOR_ITEM) + continue; + + const Being *being = static_cast<Being*>(*it); + if (!being) + continue; + + int dotSize = 2; + + int type = UserPalette::PC; + + if (being == player_node) + { + type = UserPalette::SELF; + dotSize = 3; + } + else if (being->isGM()) + { + type = UserPalette::GM; + } + else if (being->isInParty()) + { + type = UserPalette::PARTY; + } + else if (being) + { + switch (being->getType()) + { + case ActorSprite::MONSTER: + type = UserPalette::MONSTER; + break; + + case ActorSprite::NPC: + type = UserPalette::NPC; + break; + + default: + continue; + } + } + + if (userPalette) + graphics->setColor(userPalette->getColor(type)); + + const int offsetHeight = static_cast<int>(static_cast<float>( + dotSize - 1) * mHeightProportion); + const int offsetWidth = static_cast<int>(static_cast<float>( + dotSize - 1) * mWidthProportion); + const Vector &pos = being->getPosition(); + + graphics->fillRectangle(gcn::Rectangle( + static_cast<int>(pos.x * mWidthProportion) / 32 + + mapOriginX - offsetWidth, + static_cast<int>(pos.y * mHeightProportion) / 32 + + mapOriginY - offsetHeight, + dotSize, dotSize)); + } + + const Vector &pos = player_node->getPosition(); +// logger->log("width:" + toString(graph->getWidth())); + + int x = static_cast<int>((pos.x - (graph->getWidth() / 2) + + viewport->getCameraRelativeX()) + * mWidthProportion) / 32 + mapOriginX; + int y = static_cast<int>((pos.y - (graph->getHeight() / 2) + + viewport->getCameraRelativeY()) + * mHeightProportion) / 32 + mapOriginY; + + const int w = graph->getWidth() * mWidthProportion / 32; + const int h = graph->getHeight() * mHeightProportion / 32; + + if (w <= a.width) + { + if (x < 0 && w) + x = 0; + if (x + w > a.width) + x = a.width - w; + } + if (h <= a.height) + { + if (y < 0 && h) + y = 0; + if (y + h > a.height) + y = a.height - h; + } + + graphics->setColor(userPalette->getColor(UserPalette::PC)); + graphics->drawRectangle(gcn::Rectangle(x, y, w, h)); + graphics->popClipArea(); +} |