diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2006-08-28 23:04:08 +0000 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2006-08-28 23:04:08 +0000 |
commit | 391203d83ed7a72b54fb7d7c72dbe35db14f0ea9 (patch) | |
tree | a9a9e14bbbdde0b48c66b99038d505a42a51609b /src | |
parent | af61e1e7df91b97c3f7516e9eb2b37b621f069ad (diff) | |
download | mana-client-391203d83ed7a72b54fb7d7c72dbe35db14f0ea9.tar.gz mana-client-391203d83ed7a72b54fb7d7c72dbe35db14f0ea9.tar.bz2 mana-client-391203d83ed7a72b54fb7d7c72dbe35db14f0ea9.tar.xz mana-client-391203d83ed7a72b54fb7d7c72dbe35db14f0ea9.zip |
Merged trunk development between revisions 2530 and 2618 to the 0.1.0 branch.
Diffstat (limited to 'src')
38 files changed, 730 insertions, 138 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index aac3a8d3..1e8a1424 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -158,6 +158,7 @@ tmw_SOURCES = graphic/imagerect.h \ resources/imagewriter.cpp \ resources/imagewriter.h \ resources/iteminfo.h \ + resources/iteminfo.cpp \ resources/itemmanager.cpp \ resources/itemmanager.h \ resources/mapreader.cpp \ diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp index 8f9c0600..f984d13f 100644 --- a/src/animatedsprite.cpp +++ b/src/animatedsprite.cpp @@ -49,12 +49,14 @@ AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant): free(data); if (!doc) { - logger->error("Animation: Error while parsing animation definition file!"); + logger->error( + "Animation: Error while parsing animation definition file!"); } xmlNodePtr node = xmlDocGetRootElement(doc); if (!node || !xmlStrEqual(node->name, BAD_CAST "sprite")) { - logger->error("Animation: this is not a valid animation definition file!"); + logger->error( + "Animation: this is not a valid animation definition file!"); } // Get the variant @@ -233,13 +235,14 @@ AnimatedSprite::~AnimatedSprite() void AnimatedSprite::reset() { - // Reset all defined actions (because of aliases, some will be resetted - // multiple times) + // Reset all defined actions (because of aliases some will be resetted + // multiple times, but this doesn't matter) for (ActionIterator i = mActions.begin(); i != mActions.end(); ++i) { - //TODO: If resetting everything is really a nice way of fixing the - // synchronization issues, finish implementing this. - //i->second->reset(); + if (i->second) + { + i->second->reset(); + } } } diff --git a/src/animation.cpp b/src/animation.cpp index 1213d0d6..c1b27ebd 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -27,9 +27,15 @@ #include "utils/dtor.h" -Animation::Animation(): - mTime(0) +Animation::Animation() { + reset(); +} + +void +Animation::reset() +{ + mTime = 0; iCurrentPhase = mAnimationPhases.begin(); } @@ -123,3 +129,13 @@ Action::setAnimation(int direction, Animation *animation) mAnimations[direction] = animation; } + +void +Action::reset() +{ + for (AnimationIterator i = mAnimations.begin(); + i != mAnimations.end(); ++i) + { + i->second->reset(); + } +} diff --git a/src/animation.h b/src/animation.h index c5b277b7..60dcd287 100644 --- a/src/animation.h +++ b/src/animation.h @@ -55,6 +55,12 @@ class Animation */ Animation(); + /** + * Restarts the animation from the first frame. + */ + void + reset(); + void addPhase(int image, unsigned int delay, int offsetX, int offsetY); @@ -68,13 +74,13 @@ class Animation * Returns the x offset of the current frame. */ int - getOffsetX() const { return (*iCurrentPhase).offsetX; }; + getOffsetX() const { return iCurrentPhase->offsetX; }; /** * Returns the y offset of the current frame. */ int - getOffsetY() const { return (*iCurrentPhase).offsetY; }; + getOffsetY() const { return iCurrentPhase->offsetY; }; /** * Returns the length of this animation. @@ -119,6 +125,12 @@ class Action void setAnimation(int direction, Animation *animation); + /** + * Resets all animations associated with this action. + */ + void + reset(); + Animation* getAnimation(int direction) const; diff --git a/src/engine.cpp b/src/engine.cpp index eda154f3..28410748 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -27,6 +27,7 @@ #include "being.h" #include "beingmanager.h" +#include "configuration.h" #include "flooritemmanager.h" #include "game.h" #include "graphics.h" @@ -54,7 +55,6 @@ int camera_x, camera_y; ItemManager *itemDb; /**< Item database object */ -Spriteset *itemset; Spriteset *emotionset; Spriteset *npcset; std::vector<Spriteset *> weaponset; @@ -79,11 +79,9 @@ Engine::Engine(): weaponset.push_back(tmp); } } - itemset = resman->getSpriteset("graphics/sprites/items.png", 32, 32); if (!npcset) logger->error("Unable to load NPC spriteset!"); if (!emotionset) logger->error("Unable to load emotions spriteset!"); - if (!itemset) logger->error("Unable to load item spriteset!"); // Initialize item manager itemDb = new ItemManager(); @@ -94,7 +92,6 @@ Engine::~Engine() // Delete sprite sets npcset->decRef(); emotionset->decRef(); - itemset->decRef(); std::for_each(weaponset.begin(), weaponset.end(), std::mem_fun(&Spriteset::decRef)); @@ -157,34 +154,85 @@ void Engine::draw(Graphics *graphics) { int midTileX = graphics->getWidth() / 2; int midTileY = graphics->getHeight() / 2; + static int lastTick = tick_time; - int map_x = (player_node->mX - midTileX) + player_node->getXOffset(); - int map_y = (player_node->mY - midTileY) + player_node->getYOffset(); + // Avoid freaking out when tick_time overflows + if (tick_time < lastTick) + { + lastTick = tick_time; + } + + int player_x = player_node->mX - midTileX + player_node->getXOffset(); + int player_y = player_node->mY - midTileY + player_node->getYOffset(); + + scrollLaziness = (int)config.getValue("ScrollLaziness", 32); + scrollRadius = (int)config.getValue("ScrollRadius", 32); + + if (scrollLaziness < 1) + scrollLaziness = 1; //avoids division by zero + + //apply lazy scrolling + while (lastTick < tick_time) + { + if (player_x > view_x + scrollRadius) + { + view_x += (player_x - view_x - scrollRadius) / scrollLaziness; + } + if (player_x < view_x - scrollRadius) + { + view_x += (player_x - view_x + scrollRadius) / scrollLaziness; + } + if (player_y > view_y + scrollRadius) + { + view_y += (player_y - view_y - scrollRadius) / scrollLaziness; + } + if (player_y < view_y - scrollRadius) + { + view_y += (player_y - view_y + scrollRadius) / scrollLaziness; + } + lastTick++; + } + + //auto center when player is off screen + if ( player_x - view_x > graphics->getWidth() / 2 + || view_x - player_x > graphics->getWidth() / 2 + || view_y - player_y > graphics->getHeight() / 2 + || player_y - view_y > graphics->getHeight() / 2 + ) + { + view_x = player_x; + view_y = player_y; + }; if (mCurrentMap) { - if (map_x < 0) { - map_x = 0; + if (view_x < 0) { + view_x = 0; } - if (map_y < 0) { - map_y = 0; + if (view_y < 0) { + view_y = 0; } - if (map_x > mCurrentMap->getWidth() * 32 - midTileX) { - map_x = mCurrentMap->getWidth() * 32 - midTileX; + if (view_x > mCurrentMap->getWidth() * 32 - midTileX) { + view_x = mCurrentMap->getWidth() * 32 - midTileX; } - if (map_y > mCurrentMap->getHeight() * 32 - midTileY) { - map_y = mCurrentMap->getHeight() * 32 - midTileY; + if (view_y > mCurrentMap->getHeight() * 32 - midTileY) { + view_y = mCurrentMap->getHeight() * 32 - midTileY; } } - camera_x = map_x; - camera_y = map_y; + camera_x = (int)(view_x + 16); + camera_y = (int)(view_y + 16); // Draw tiles and sprites if (mCurrentMap != NULL) { - mCurrentMap->draw(graphics, map_x, map_y, 0); - mCurrentMap->draw(graphics, map_x, map_y, 1); - mCurrentMap->draw(graphics, map_x, map_y, 2); + mCurrentMap->draw(graphics, (int)view_x, (int)view_y, 0); + mCurrentMap->draw(graphics, (int)view_x, (int)view_y, 1); + mCurrentMap->draw(graphics, (int)view_x, (int)view_y, 2); + mCurrentMap->drawOverlay( graphics, + view_x, + view_y, + (int)config.getValue("OverlayDetail", 2) + ); } else { @@ -202,8 +250,8 @@ void Engine::draw(Graphics *graphics) int mouseX, mouseY; SDL_GetMouseState(&mouseX, &mouseY); - int mouseTileX = (mouseX + map_x) / 32; - int mouseTileY = (mouseY + map_y) / 32; + int mouseTileX = (int)(mouseX + view_x) / 32; + int mouseTileY = (int)(mouseY + view_y) / 32; Path debugPath = mCurrentMap->findPath( player_node->mX / 32, player_node->mY / 32, @@ -212,8 +260,8 @@ void Engine::draw(Graphics *graphics) graphics->setColor(gcn::Color(255, 0, 0)); for (PathIterator i = debugPath.begin(); i != debugPath.end(); i++) { - int squareX = i->x * 32 - map_x + 12; - int squareY = i->y * 32 - map_y + 12; + int squareX = i->x * 32 - int(view_x) + 12; + int squareY = i->y * 32 - int(view_y) + 12; graphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8)); graphics->drawText( @@ -226,9 +274,9 @@ void Engine::draw(Graphics *graphics) Beings *beings = beingManager->getAll(); for (BeingIterator i = beings->begin(); i != beings->end(); i++) { - (*i)->drawSpeech(graphics, -map_x, -map_y); - (*i)->drawName(graphics, -map_x, -map_y); - (*i)->drawEmotion(graphics, -map_x, -map_y); + (*i)->drawSpeech(graphics, -(int)view_x, -(int)view_y); + (*i)->drawName(graphics, -(int)view_x, -(int)view_y); + (*i)->drawEmotion(graphics, -(int)view_x, -(int)view_y); } // Draw target marker if needed @@ -239,8 +287,8 @@ void Engine::draw(Graphics *graphics) graphics->setColor(gcn::Color(255, 255, 255)); int dy = (target->getType() == Being::PLAYER) ? 90 : 52; - graphics->drawText("[TARGET]", target->getPixelX() - map_x + 15, - target->getPixelY() - map_y - dy, gcn::Graphics::CENTER); + graphics->drawText("[TARGET]", target->getPixelX() - (int)view_x + 15, + target->getPixelY() - (int)view_y - dy, gcn::Graphics::CENTER); } gui->draw(); diff --git a/src/engine.h b/src/engine.h index bdf8419a..e8ef7e33 100644 --- a/src/engine.h +++ b/src/engine.h @@ -76,6 +76,11 @@ class Engine bool mShowDebugPath; Map *mCurrentMap; + + int scrollRadius; + int scrollLaziness; + float view_x; // current viewpoint in pixels + float view_y; // current viewpoint in pixels }; extern Engine *engine; diff --git a/src/floor_item.cpp b/src/floor_item.cpp index 1581b201..edd5d4a7 100644 --- a/src/floor_item.cpp +++ b/src/floor_item.cpp @@ -29,7 +29,6 @@ #include "resources/iteminfo.h" #include "resources/spriteset.h" -extern Spriteset *itemset; FloorItem::FloorItem(unsigned int id, unsigned int itemId, @@ -42,8 +41,8 @@ FloorItem::FloorItem(unsigned int id, mY(y), mMap(map) { - // Retrieve item image using a global itemset and itemDb (alternative?) - mImage = itemset->get(itemDb->getItemInfo(itemId)->getImage() - 1); + // Retrieve item image from item info + mImage = itemDb->getItemInfo(itemId)->getImage(); // Add ourselves to the map mSpriteIterator = mMap->addSprite(this); diff --git a/src/floor_item.h b/src/floor_item.h index 24eb495d..386d0759 100644 --- a/src/floor_item.h +++ b/src/floor_item.h @@ -27,6 +27,7 @@ #include "graphics.h" #include "map.h" #include "sprite.h" +#include "resources/image.h" /** * An item lying on the floor. diff --git a/src/game.cpp b/src/game.cpp index 3e789728..f5ebe095 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -202,6 +202,10 @@ void createGuiWindows() minimap->getHeight() + 30);*/ // Set initial window visibility + chatWindow->setSticky(true); + miniStatusWindow->setSticky(true); + menuWindow->setSticky(true); + chatWindow->setVisible(true); miniStatusWindow->setVisible(true); statusWindow->setVisible(false); @@ -457,7 +461,30 @@ void Game::handleInput() } break; - // Picking up items on the floor + // Attempt to hide all windows + case SDLK_h: + chatWindow->setVisible(false); + miniStatusWindow->setVisible(false); + statusWindow->setVisible(false); + menuWindow->setVisible(false); + buyDialog->setVisible(false); + sellDialog->setVisible(false); + buySellDialog->setVisible(false); + inventoryWindow->setVisible(false); + npcTextDialog->setVisible(false); + npcListDialog->setVisible(false); + skillDialog->setVisible(false); + //newSkillWindow->setVisible(false); + setupWindow->setVisible(false); + equipmentWindow->setVisible(false); + chargeDialog->setVisible(false); + tradeWindow->setVisible(false); + //buddyWindow->setVisible(false); + helpWindow->setVisible(false); + debugWindow->setVisible(false); + break; + + // Picking up items on the floor case SDLK_g: case SDLK_z: if (!chatWindow->isFocused()) diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index adcbe290..042a5be8 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -224,6 +224,11 @@ void CharSelectDialog::logic() updatePlayerInfo(); } +std::string CharSelectDialog::getName() +{ + return mNameLabel->getCaption(); +} + CharCreateDialog::CharCreateDialog(Window *parent, int slot): Window("Create Character", true, parent), mSlot(slot) { diff --git a/src/gui/char_select.h b/src/gui/char_select.h index 73fc8b2d..06881bb5 100644 --- a/src/gui/char_select.h +++ b/src/gui/char_select.h @@ -54,6 +54,11 @@ class CharSelectDialog : public Window, public gcn::ActionListener void logic(); + /** + * Returns name of selected player + */ + std::string getName(); + private: LockedArray<LocalPlayer*> *mCharInfo; diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 9098f9f0..9a5d60b0 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -395,7 +395,7 @@ ChatWindow::setInputText(std::string input_str) void ChatWindow::setVisible(bool isVisible) { - Widget::setVisible(isVisible); + Window::setVisible(isVisible); /* * For whatever reason, if setVisible is called, the mTmpVisible effect diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index bef39dff..2cbffde4 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -40,15 +40,10 @@ EquipmentWindow::EquipmentWindow(Equipment *equipment): setWindowName("Equipment"); setDefaultSize(5, 230, 200, 120); loadWindowState(); - - mItemset = ResourceManager::getInstance()->getSpriteset( - "graphics/sprites/items.png", 32, 32); - if (!mItemset) logger->error("Unable to load items.png"); } EquipmentWindow::~EquipmentWindow() { - mItemset->decRef(); } void EquipmentWindow::draw(gcn::Graphics *graphics) @@ -70,7 +65,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) continue; } - image = mItemset->get(item->getInfo()->getImage() - 1); + image = item->getInfo()->getImage(); dynamic_cast<Graphics*>(graphics)->drawImage( image, 36 * (i % 4) + 10, 36 * (i / 4) + 25); } @@ -81,7 +76,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) return; } - image = mItemset->get(item->getInfo()->getImage() - 1); + image = item->getInfo()->getImage(); dynamic_cast<Graphics*>(graphics)->drawImage(image, 160, 25); graphics->drawText(toString(item->getQuantity()), 170, 62, diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h index aeaae58c..99a3cc60 100644 --- a/src/gui/equipmentwindow.h +++ b/src/gui/equipmentwindow.h @@ -27,7 +27,6 @@ #include "window.h" class Equipment; -class Spriteset; /** * Equipment dialog. @@ -53,8 +52,6 @@ class EquipmentWindow : public Window void draw(gcn::Graphics *graphics); private: - Spriteset *mItemset; - Equipment *mEquipment; }; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 69563dc1..b27868e3 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -27,11 +27,13 @@ #include <guichan/image.hpp> #include <guichan/imagefont.hpp> - -// Moved up because of nested inclusion of winnt.h which defines DELETE -// constant as well as guichan does +// Should stay here because of Guichan being sensitive to headers order #include <guichan/sdl/sdlinput.hpp> +#ifdef USE_OPENGL +#include "../resources/openglsdlimageloader.h" +#endif + #include "focushandler.h" #include "popupmenu.h" #include "window.h" @@ -231,6 +233,7 @@ Gui::draw() void Gui::mousePress(int mx, int my, int button) { + printf("Gui::mousePress(%d,%d)\n", mx, my); // Mouse pressed on window container (basically, the map) // Are we in-game yet? @@ -247,6 +250,7 @@ Gui::mousePress(int mx, int my, int button) int tilex = (mx + camera_x) / 32; int tiley = (my + camera_y) / 32; + printf("tilex,tiley: %d,%d\n", tilex, tiley); // Right click might open a popup if (button == gcn::MouseInput::RIGHT) diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index edcf9764..c7c55fd9 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -41,8 +41,6 @@ ItemContainer::ItemContainer(Inventory *inventory): mInventory(inventory) { ResourceManager *resman = ResourceManager::getInstance(); - mItemset = resman->getSpriteset("graphics/sprites/items.png", 32, 32); - if (!mItemset) logger->error("Unable to load items.png"); mSelImg = resman->getImage("graphics/gui/selection.png"); if (!mSelImg) logger->error("Unable to load selection.png"); @@ -55,7 +53,6 @@ ItemContainer::ItemContainer(Inventory *inventory): ItemContainer::~ItemContainer() { - mItemset->decRef(); mSelImg->decRef(); } @@ -73,8 +70,8 @@ void ItemContainer::logic() void ItemContainer::draw(gcn::Graphics* graphics) { - int gridWidth = mItemset->get(0)->getWidth() + 4; - int gridHeight = mItemset->get(0)->getHeight() + 10; + int gridWidth = 36; //(item icon width + 4) + int gridHeight = 42; //(item icon height + 10) int columns = getWidth() / gridWidth; // Have at least 1 column @@ -113,11 +110,11 @@ void ItemContainer::draw(gcn::Graphics* graphics) } // Draw item icon - int idx; - if ((idx = item->getInfo()->getImage()) > 0) + Image* image; + if ((image = item->getInfo()->getImage()) != NULL) { dynamic_cast<Graphics*>(graphics)->drawImage( - mItemset->get(idx - 1), itemX, itemY); + image, itemX, itemY); } // Draw item caption @@ -133,8 +130,8 @@ void ItemContainer::setWidth(int width) { gcn::Widget::setWidth(width); - int gridWidth = mItemset->get(0)->getWidth() + 4; - int gridHeight = mItemset->get(0)->getHeight() + 14; + int gridWidth = 36; //item icon width + 4 + int gridHeight = 46; //item icon height + 14 int columns = getWidth() / gridWidth; if (columns < 1) @@ -158,8 +155,8 @@ void ItemContainer::selectNone() void ItemContainer::mousePress(int mx, int my, int button) { - int gridWidth = mItemset->get(0)->getWidth() + 4; - int gridHeight = mItemset->get(0)->getHeight() + 10; + int gridWidth = 36; //(item icon width + 4) + int gridHeight = 42; //(item icon height + 10) int columns = getWidth() / gridWidth; if (button == gcn::MouseInput::LEFT || gcn::MouseInput::RIGHT) diff --git a/src/gui/itemcontainer.h b/src/gui/itemcontainer.h index 63e8bf47..f52f37ec 100644 --- a/src/gui/itemcontainer.h +++ b/src/gui/itemcontainer.h @@ -30,7 +30,6 @@ class Image; class Inventory; class Item; -class Spriteset; /** * An item container. Used to show items in inventory and trade dialog. @@ -83,7 +82,6 @@ class ItemContainer : public gcn::Widget, public gcn::MouseListener private: Inventory *mInventory; - Spriteset *mItemset; Image *mSelImg; Item *mSelectedItem; diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp index 53849550..932b1f22 100644 --- a/src/gui/ministatus.cpp +++ b/src/gui/ministatus.cpp @@ -29,6 +29,8 @@ #include "progressbar.h" #include "../localplayer.h" +#include "../configuration.h" +#include "../graphics.h" #include "../utils/tostring.h" @@ -42,31 +44,40 @@ MiniStatusWindow::MiniStatusWindow(): mHpBar = new ProgressBar(1.0f, 100, 20, 0, 171, 34); mMpBar = new ProgressBar(1.0f, 100, 20, 26, 102, 230); + mXpBar = new ProgressBar(1.0f, 100, 20, 143, 192, 211); mHpLabel = new gcn::Label(""); mMpLabel = new gcn::Label(""); + mXpLabel = new gcn::Label(""); mHpBar->setPosition(0, 3); mMpBar->setPosition(mHpBar->getWidth() + 3, 3); + mXpBar->setPosition(mMpBar->getX() + mMpBar->getWidth() + 3, 3); mHpLabel->setDimension(mHpBar->getDimension()); mMpLabel->setDimension(mMpBar->getDimension()); + mXpLabel->setDimension(mXpBar->getDimension()); mHpLabel->setForegroundColor(gcn::Color(255, 255, 255)); mMpLabel->setForegroundColor(gcn::Color(255, 255, 255)); + mXpLabel->setForegroundColor(gcn::Color(255, 255, 255)); mHpLabel->setFont(speechFont); mMpLabel->setFont(speechFont); + mXpLabel->setFont(speechFont); mHpLabel->setAlignment(gcn::Graphics::CENTER); mMpLabel->setAlignment(gcn::Graphics::CENTER); + mXpLabel->setAlignment(gcn::Graphics::CENTER); add(mHpBar); add(mMpBar); + add(mXpBar); add(mHpLabel); add(mMpLabel); + add(mXpLabel); - setDefaultSize(0, 0, mMpBar->getX() + mMpBar->getWidth(), - mMpBar->getY() + mMpBar->getHeight()); + setDefaultSize(0, 0, mXpBar->getX() + mXpBar->getWidth(), + mXpBar->getY() + mXpBar->getHeight()); } void MiniStatusWindow::update() @@ -85,12 +96,33 @@ void MiniStatusWindow::update() mHpBar->setColor(0, 171, 34); // Green } - mHpBar->setProgress((float)player_node->mHp / (float)player_node->mMaxHp); - // mpBar->setProgress((float)player_node->mp / (float)player_node->maxMp); + mHpBar->setProgress((float) player_node->mHp / player_node->mMaxHp); + // mMpBar->setProgress((float) player_node->mMp / player_node->mMaxMp); + mXpBar->setProgress((float) player_node->mXp / player_node->mXpForNextLevel); - // Update and center labels + // Update labels mHpLabel->setCaption(toString(player_node->mHp)); mMpLabel->setCaption(toString(player_node->mMp)); + + std::stringstream updatedText; + updatedText << (int) ( + (float) player_node->mXp / + player_node->mXpForNextLevel * 100) << "%"; + + // Displays the number of monsters to next lvl + // (disabled for now but interesting idea) + /* + if(config.getValue("xpBarMonsterCounterExp", 0)!=0) + { + updatedText << " | " + << (int)(((float)player_node->mXpForNextLevel - (float)player_node->mXp) + / (float)config.getValue("xpBarMonsterCounterExp", 0)) + << " " + << config.getValue("xpBarMonsterCounterName", "Monsters") <<" left..."; + } + */ + + mXpLabel->setCaption(updatedText.str()); } void MiniStatusWindow::draw(gcn::Graphics *graphics) diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h index f56f847c..718fe140 100644 --- a/src/gui/ministatus.h +++ b/src/gui/ministatus.h @@ -56,11 +56,15 @@ class MiniStatusWindow : public Window */ void update(); - /** + /* * Mini Status Bars */ - ProgressBar *mHpBar, *mMpBar; - gcn::Label *mHpLabel, *mMpLabel; + ProgressBar *mHpBar; + ProgressBar *mMpBar; + ProgressBar *mXpBar; + gcn::Label *mHpLabel; + gcn::Label *mMpLabel; + gcn::Label *mXpLabel; }; #endif diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp index 6af9119b..d12ace75 100644 --- a/src/gui/setup.cpp +++ b/src/gui/setup.cpp @@ -43,7 +43,7 @@ Setup::Setup(): Window("Setup") { int width = 230; - int height = 185; + int height = 225; setContentSize(width, height); const char *buttonNames[] = { @@ -58,7 +58,7 @@ Setup::Setup(): } TabbedContainer *panel = new TabbedContainer(); - panel->setDimension(gcn::Rectangle(5, 5, 220, 150)); + panel->setDimension(gcn::Rectangle(5, 5, 220, 185)); panel->setOpaque(false); SetupTab *tab; diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp index 36b0ee20..d9212728 100644 --- a/src/gui/setup_joystick.cpp +++ b/src/gui/setup_joystick.cpp @@ -26,22 +26,31 @@ #include <guichan/widgets/label.hpp> #include "button.h" - +#include "checkbox.h" +#include "../configuration.h" #include "../joystick.h" extern Joystick *joystick; Setup_Joystick::Setup_Joystick(): mCalibrateLabel(new gcn::Label("Press the button to start calibration")), - mCalibrateButton(new Button("Calibrate", "calibrate", this)) + mCalibrateButton(new Button("Calibrate", "calibrate", this)), + mJoystickEnabled(new CheckBox("Enable joystick")) { setOpaque(false); + mJoystickEnabled->setPosition(10, 10); + mCalibrateLabel->setPosition(10, 25); + mCalibrateButton->setPosition(10, 30 + mCalibrateLabel->getHeight()); + + mOriginalJoystickEnabled = (joystick ? joystick->isEnabled() : false); + mJoystickEnabled->setMarked(mOriginalJoystickEnabled); - mCalibrateLabel->setPosition(5, 10); - mCalibrateButton->setPosition(10, 20 + mCalibrateLabel->getHeight()); + mJoystickEnabled->setEventId("joystickEnabled"); + mJoystickEnabled->addActionListener(this); add(mCalibrateLabel); add(mCalibrateButton); + add(mJoystickEnabled); } void Setup_Joystick::action(const std::string &event, gcn::Widget *widget) @@ -50,13 +59,37 @@ void Setup_Joystick::action(const std::string &event, gcn::Widget *widget) return; } - if (joystick->isCalibrating()) { - mCalibrateButton->setCaption("Calibrate"); - mCalibrateLabel->setCaption("Press the button to start calibration"); - joystick->finishCalibration(); - } else { - mCalibrateButton->setCaption("Stop"); - mCalibrateLabel->setCaption("Rotate the stick"); - joystick->startCalibration(); + if (event == "joystickEnabled") + { + joystick->setEnabled(mJoystickEnabled->isMarked()); + } + else + { + if (joystick->isCalibrating()) { + mCalibrateButton->setCaption("Calibrate"); + mCalibrateLabel->setCaption( + "Press the button to start calibration"); + joystick->finishCalibration(); + } else { + mCalibrateButton->setCaption("Stop"); + mCalibrateLabel->setCaption("Rotate the stick"); + joystick->startCalibration(); + } } } + +void Setup_Joystick::cancel() +{ + if (joystick) + { + joystick->setEnabled(mOriginalJoystickEnabled); + } + mJoystickEnabled->setMarked(mOriginalJoystickEnabled); +} + +void Setup_Joystick::apply() +{ + config.setValue("joystickEnabled", + joystick ? joystick->isEnabled() : false); +} + diff --git a/src/gui/setup_joystick.h b/src/gui/setup_joystick.h index da773c8f..4cc2b3d9 100644 --- a/src/gui/setup_joystick.h +++ b/src/gui/setup_joystick.h @@ -35,14 +35,16 @@ class Setup_Joystick : public SetupTab, public gcn::ActionListener public: Setup_Joystick(); - void apply() {} - void cancel() {} + void apply(); + void cancel(); void action(const std::string& eventId, gcn::Widget* widget); private: gcn::Label *mCalibrateLabel; gcn::Button *mCalibrateButton; + bool mOriginalJoystickEnabled; + gcn::CheckBox *mJoystickEnabled; }; #endif diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index 7ac226d3..7c72975a 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -115,7 +115,13 @@ Setup_Video::Setup_Video(): mAlphaSlider(new Slider(0.2, 1.0)), mFpsCheckBox(new CheckBox("FPS Limit: ")), mFpsSlider(new Slider(10, 200)), - mFpsField(new TextField()) + mFpsField(new TextField()), + mOriginalScrollLaziness((int) config.getValue("ScrollLaziness", 32)), + mScrollLazinessSlider(new Slider(1, 64)), + mScrollLazinessField(new TextField()), + mOriginalScrollRadius((int) config.getValue("ScrollRadius", 32)), + mScrollRadiusSlider(new Slider(0, 128)), + mScrollRadiusField(new TextField()) { setOpaque(false); @@ -153,12 +159,36 @@ Setup_Video::Setup_Video(): mAlphaSlider->setEventId("guialpha"); mFpsCheckBox->setEventId("fpslimitcheckbox"); mFpsSlider->setEventId("fpslimitslider"); + mScrollRadiusSlider->setEventId("scrollradiusslider"); + mScrollRadiusField->setEventId("scrollradiusfield"); + mScrollLazinessSlider->setEventId("scrolllazinessslider"); + mScrollLazinessField->setEventId("scrolllazinessfield"); mCustomCursorCheckBox->addActionListener(this); mAlphaSlider->addActionListener(this); mFpsCheckBox->addActionListener(this); mFpsSlider->addActionListener(this); mFpsField->addKeyListener(this); + mScrollRadiusSlider->addActionListener(this); + mScrollRadiusField->addKeyListener(this); + mScrollLazinessSlider->addActionListener(this); + mScrollLazinessField->addKeyListener(this); + + mScrollRadiusSlider->setDimension(gcn::Rectangle(10, 120, 75, 10)); + gcn::Label *scrollRadiusLabel = new gcn::Label("Scroll radius"); + scrollRadiusLabel->setPosition(90, 120); + mScrollRadiusField->setPosition(180, 120); + mScrollRadiusField->setWidth(30); + mScrollRadiusField->setText(toString(mOriginalScrollRadius)); + mScrollRadiusSlider->setValue(mOriginalScrollRadius); + + mScrollLazinessSlider->setDimension(gcn::Rectangle(10, 140, 75, 10)); + gcn::Label *scrollLazinessLabel = new gcn::Label("Scroll laziness"); + scrollLazinessLabel->setPosition(90, 140); + mScrollLazinessField->setPosition(180, 140); + mScrollLazinessField->setWidth(30); + mScrollLazinessField->setText(toString(mOriginalScrollLaziness)); + mScrollLazinessSlider->setValue(mOriginalScrollLaziness); add(scrollArea); add(mFsCheckBox); @@ -169,6 +199,12 @@ Setup_Video::Setup_Video(): add(mFpsCheckBox); add(mFpsSlider); add(mFpsField); + add(mScrollRadiusSlider); + add(scrollRadiusLabel); + add(mScrollRadiusField); + add(mScrollLazinessSlider); + add(scrollLazinessLabel); + add(mScrollLazinessField); } Setup_Video::~Setup_Video() @@ -225,6 +261,27 @@ void Setup_Video::apply() mOpenGLEnabled = config.getValue("opengl", 0); } +int +Setup_Video::updateSlider(gcn::Slider *slider, gcn::TextField *field, + const std::string &configName) +{ + int value; + std::stringstream temp(field->getText()); + temp >> value; + if (value < slider->getScaleStart()) + { + value = (int) slider->getScaleStart(); + } + else if (value > slider->getScaleEnd()) + { + value = (int) slider->getScaleEnd(); + } + field->setText(toString(value)); + slider->setValue(value); + config.setValue(configName, value); + return value; +} + void Setup_Video::cancel() { mFsCheckBox->setMarked(mFullScreenEnabled); @@ -232,6 +289,11 @@ void Setup_Video::cancel() mCustomCursorCheckBox->setMarked(mCustomCursorEnabled); mAlphaSlider->setValue(mOpacity); + mScrollRadiusField->setText(toString(mOriginalScrollRadius)); + mScrollLazinessField->setText(toString(mOriginalScrollLaziness)); + updateSlider(mScrollRadiusSlider, mScrollRadiusField, "ScrollRadius"); + updateSlider(mScrollLazinessSlider, mScrollLazinessField, "ScrollLaziness"); + config.setValue("screen", mFullScreenEnabled ? 1 : 0); config.setValue("customcursor", mCustomCursorEnabled ? 1 : 0); config.setValue("guialpha", mOpacity); @@ -254,6 +316,18 @@ void Setup_Video::action(const std::string &event, gcn::Widget *widget) mFps = (int)mFpsSlider->getValue(); mFpsField->setText(toString(mFps)); } + else if (event == "scrollradiusslider") + { + int val = (int)mScrollRadiusSlider->getValue(); + mScrollRadiusField->setText(toString(val)); + config.setValue("ScrollRadius", val); + } + else if (event == "scrolllazinessslider") + { + int val = (int)mScrollLazinessSlider->getValue(); + mScrollLazinessField->setText(toString(val)); + config.setValue("ScrollLaziness", val); + } else if (event == "fpslimitcheckbox") { if (mFpsCheckBox->isMarked()) @@ -293,4 +367,6 @@ void Setup_Video::keyPress(const gcn::Key &key) mFpsField->setText(""); mFps = 0; } + updateSlider(mScrollRadiusSlider, mScrollRadiusField, "ScrollRadius"); + updateSlider(mScrollLazinessSlider, mScrollLazinessField, "ScrollLaziness"); } diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h index d0a10925..a3fd8884 100644 --- a/src/gui/setup_video.h +++ b/src/gui/setup_video.h @@ -59,10 +59,26 @@ class Setup_Video : public SetupTab, public gcn::ActionListener, gcn::CheckBox *mFsCheckBox; gcn::CheckBox *mOpenGLCheckBox; gcn::CheckBox *mCustomCursorCheckBox; + gcn::Slider *mAlphaSlider; gcn::CheckBox *mFpsCheckBox; gcn::Slider *mFpsSlider; gcn::TextField *mFpsField; + + int mOriginalScrollLaziness; + gcn::Slider *mScrollLazinessSlider; + gcn::TextField *mScrollLazinessField; + + int mOriginalScrollRadius; + gcn::Slider *mScrollRadiusSlider; + gcn::TextField *mScrollRadiusField; + + void + updateSliders(bool originalValues); + + int + updateSlider(gcn::Slider *slider, gcn::TextField *field, + const std::string &configName); }; #endif diff --git a/src/gui/window.cpp b/src/gui/window.cpp index 9a07111f..2172baa8 100644 --- a/src/gui/window.cpp +++ b/src/gui/window.cpp @@ -63,6 +63,7 @@ Window::Window(const std::string& caption, bool modal, Window *parent): mModal(modal), mResizable(false), mMouseResize(false), + mSticky(false), mMinWinWidth(100), mMinWinHeight(28), mMaxWinWidth(INT_MAX), @@ -243,6 +244,26 @@ bool Window::isResizable() return mResizable; } +void Window::setSticky(bool sticky) +{ + mSticky = sticky; +} + +bool Window::isSticky() { + return mSticky; +} + +void Window::setVisible(bool visible) { + if(isSticky()) + { + gcn::Window::setVisible(true); + } + else + { + gcn::Window::setVisible(visible); + } +} + void Window::scheduleDelete() { windowContainer->scheduleDelete(this); diff --git a/src/gui/window.h b/src/gui/window.h index 42ce444c..51c876e3 100644 --- a/src/gui/window.h +++ b/src/gui/window.h @@ -134,6 +134,25 @@ class Window : public gcn::Window void setMaxHeight(unsigned int height); /** + * Sets whether the window is sticky. + * A sticky window will not have its visibility set to false + * on a general setVisible(false) call. + */ + void setSticky(bool sticky); + + /** + * Returns whether the window is sticky. + */ + bool isSticky(); + + /** + * Overloads window setVisible by guichan to allow sticky window + * Handling + */ + + void setVisible(bool visible); + + /** * Returns the parent window. * * @return The parent window or <code>NULL</code> if there is none. @@ -204,6 +223,7 @@ class Window : public gcn::Window bool mModal; /**< Window is modal */ bool mResizable; /**< Window can be resized */ bool mMouseResize; /**< Window is being resized */ + bool mSticky; /**< Window resists minimzation */ int mMinWinWidth; /**< Minimum window width */ int mMinWinHeight; /**< Minimum window height */ int mMaxWinWidth; /**< Maximum window width */ diff --git a/src/joystick.cpp b/src/joystick.cpp index bb6e887b..a5dab4f4 100644 --- a/src/joystick.cpp +++ b/src/joystick.cpp @@ -59,10 +59,11 @@ Joystick::Joystick(int no): logger->log("Hats: %i", SDL_JoystickNumHats(mJoystick)); logger->log("Buttons: %i", SDL_JoystickNumButtons(mJoystick)); - mUpTolerance = (int)config.getValue("upTolerance", 100); - mDownTolerance = (int)config.getValue("downTolerance", 100); - mLeftTolerance = (int)config.getValue("leftTolerance", 100); - mRightTolerance = (int)config.getValue("rightTolerance", 100); + mEnabled = (int) config.getValue("joystickEnabled", 0) != 0; + mUpTolerance = (int) config.getValue("upTolerance", 100); + mDownTolerance = (int) config.getValue("downTolerance", 100); + mLeftTolerance = (int) config.getValue("leftTolerance", 100); + mRightTolerance = (int) config.getValue("rightTolerance", 100); } Joystick::~Joystick() @@ -73,6 +74,7 @@ Joystick::~Joystick() void Joystick::update() { mDirection = 0; + SDL_JoystickUpdate(); // When calibrating, don't bother the outside with our state @@ -81,6 +83,8 @@ void Joystick::update() return; }; + if (!mEnabled) return; + // X-Axis int position = SDL_JoystickGetAxis(mJoystick, 0); if (position >= mRightTolerance) @@ -144,7 +148,6 @@ void Joystick::doCalibration() } } - void Joystick::finishCalibration() { config.setValue("leftTolerance", mLeftTolerance); @@ -154,10 +157,7 @@ void Joystick::finishCalibration() mCalibrating = false; } -bool Joystick::buttonPressed(unsigned char no) +bool Joystick::buttonPressed(unsigned char no) const { - if (no > MAX_BUTTONS) - return false; - - return mButtons[no]; + return (no < MAX_BUTTONS) ? mButtons[no] : false; } diff --git a/src/joystick.h b/src/joystick.h index ebdfabeb..f0759add 100644 --- a/src/joystick.h +++ b/src/joystick.h @@ -30,12 +30,12 @@ class Joystick { public: /** - * Number of buttons we can handle + * Number of buttons we can handle. */ static const unsigned char MAX_BUTTONS = 6; /** - * Directions, to be used as bitmask values + * Directions, to be used as bitmask values. */ static const char UP = 1; static const char DOWN = 2; @@ -43,12 +43,12 @@ class Joystick static const char RIGHT = 8; /** - * Initializes the joystick subsystem + * Initializes the joystick subsystem. */ static void init(); /** - * Returns the number of available joysticks + * Returns the number of available joysticks. */ static int getNumberOfJoysticks() { return joystickCount; } @@ -60,21 +60,33 @@ class Joystick ~Joystick(); + bool + isEnabled() const { return mEnabled; } + + void + setEnabled(bool enabled) { mEnabled = enabled; } + /** * Updates the direction and button information. */ - void update(); + void + update(); + + void + startCalibration(); + + void + finishCalibration(); - void startCalibration(); - void finishCalibration(); - bool isCalibrating() { return mCalibrating; }; + bool + isCalibrating() const { return mCalibrating; } - bool buttonPressed(unsigned char no); + bool buttonPressed(unsigned char no) const; - bool isUp() { return mDirection & UP; }; - bool isDown() { return mDirection & DOWN; }; - bool isLeft() { return mDirection & LEFT; }; - bool isRight() { return mDirection & RIGHT; }; + bool isUp() const { return mDirection & UP; }; + bool isDown() const { return mDirection & DOWN; }; + bool isLeft() const { return mDirection & LEFT; }; + bool isRight() const { return mDirection & RIGHT; }; protected: unsigned char mDirection; @@ -83,6 +95,7 @@ class Joystick int mUpTolerance, mDownTolerance, mLeftTolerance, mRightTolerance; bool mCalibrating; + bool mEnabled; static int joystickCount; diff --git a/src/main.cpp b/src/main.cpp index 573b1a79..f540dacd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -330,6 +330,7 @@ struct Options bool chooseDefault; std::string username; std::string password; + std::string playername; }; void printHelp() @@ -341,13 +342,14 @@ void printHelp() << " -u --skipupdate : Skip the update process" << std::endl << " -U --username : Login with this username" << std::endl << " -P --password : Login with this password" << std::endl - << " -D --default : Bypass the login process with default settings" + << " -D --default : Bypass the login process with default settings" << std::endl + << " -p --playername : Login with this player" << std::endl; } void parseOptions(int argc, char *argv[], Options &options) { - const char *optstring = "huU:P:D"; + const char *optstring = "huU:P:Dp:"; const struct option long_options[] = { { "help", no_argument, 0, 'h' }, @@ -355,6 +357,7 @@ void parseOptions(int argc, char *argv[], Options &options) { "username", required_argument, 0, 'U' }, { "password", required_argument, 0, 'P' }, { "default", no_argument, 0, 'D' }, + { "playername", required_argument, 0, 'p' }, { 0 } }; @@ -382,6 +385,9 @@ void parseOptions(int argc, char *argv[], Options &options) case 'D': options.chooseDefault = true; break; + case 'p': + options.playername = optarg; + break; } } } @@ -668,7 +674,20 @@ int main(int argc, char *argv[]) case STATE_CHAR_SELECT: logger->log("State: CHAR_SELECT"); currentDialog = new CharSelectDialog(&charInfo); - if (options.chooseDefault) { + if (options.playername != "") { + n_character = 0; + while (((CharSelectDialog*) currentDialog)->getName() + != options.playername && + n_character < MAX_SLOT + 1) + { + ((CharSelectDialog*) currentDialog)->action("next", + NULL); + ((CharSelectDialog*) currentDialog)->updatePlayerInfo(); + n_character++; + } + n_character = MAX_SLOT + 1; + } + if (options.chooseDefault || options.playername != "") { ((CharSelectDialog*)currentDialog)->action("ok", NULL); } diff --git a/src/map.cpp b/src/map.cpp index 1b2ce1e8..cbebc41c 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -60,7 +60,8 @@ struct Location Map::Map(int width, int height, int tileWidth, int tileHeight): mWidth(width), mHeight(height), mTileWidth(tileWidth), mTileHeight(tileHeight), - mOnClosedList(1), mOnOpenList(2) + mOnClosedList(1), mOnOpenList(2), + mLastScrollX(0.0f), mLastScrollY(0.0f) { mMetaTiles = new MetaTile[mWidth * mHeight]; mTiles = new Image*[mWidth * mHeight * 3]; @@ -68,12 +69,18 @@ Map::Map(int width, int height, int tileWidth, int tileHeight): Map::~Map() { + // clean up map data delete[] mMetaTiles; delete[] mTiles; - - // Clean up tilesets + // clean up tilesets for_each(mTilesets.begin(), mTilesets.end(), make_dtor(mTilesets)); mTilesets.clear(); + // clean up overlays + std::list<AmbientOverlay>::iterator i; + for (i = mOverlays.begin(); i != mOverlays.end(); i++) + { + (*i).image->decRef(); + } } void @@ -160,6 +167,106 @@ Map::draw(Graphics *graphics, int scrollX, int scrollY, int layer) } void +Map::drawOverlay(Graphics *graphics, float scrollX, float scrollY, int detail) +{ + static int lastTick = tick_time; + + // detail 0: no overlays + if (detail <= 0) return; + + std::list<AmbientOverlay>::iterator i; + + // Avoid freaking out when tick_time overflows + if (tick_time < lastTick) + { + lastTick = tick_time; + } + + if (mLastScrollX == 0.0f && mLastScrollY == 0.0f) + { + // first call - initialisation + mLastScrollX = scrollX; + mLastScrollY = scrollY; + } + + //update Overlays + while (lastTick < tick_time) + { + for (i = mOverlays.begin(); i != mOverlays.end(); i++) + { + if ((*i).image != NULL) + { + //apply self scrolling + (*i).scrollX -= (*i).scrollSpeedX; + (*i).scrollY -= (*i).scrollSpeedY; + + //apply parallaxing + (*i).scrollX += (scrollX - mLastScrollX) * (*i).parallax; + (*i).scrollY += (scrollY - mLastScrollY) * (*i).parallax; + + //keep the image pattern on the screen + while ((*i).scrollX > (*i).image->getWidth()) + { + (*i).scrollX -= (*i).image->getWidth(); + } + while ((*i).scrollY > (*i).image->getHeight()) + { + (*i).scrollY -= (*i).image->getHeight(); + } + while ((*i).scrollX < 0) + { + (*i).scrollX += (*i).image->getWidth(); + } + while ((*i).scrollY < 0) + { + (*i).scrollY += (*i).image->getHeight(); + } + } + } + mLastScrollX = scrollX; + mLastScrollY = scrollY; + lastTick++; + + // detail 1: only one overlay, higher: all overlays + if (detail == 1) break; + } + + //draw overlays + for (i = mOverlays.begin(); i != mOverlays.end(); i++) + { + if ((*i).image != NULL) + { + graphics->drawImagePattern ( (*i).image, + 0 - (int)(*i).scrollX, + 0 - (int)(*i).scrollY, + graphics->getWidth() + (int)(*i).scrollX, + graphics->getHeight() + (int)(*i).scrollY + ); + }; + // detail 1: only one overlay, higher: all overlays + if (detail == 1) break; + }; +} + +void +Map::setOverlay(Image *image, float speedX, float speedY, float parallax) +{ + if (image != NULL) + { + AmbientOverlay newOverlay; + + newOverlay.image = image; + newOverlay.parallax = parallax; + newOverlay.scrollSpeedX = speedX; + newOverlay.scrollSpeedY = speedY; + newOverlay.scrollX = 0; + newOverlay.scrollY = 0; + + mOverlays.push_back(newOverlay); + } +} + +void Map::setTileWithGid(int x, int y, int layer, int gid) { if (layer == 3) @@ -41,6 +41,8 @@ typedef Tilesets::iterator TilesetIterator; typedef std::list<Sprite*> Sprites; typedef Sprites::iterator SpriteIterator; +extern volatile int tick_time; + /** * A meta tile stores additional information about a location on a tile map. * This is information that doesn't need to be repeated for each tile in each @@ -63,6 +65,16 @@ struct MetaTile bool walkable; /**< Can beings walk on this tile */ }; +struct AmbientOverlay +{ + Image *image; + float parallax; + float scrollX; + float scrollY; + float scrollSpeedX; + float scrollSpeedY; +}; + /** * A tile map. */ @@ -80,11 +92,21 @@ class Map : public Properties ~Map(); /** - * Draws the map to the given graphics output. + * Draws a map layer to the given graphics output. */ void draw(Graphics *graphics, int scrollX, int scrollY, int layer); /** + * Sets Overlay Graphic and Scrollspeed + */ + void setOverlay(Image *image, float speedX, float speedY, float parallax); + + /** + * Draws the overlay graphic to the given graphics output. + */ + void drawOverlay(Graphics *graphics, float scrollX, float scrollY, int detail); + + /** * Sets the size of the map. This will destroy any existing map data. */ void setSize(int width, int height); @@ -198,6 +220,12 @@ class Map : public Properties // Pathfinding members int mOnClosedList, mOnOpenList; + + //overlay Data + AmbientOverlay mFoo; + std::list<AmbientOverlay> mOverlays; + float mLastScrollX; + float mLastScrollY; }; #endif diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp index cb1883b0..c4192bc5 100644 --- a/src/net/inventoryhandler.cpp +++ b/src/net/inventoryhandler.cpp @@ -28,6 +28,7 @@ #include "messagein.h" #include "protocol.h" +#include "../resources/iteminfo.h" #include "../item.h" #include "../localplayer.h" @@ -91,6 +92,14 @@ void InventoryHandler::handleMessage(MessageIn &msg) if (msg.readByte()> 0) { chatWindow->chatLog("Unable to pick up item", BY_SERVER); } else { + ItemInfo *itemInfo = itemDb->getItemInfo(itemId); + if (itemInfo) { + chatWindow->chatLog("You picked up a " + + itemInfo->getName(), BY_SERVER); + } else { + chatWindow->chatLog("You picked up an unknown item", + BY_SERVER); + } player_node->addInvItem(index, itemId, amount, equipType != 0); } break; diff --git a/src/player.cpp b/src/player.cpp index b635397e..af9a3344 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -84,6 +84,7 @@ Player::setSex(Uint8 sex) } Being::setSex(sex); + resetAnimations(); } } @@ -99,6 +100,7 @@ Player::setHairColor(Uint16 color) newHairSprite->setDirection(getSpriteDirection()); mSprites[HAIR_SPRITE] = newHairSprite; + resetAnimations(); setAction(mAction); } @@ -118,6 +120,7 @@ Player::setHairStyle(Uint16 style) newHairSprite->setDirection(getSpriteDirection()); mSprites[HAIR_SPRITE] = newHairSprite; + resetAnimations(); setAction(mAction); } @@ -155,6 +158,7 @@ Player::setVisibleEquipment(Uint8 slot, Uint8 id) equipmentSprite->setDirection(getSpriteDirection()); mSprites[position] = equipmentSprite; + resetAnimations(); setAction(mAction); } @@ -162,4 +166,14 @@ Player::setVisibleEquipment(Uint8 slot, Uint8 id) Being::setVisibleEquipment(slot, id); } - +void +Player::resetAnimations() +{ + for (int i = 0; i < VECTOREND_SPRITE; i++) + { + if (mSprites[i] != NULL) + { + mSprites[i]->reset(); + } + } +} diff --git a/src/player.h b/src/player.h index d0d55cc8..65b0303d 100644 --- a/src/player.h +++ b/src/player.h @@ -57,6 +57,14 @@ class Player : public Being virtual void setVisibleEquipment(Uint8 slot, Uint8 id); + + private: + /** + * Resets all animations associated with this player. This is used to + * synchronize the animations after a new one has been added. + */ + void + resetAnimations(); }; #endif diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp new file mode 100644 index 00000000..5d39d832 --- /dev/null +++ b/src/resources/iteminfo.cpp @@ -0,0 +1,44 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "iteminfo.h" + +#include "resourcemanager.h" + +Image* +ItemInfo::getImage() { + if (mImage == NULL && mImageName != "") { + mImage = ResourceManager::getInstance()->getImage(mImageName); + } + return mImage; +} + +void +ItemInfo::setImage(const std::string &image) { + mImageName = "graphics/items/" + image; +} + +ItemInfo::~ItemInfo() { + if (mImage != NULL){ + mImage->decRef(); + } +} diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index 54e7907b..afa2e857 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -26,6 +26,8 @@ #include <string> +#include "image.h" + /** * Defines a class for storing item infos. */ @@ -38,7 +40,8 @@ class ItemInfo * Constructor. */ ItemInfo(): - mImage(0), + mImage(NULL), + mImageName(""), mArt(0), mType(0), mWeight(0), @@ -59,10 +62,10 @@ class ItemInfo getName() { return mName; } void - setImage(short image) { mImage = image; } + setImage(const std::string &image); - short - getImage() { return mImage; } + Image* + getImage(); void setDescription(const std::string &description) @@ -101,9 +104,10 @@ class ItemInfo /** * Destructor. */ - ~ItemInfo() {} + ~ItemInfo(); - short mImage; + Image* mImage; + std::string mImageName; short mArt; std::string mName; std::string mDescription; diff --git a/src/resources/itemmanager.cpp b/src/resources/itemmanager.cpp index 63c0b036..a497b3c8 100644 --- a/src/resources/itemmanager.cpp +++ b/src/resources/itemmanager.cpp @@ -68,8 +68,8 @@ ItemManager::ItemManager() for (node = node->xmlChildrenNode; node != NULL; node = node->next) { - int id = 0, image = 0, art = 0, type = 0, weight = 0, slot = 0; - std::string name = "", description = "", effect = ""; + int id = 0, art = 0, type = 0, weight = 0, slot = 0; + std::string name = "", description = "", effect = "", image = ""; if (!xmlStrEqual(node->name, BAD_CAST "item")) { continue; @@ -77,7 +77,7 @@ ItemManager::ItemManager() xmlChar *prop = NULL; READ_PROP(node, prop, "id", id, atoi); - READ_PROP(node, prop, "image", image, atoi); + READ_PROP(node, prop, "image", image, ); READ_PROP(node, prop, "art", art, atoi); READ_PROP(node, prop, "name", name, ); READ_PROP(node, prop, "description", description, ); @@ -86,6 +86,7 @@ ItemManager::ItemManager() READ_PROP(node, prop, "weight", weight, atoi); READ_PROP(node, prop, "slot", slot, atoi); + if (id && name != "") { ItemInfo *itemInfo = new ItemInfo(); @@ -100,6 +101,7 @@ ItemManager::ItemManager() mItemInfos[id] = itemInfo; } + if (id == 0) { logger->log("Item Manager: An item has no ID in items.xml!"); @@ -109,7 +111,7 @@ ItemManager::ItemManager() logger->log("Item Manager: An item has no name in items.xml!"); } - if (image == 0) + if (image == "") { logger->log("Item Manager: Missing image parameter for item: %i. %s", id, name.c_str()); @@ -141,7 +143,7 @@ ItemManager::ItemManager() } if (slot == 0) { - logger->log("Item Manager: Missing image parameter for item: %i. %s", + logger->log("Item Manager: Missing slot parameter for item: %i. %s", id, name.c_str()); } diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp index 382b0797..c1ae911c 100644 --- a/src/resources/mapreader.cpp +++ b/src/resources/mapreader.cpp @@ -34,6 +34,7 @@ #include "../map.h" #include "../tileset.h" +#include "../utils/tostring.h" const unsigned int DEFAULT_TILE_WIDTH = 32; const unsigned int DEFAULT_TILE_HEIGHT = 32; @@ -213,6 +214,32 @@ MapReader::readMap(xmlNodePtr node, const std::string &path) } } + //set Overlays + int i = 0; + ResourceManager *resman = ResourceManager::getInstance(); + + while (map->hasProperty("overlay" + toString(i) + "image")) + { + Image *overlayImage = resman->getImage(map->getProperty("overlay" + toString(i) + "image")); + float scrollX = 0.0f; + float scrollY = 0.0f; + float parallax = 0.0f; + if (map->hasProperty("overlay" + toString(i) + "scrollX")) + { + scrollX = atof(map->getProperty("overlay" + toString(i) + "scrollX").c_str()); + } + if (map->hasProperty("overlay" + toString(i) + "scrollY")) + { + scrollY = atof(map->getProperty("overlay" + toString(i) + "scrollY").c_str()); + } + if (map->hasProperty("overlay" + toString(i) + "parallax")) + { + parallax = atof(map->getProperty("overlay" + toString(i) + "parallax").c_str()); + } + map->setOverlay (overlayImage, scrollX, scrollY, parallax); + i++; + } + return map; } |