From 1e4aa6a5e7476bea736b89fe5d7094b6a68705e5 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 25 Oct 2012 01:13:56 +0300 Subject: Add support for different hover/pickup cursors for monsters, npc, items, etc. In monsters.xml new monster attribute: hoverCursor - default value "attack". In npcs.xml new npc attribute: hoverCursor - default value "talk". In items.xml new item attribute: pickupCursor - default value "pickup". Warps using "up" cursor for now. --- src/CMakeLists.txt | 2 ++ src/Makefile.am | 2 ++ src/being.h | 3 ++ src/flooritem.cpp | 4 ++- src/flooritem.h | 6 ++++ src/gui/gui.cpp | 2 +- src/gui/gui.h | 20 ++----------- src/gui/viewport.cpp | 18 +++++++----- src/gui/widgets/window.cpp | 20 ++++++------- src/resources/beinginfo.cpp | 1 + src/resources/beinginfo.h | 12 ++++++++ src/resources/cursor.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++ src/resources/cursor.h | 60 +++++++++++++++++++++++++++++++++++++++ src/resources/itemdb.cpp | 2 ++ src/resources/iteminfo.cpp | 3 +- src/resources/iteminfo.h | 10 +++++++ src/resources/monsterdb.cpp | 3 ++ src/resources/npcdb.cpp | 9 ++++-- 18 files changed, 204 insertions(+), 41 deletions(-) create mode 100644 src/resources/cursor.cpp create mode 100644 src/resources/cursor.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8ea242ee9..96ac9e95d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -414,6 +414,8 @@ SET(SRCS resources/chardb.h resources/colordb.cpp resources/colordb.h + resources/cursor.cpp + resources/cursor.h resources/dye.cpp resources/dye.h resources/emotedb.cpp diff --git a/src/Makefile.am b/src/Makefile.am index edf151089..b86617e23 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -416,6 +416,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ resources/chardb.h \ resources/colordb.cpp \ resources/colordb.h \ + resources/cursor.cpp \ + resources/cursor.h \ resources/dye.cpp \ resources/dye.h \ resources/emotedb.cpp \ diff --git a/src/being.h b/src/being.h index a9ccba82e..c7d8c3609 100644 --- a/src/being.h +++ b/src/being.h @@ -843,6 +843,9 @@ class Being : public ActorSprite, public ConfigListener int getHitEffect(const Being *const attacker, const AttackType type, const int attackId) const; + Cursor::Cursor getHoverCursor() + { return mInfo ? mInfo->getHoverCursor() : Cursor::CURSOR_POINTER; } + static uint8_t genderToInt(const Gender sex); static Gender intToGender(uint8_t sex); diff --git a/src/flooritem.cpp b/src/flooritem.cpp index 7826f7855..2a7ca5aed 100644 --- a/src/flooritem.cpp +++ b/src/flooritem.cpp @@ -48,7 +48,8 @@ FloorItem::FloorItem(const int id, const int itemId, const int x, const int y, mPickupCount(0), mColor(color), mShowMsg(true), - mHighlight(config.getBoolValue("floorItemsHighlight")) + mHighlight(config.getBoolValue("floorItemsHighlight")), + mCursor(Cursor::CURSOR_PICKUP) { setMap(map); const ItemInfo &info = ItemDB::get(itemId); @@ -72,6 +73,7 @@ FloorItem::FloorItem(const int id, const int itemId, const int x, const int y, mPos.y = 0; } + mCursor = info.getPickupCursor(); setupSpriteDisplay(info.getDisplay(), true, 1, info.getDyeColorsString(mColor)); mYDiff = 31; diff --git a/src/flooritem.h b/src/flooritem.h index 00cf49aa8..0542d2f11 100644 --- a/src/flooritem.h +++ b/src/flooritem.h @@ -25,6 +25,8 @@ #include "actorsprite.h" +#include "resources/cursor.h" + class ItemInfo; /** @@ -95,6 +97,9 @@ class FloorItem final : public ActorSprite void disableHightlight() { mHighlight = false; } + Cursor::Cursor getHoverCursor() + { return mCursor; } + private: int mItemId; int mX, mY; @@ -107,6 +112,7 @@ class FloorItem final : public ActorSprite unsigned char mColor; bool mShowMsg; bool mHighlight; + Cursor::Cursor mCursor; }; #endif diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 5939345f0..6e78e3ac8 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -82,7 +82,7 @@ Gui::Gui(Graphics *const graphics) : mMouseCursors(nullptr), mMouseCursorAlpha(1.0f), mMouseInactivityTimer(0), - mCursorType(CURSOR_POINTER) + mCursorType(Cursor::CURSOR_POINTER) { logger->log1("Initializing GUI..."); // Set graphics diff --git a/src/gui/gui.h b/src/gui/gui.h index c327a4b81..e8969d666 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -23,6 +23,8 @@ #ifndef GUI_H #define GUI_H +#include "resources/cursor.h" + #include #include "localconsts.h" @@ -139,24 +141,6 @@ class Gui final : public gcn::Gui void getAbsolutePosition(gcn::Widget *widget, int &x, int &y); - /** - * Cursors are in graphic order from left to right. - * CURSOR_POINTER should be left untouched. - * CURSOR_TOTAL should always be last. - */ - enum - { - CURSOR_POINTER = 0, - CURSOR_RESIZE_ACROSS, - CURSOR_RESIZE_DOWN, - CURSOR_RESIZE_DOWN_LEFT, - CURSOR_RESIZE_DOWN_RIGHT, - CURSOR_FIGHT, - CURSOR_PICKUP, - CURSOR_TALK, - CURSOR_TOTAL - }; - protected: void handleMouseMoved(const gcn::MouseInput &mouseInput); diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 42e6473ee..e7d7ab85d 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -788,6 +788,7 @@ void Viewport::mouseMoved(gcn::MouseEvent &event A_UNUSED) if (mTextPopup->isVisible()) mTextPopup->setVisible(false); } + gui->setCursorType(Cursor::CURSOR_UP); return; } } @@ -801,31 +802,34 @@ void Viewport::mouseMoved(gcn::MouseEvent &event A_UNUSED) { // NPCs case ActorSprite::NPC: - gui->setCursorType(Gui::CURSOR_TALK); + gui->setCursorType(mHoverBeing->getHoverCursor()); break; // Monsters case ActorSprite::MONSTER: - gui->setCursorType(Gui::CURSOR_FIGHT); + gui->setCursorType(mHoverBeing->getHoverCursor()); break; + case ActorSprite::PORTAL: + gui->setCursorType(mHoverBeing->getHoverCursor()); + break; + + case ActorSprite::FLOOR_ITEM: case ActorSprite::UNKNOWN: case ActorSprite::PLAYER: - case ActorSprite::FLOOR_ITEM: - case ActorSprite::PORTAL: default: - gui->setCursorType(Gui::CURSOR_POINTER); + gui->setCursorType(Cursor::CURSOR_POINTER); break; } } // Item mouseover else if (mHoverItem) { - gui->setCursorType(Gui::CURSOR_PICKUP); + gui->setCursorType(mHoverItem->getHoverCursor()); } else { - gui->setCursorType(Gui::CURSOR_POINTER); + gui->setCursorType(Cursor::CURSOR_POINTER); } } diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 9128402ad..1a6eb334c 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -131,7 +131,7 @@ Window::Window(const std::string &caption, const bool modal, if (mModal) { - gui->setCursorType(Gui::CURSOR_POINTER); + gui->setCursorType(Cursor::CURSOR_POINTER); requestModalFocus(); } @@ -443,7 +443,7 @@ void Window::widgetMoved(const gcn::Event& event A_UNUSED) void Window::widgetHidden(const gcn::Event &event A_UNUSED) { if (gui) - gui->setCursorType(Gui::CURSOR_POINTER); + gui->setCursorType(Cursor::CURSOR_POINTER); if (!mFocusHandler) return; @@ -587,7 +587,7 @@ void Window::mouseReleased(gcn::MouseEvent &event A_UNUSED) { mouseResize = 0; if (gui) - gui->setCursorType(Gui::CURSOR_POINTER); + gui->setCursorType(Cursor::CURSOR_POINTER); } // This should be the responsibility of Guichan (and is from 0.8.0 on) @@ -602,7 +602,7 @@ void Window::mouseEntered(gcn::MouseEvent &event) void Window::mouseExited(gcn::MouseEvent &event A_UNUSED) { if (mGrip && !mouseResize && gui) - gui->setCursorType(Gui::CURSOR_POINTER); + gui->setCursorType(Cursor::CURSOR_POINTER); } void Window::updateResizeHandler(gcn::MouseEvent &event) @@ -617,22 +617,22 @@ void Window::updateResizeHandler(gcn::MouseEvent &event) { case BOTTOM | RIGHT: case TOP | LEFT: - gui->setCursorType(Gui::CURSOR_RESIZE_DOWN_RIGHT); + gui->setCursorType(Cursor::CURSOR_RESIZE_DOWN_RIGHT); break; case TOP | RIGHT: case BOTTOM | LEFT: - gui->setCursorType(Gui::CURSOR_RESIZE_DOWN_LEFT); + gui->setCursorType(Cursor::CURSOR_RESIZE_DOWN_LEFT); break; case BOTTOM: case TOP: - gui->setCursorType(Gui::CURSOR_RESIZE_DOWN); + gui->setCursorType(Cursor::CURSOR_RESIZE_DOWN); break; case RIGHT: case LEFT: - gui->setCursorType(Gui::CURSOR_RESIZE_ACROSS); + gui->setCursorType(Cursor::CURSOR_RESIZE_ACROSS); break; default: - gui->setCursorType(Gui::CURSOR_POINTER); + gui->setCursorType(Cursor::CURSOR_POINTER); } } @@ -735,7 +735,7 @@ void Window::setModal(bool modal) if (mModal) { if (gui) - gui->setCursorType(Gui::CURSOR_POINTER); + gui->setCursorType(Cursor::CURSOR_POINTER); requestModalFocus(); } else diff --git a/src/resources/beinginfo.cpp b/src/resources/beinginfo.cpp index f55d1f2e3..029e3d40d 100644 --- a/src/resources/beinginfo.cpp +++ b/src/resources/beinginfo.cpp @@ -37,6 +37,7 @@ Attack *BeingInfo::empty = new Attack(SpriteAction::ATTACK, BeingInfo::BeingInfo() : mName(_("unnamed")), mTargetCursorSize(ActorSprite::TC_MEDIUM), + mHoverCursor(Cursor::CURSOR_POINTER), mWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER | Map::BLOCKMASK_MONSTER | Map::BLOCKMASK_AIR | Map::BLOCKMASK_WATER), diff --git a/src/resources/beinginfo.h b/src/resources/beinginfo.h index 8f3d09001..ed73f576a 100644 --- a/src/resources/beinginfo.h +++ b/src/resources/beinginfo.h @@ -25,6 +25,8 @@ #include "actorsprite.h" +#include "resources/cursor.h" + #include #include @@ -104,6 +106,15 @@ class BeingInfo final &targetSize) { mTargetCursorSize = targetSize; } + void setHoverCursor(const std::string &name) + { return setHoverCursor(Cursor::stringToCursor(name)); } + + void setHoverCursor(const Cursor::Cursor &cursor) + { mHoverCursor = cursor; } + + Cursor::Cursor getHoverCursor() + { return mHoverCursor; } + ActorSprite::TargetCursorSize getTargetCursorSize() const { return mTargetCursorSize; } @@ -183,6 +194,7 @@ class BeingInfo final SpriteDisplay mDisplay; std::string mName; ActorSprite::TargetCursorSize mTargetCursorSize; + Cursor::Cursor mHoverCursor; SoundEvents mSounds; Attacks mAttacks; unsigned char mWalkMask; diff --git a/src/resources/cursor.cpp b/src/resources/cursor.cpp new file mode 100644 index 000000000..48e046180 --- /dev/null +++ b/src/resources/cursor.cpp @@ -0,0 +1,68 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus 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 . + */ + +#include "resources/cursor.h" + +namespace Cursor +{ + static StrToCursor hoverCursors[] = + { + {"select", Cursor::CURSOR_POINTER}, + {"pointer", Cursor::CURSOR_POINTER}, + {"lr", Cursor::CURSOR_RESIZE_ACROSS}, + {"rl", Cursor::CURSOR_RESIZE_ACROSS}, + {"resizeAcross", Cursor::CURSOR_RESIZE_ACROSS}, + {"ud", Cursor::CURSOR_RESIZE_DOWN}, + {"du", Cursor::CURSOR_RESIZE_DOWN}, + {"resizeDown", Cursor::CURSOR_RESIZE_DOWN}, + {"ldru", Cursor::CURSOR_RESIZE_DOWN_LEFT}, + {"ruld", Cursor::CURSOR_RESIZE_DOWN_LEFT}, + {"ld", Cursor::CURSOR_RESIZE_DOWN_LEFT}, + {"ru", Cursor::CURSOR_RESIZE_DOWN_LEFT}, + {"resizeDownLeft", Cursor::CURSOR_RESIZE_DOWN_LEFT}, + {"lurd", Cursor::CURSOR_RESIZE_DOWN_RIGHT}, + {"rdlu", Cursor::CURSOR_RESIZE_DOWN_RIGHT}, + {"rd", Cursor::CURSOR_RESIZE_DOWN_RIGHT}, + {"lu", Cursor::CURSOR_RESIZE_DOWN_RIGHT}, + {"resizeDownRight", Cursor::CURSOR_RESIZE_DOWN_RIGHT}, + {"attack", Cursor::CURSOR_FIGHT}, + {"fight", Cursor::CURSOR_FIGHT}, + {"take", Cursor::CURSOR_PICKUP}, + {"pickup", Cursor::CURSOR_PICKUP}, + {"talk", Cursor::CURSOR_TALK}, + {"action", Cursor::CURSOR_ACTION}, + {"left", Cursor::CURSOR_LEFT}, + {"up", Cursor::CURSOR_UP}, + {"right", Cursor::CURSOR_RIGHT}, + {"down", Cursor::CURSOR_DOWN} + }; + + Cursor stringToCursor(const std::string &name) + { + for (size_t f = 0; f < sizeof(hoverCursors) / sizeof(StrToCursor); + f ++) + { + if (hoverCursors[f].str == name) + return hoverCursors[f].cursor; + } + return Cursor::CURSOR_POINTER; + } + +} diff --git a/src/resources/cursor.h b/src/resources/cursor.h new file mode 100644 index 000000000..4ecbb82de --- /dev/null +++ b/src/resources/cursor.h @@ -0,0 +1,60 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus 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 . + */ + +#ifndef CURSOR_H +#define CURSOR_H + +#include + +namespace Cursor +{ + /** + * Cursors are in graphic order from left to right. + * CURSOR_POINTER should be left untouched. + * CURSOR_TOTAL should always be last. + */ + enum Cursor + { + CURSOR_POINTER = 0, + CURSOR_RESIZE_ACROSS, + CURSOR_RESIZE_DOWN, + CURSOR_RESIZE_DOWN_LEFT, + CURSOR_RESIZE_DOWN_RIGHT, + CURSOR_FIGHT, + CURSOR_PICKUP, + CURSOR_TALK, + CURSOR_ACTION, + CURSOR_LEFT, + CURSOR_UP, + CURSOR_RIGHT, + CURSOR_DOWN, + CURSOR_TOTAL + }; + + struct StrToCursor + { + std::string str; + Cursor cursor; + }; + + Cursor stringToCursor(const std::string &name); +} + +#endif diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index f2e07ce48..c6a854c33 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -313,6 +313,8 @@ void ItemDB::load() itemInfo->setDrawPriority(-1, drawPriority); itemInfo->setColorsList(colors); itemInfo->setMaxFloorOffset(maxFloorOffset); + itemInfo->setPickupCursor(XML::getProperty( + node, "pickupCursor", "pickup")); std::string effect; for (size_t i = 0; i < sizeof(fields) / sizeof(fields[0]); ++ i) diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp index c0fb962c7..e7c20aa6f 100644 --- a/src/resources/iteminfo.cpp +++ b/src/resources/iteminfo.cpp @@ -53,7 +53,8 @@ ItemInfo::ItemInfo() : mHitEffectId(-1), mCriticalHitEffectId(-1), mMissEffectId(-1), - maxFloorOffset(32) + maxFloorOffset(32), + mPickupCursor(Cursor::CURSOR_POINTER) { for (int f = 0; f < 10; f ++) { diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index 4e4e9f424..cd832bd9d 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -271,6 +271,15 @@ class ItemInfo final const std::string replaceColors(std::string str, const unsigned char color) const; + void setPickupCursor(const std::string &cursor) + { return setPickupCursor(Cursor::stringToCursor(cursor)); } + + void setPickupCursor(const Cursor::Cursor &cursor) + { mPickupCursor = cursor; } + + Cursor::Cursor getPickupCursor() const + { return mPickupCursor; } + int mDrawBefore[10]; int mDrawAfter[10]; int mDrawPriority[10]; @@ -314,6 +323,7 @@ class ItemInfo final int mCriticalHitEffectId; int mMissEffectId; int maxFloorOffset; + Cursor::Cursor mPickupCursor; }; #endif diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp index ae0d6c3ba..48c14b06a 100644 --- a/src/resources/monsterdb.cpp +++ b/src/resources/monsterdb.cpp @@ -87,6 +87,9 @@ void MonsterDB::load() currentInfo->setTargetCursorSize(XML::getProperty(monsterNode, "targetCursor", "medium")); + currentInfo->setHoverCursor(XML::getProperty(monsterNode, + "hoverCursor", "attack")); + currentInfo->setTargetOffsetX(XML::getProperty(monsterNode, "targetOffsetX", 0)); diff --git a/src/resources/npcdb.cpp b/src/resources/npcdb.cpp index 81a89b611..350695bef 100644 --- a/src/resources/npcdb.cpp +++ b/src/resources/npcdb.cpp @@ -78,13 +78,16 @@ void NPCDB::load() } currentInfo->setTargetCursorSize(XML::getProperty(npcNode, - "targetCursor", "medium")); + "targetCursor", "medium")); + + currentInfo->setHoverCursor(XML::getProperty(npcNode, + "hoverCursor", "talk")); currentInfo->setTargetOffsetX(XML::getProperty(npcNode, - "targetOffsetX", 0)); + "targetOffsetX", 0)); currentInfo->setTargetOffsetY(XML::getProperty(npcNode, - "targetOffsetY", 0)); + "targetOffsetY", 0)); currentInfo->setSortOffsetY(XML::getProperty(npcNode, "sortOffsetY", 0)); -- cgit v1.2.3-70-g09d2