summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/animatedsprite.cpp17
-rw-r--r--src/animation.cpp20
-rw-r--r--src/animation.h16
-rw-r--r--src/engine.cpp104
-rw-r--r--src/engine.h5
-rw-r--r--src/floor_item.cpp5
-rw-r--r--src/floor_item.h1
-rw-r--r--src/game.cpp29
-rw-r--r--src/gui/char_select.cpp5
-rw-r--r--src/gui/char_select.h5
-rw-r--r--src/gui/chat.cpp2
-rw-r--r--src/gui/equipmentwindow.cpp9
-rw-r--r--src/gui/equipmentwindow.h3
-rw-r--r--src/gui/gui.cpp10
-rw-r--r--src/gui/itemcontainer.cpp21
-rw-r--r--src/gui/itemcontainer.h2
-rw-r--r--src/gui/ministatus.cpp42
-rw-r--r--src/gui/ministatus.h10
-rw-r--r--src/gui/setup.cpp4
-rw-r--r--src/gui/setup_joystick.cpp57
-rw-r--r--src/gui/setup_joystick.h6
-rw-r--r--src/gui/setup_video.cpp78
-rw-r--r--src/gui/setup_video.h16
-rw-r--r--src/gui/window.cpp21
-rw-r--r--src/gui/window.h20
-rw-r--r--src/joystick.cpp20
-rw-r--r--src/joystick.h39
-rw-r--r--src/main.cpp25
-rw-r--r--src/map.cpp113
-rw-r--r--src/map.h30
-rw-r--r--src/net/inventoryhandler.cpp9
-rw-r--r--src/player.cpp16
-rw-r--r--src/player.h8
-rw-r--r--src/resources/iteminfo.cpp44
-rw-r--r--src/resources/iteminfo.h16
-rw-r--r--src/resources/itemmanager.cpp12
-rw-r--r--src/resources/mapreader.cpp27
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)
diff --git a/src/map.h b/src/map.h
index a91b815f..317a0b59 100644
--- a/src/map.h
+++ b/src/map.h
@@ -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;
}