summaryrefslogtreecommitdiff
path: root/src/gui/minimap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/minimap.cpp')
-rw-r--r--src/gui/minimap.cpp292
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();
+}