summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIra Rice <irarice@gmail.com>2008-12-07 16:53:32 -0700
committerIra Rice <irarice@gmail.com>2008-12-07 16:53:32 -0700
commitaef082e6fe4fca268f9bfe401409eb342f82e4af (patch)
tree26e9f2f2be9ad59666a4c039c7717e0e5becd3eb /src
parent7f24abc455a407e84f13d75099e36db77fa8931d (diff)
parenta7c21e6f8add37af7412449742ec55c8daa8571a (diff)
downloadmana-aef082e6fe4fca268f9bfe401409eb342f82e4af.tar.gz
mana-aef082e6fe4fca268f9bfe401409eb342f82e4af.tar.bz2
mana-aef082e6fe4fca268f9bfe401409eb342f82e4af.tar.xz
mana-aef082e6fe4fca268f9bfe401409eb342f82e4af.zip
Merge commit 'a7c21e6f8add37af7412449742ec55c8daa8571a'
Conflicts: AUTHORS CMakeLists.txt ChangeLog INSTALL README aethyra.cbp configure.ac data/help/changes.txt data/help/commands.txt data/help/header.txt data/help/support.txt src/Makefile.am src/aethyra.rc src/being.cpp src/being.h src/equipment.cpp src/equipment.h src/floor_item.h src/game.cpp src/gui/buddywindow.cpp src/gui/char_select.cpp src/gui/char_server.cpp src/gui/chat.cpp src/gui/chat.h src/gui/equipmentwindow.cpp src/gui/equipmentwindow.h src/gui/gui.cpp src/gui/inventorywindow.cpp src/gui/inventorywindow.h src/gui/itemcontainer.cpp src/gui/itemcontainer.h src/gui/minimap.cpp src/gui/ministatus.cpp src/gui/newskill.cpp src/gui/npc_text.cpp src/gui/npclistdialog.h src/gui/ok_dialog.cpp src/gui/setup_video.cpp src/gui/skill.cpp src/gui/skill.h src/gui/status.h src/gui/table_model.h src/gui/updatewindow.cpp src/gui/viewport.cpp src/inventory.cpp src/inventory.h src/keyboardconfig.cpp src/keyboardconfig.h src/localplayer.cpp src/localplayer.h src/logindata.h src/main.cpp src/map.cpp src/monster.cpp src/monster.h src/net/beinghandler.cpp src/net/beinghandler.h src/net/buysellhandler.cpp src/net/equipmenthandler.cpp src/net/loginhandler.cpp src/net/loginhandler.h src/net/network.h src/net/npchandler.cpp src/net/playerhandler.cpp src/net/protocol.h src/net/tradehandler.cpp src/npc.cpp src/npc.h src/particleemitter.cpp src/particleemitterprop.h src/player.cpp src/player.h src/player_relations.cpp src/resources/imageset.cpp src/resources/imageset.h src/resources/itemdb.cpp src/resources/mapreader.cpp src/resources/monsterinfo.h src/text.cpp src/text.h src/textmanager.cpp src/textmanager.h src/tileset.h src/utils/fastsqrt.h src/utils/strprintf.cpp src/winver.h tools/tmxcopy/Makefile tools/tmxcopy/base64.cpp tools/tmxcopy/base64.h tools/tmxcopy/tostring.h Signed-off-by: Ira Rice <irarice@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt8
-rw-r--r--src/Makefile.am2
-rwxr-xr-xsrc/SDLMain.h11
-rwxr-xr-xsrc/SDLMain.m383
-rw-r--r--src/aethyra.rc3
-rw-r--r--src/animatedsprite.cpp41
-rw-r--r--src/being.cpp46
-rw-r--r--src/being.h17
-rw-r--r--src/engine.cpp6
-rw-r--r--src/equipment.h16
-rw-r--r--src/floor_item.h2
-rw-r--r--src/game.cpp15
-rw-r--r--src/gui/buddywindow.cpp83
-rw-r--r--src/gui/char_select.cpp2
-rw-r--r--src/gui/char_server.cpp10
-rw-r--r--src/gui/char_server.h3
-rw-r--r--src/gui/chat.cpp58
-rw-r--r--src/gui/equipmentwindow.cpp8
-rw-r--r--src/gui/equipmentwindow.h3
-rw-r--r--src/gui/gui.cpp2
-rw-r--r--src/gui/inventorywindow.cpp4
-rw-r--r--src/gui/itemcontainer.cpp27
-rw-r--r--src/gui/itemcontainer.h15
-rw-r--r--src/gui/itemshortcutcontainer.cpp4
-rw-r--r--src/gui/minimap.cpp4
-rw-r--r--src/gui/newskill.cpp193
-rw-r--r--src/gui/npc_text.cpp1
-rw-r--r--src/gui/npclistdialog.h6
-rw-r--r--src/gui/setup_video.cpp11
-rw-r--r--src/gui/skill.cpp8
-rw-r--r--src/gui/skill.h1
-rw-r--r--src/gui/status.h4
-rw-r--r--src/gui/table_model.h6
-rw-r--r--src/gui/updatewindow.cpp22
-rw-r--r--src/gui/viewport.cpp9
-rw-r--r--src/gui/window.cpp1
-rw-r--r--src/inventory.cpp7
-rw-r--r--src/inventory.h7
-rw-r--r--src/joystick.cpp2
-rw-r--r--src/localplayer.cpp5
-rw-r--r--src/log.h4
-rw-r--r--src/logindata.h2
-rw-r--r--src/main.cpp35
-rw-r--r--src/map.cpp52
-rw-r--r--src/monster.cpp9
-rw-r--r--src/monster.h6
-rw-r--r--src/net/beinghandler.cpp24
-rw-r--r--src/net/buysellhandler.cpp2
-rw-r--r--src/net/charserverhandler.cpp2
-rw-r--r--src/net/equipmenthandler.cpp3
-rw-r--r--src/net/loginhandler.cpp12
-rw-r--r--src/net/loginhandler.h5
-rw-r--r--src/net/network.h6
-rw-r--r--src/net/playerhandler.cpp3
-rw-r--r--src/net/protocol.h1
-rw-r--r--src/net/tradehandler.cpp4
-rw-r--r--src/npc.cpp4
-rw-r--r--src/particlecontainer.cpp177
-rw-r--r--src/particlecontainer.h125
-rw-r--r--src/player.cpp1
-rw-r--r--src/player_relations.cpp6
-rw-r--r--src/resources/colordb.cpp9
-rw-r--r--src/resources/imageset.h6
-rw-r--r--src/resources/mapreader.cpp69
-rw-r--r--src/text.h45
-rw-r--r--src/tileset.h2
-rw-r--r--src/utils/fastsqrt.h48
-rw-r--r--src/winver.h2
68 files changed, 1368 insertions, 352 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4e8654e6..b54c7c6c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -148,6 +148,8 @@ SET(SRCS
gui/setup_joystick.h
gui/setup_keyboard.cpp
gui/setup_keyboard.h
+ gui/setup_players.cpp
+ gui/setup_players.h
gui/setuptab.h
gui/setup_video.cpp
gui/setup_video.h
@@ -165,6 +167,10 @@ SET(SRCS
gui/status.h
gui/tabbedcontainer.cpp
gui/tabbedcontainer.h
+ gui/table.cpp
+ gui/table.h
+ gui/table_model.cpp
+ gui/table_model.h
gui/textbox.cpp
gui/textbox.h
gui/textfield.cpp
@@ -329,6 +335,8 @@ SET(SRCS
particleemitterprop.h
player.cpp
player.h
+ player_relations.cpp
+ player_relations.h
properties.h
serverinfo.h
shopitem.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 75434d8e..507db6f8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -289,6 +289,8 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \
openglgraphics.h \
particle.cpp \
particle.h \
+ particlecontainer.cpp \
+ particlecontainer.h \
particleemitter.cpp \
particleemitter.h \
particleemitterprop.h \
diff --git a/src/SDLMain.h b/src/SDLMain.h
new file mode 100755
index 00000000..4683df57
--- /dev/null
+++ b/src/SDLMain.h
@@ -0,0 +1,11 @@
+/* SDLMain.m - main entry point for our Cocoa-ized SDL app
+ Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
+ Non-NIB-Code & other changes: Max Horn <max@quendi.de>
+
+ Feel free to customize this file to suit your needs
+*/
+
+#import <Cocoa/Cocoa.h>
+
+@interface SDLMain : NSObject
+@end
diff --git a/src/SDLMain.m b/src/SDLMain.m
new file mode 100755
index 00000000..3d02719c
--- /dev/null
+++ b/src/SDLMain.m
@@ -0,0 +1,383 @@
+/* SDLMain.m - main entry point for our Cocoa-ized SDL app
+ Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
+ Non-NIB-Code & other changes: Max Horn <max@quendi.de>
+
+ Feel free to customize this file to suit your needs
+ */
+
+#import "SDL.h"
+#import "SDLMain.h"
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
+ but the method still is there and works. To avoid warnings, we declare
+ it ourselves here. */
+@interface NSApplication(SDL_Missing_Methods)
+- (void)setAppleMenu:(NSMenu *)menu;
+@end
+
+/* Use this flag to determine whether we use SDLMain.nib or not */
+#define SDL_USE_NIB_FILE 0
+
+/* Use this flag to determine whether we use CPS (docking) or not */
+#define SDL_USE_CPS 1
+#ifdef SDL_USE_CPS
+/* Portions of CPS.h */
+typedef struct CPSProcessSerNum
+ {
+ UInt32 lo;
+ UInt32 hi;
+ } CPSProcessSerNum;
+
+extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
+extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
+
+#endif /* SDL_USE_CPS */
+
+static int gArgc;
+static char **gArgv;
+static BOOL gFinderLaunch;
+static BOOL gCalledAppMainline = FALSE;
+
+static NSString *getApplicationName(void)
+{
+ NSDictionary *dict;
+ NSString *appName = 0;
+
+ /* Determine the application name */
+ dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
+ if (dict)
+ appName = [dict objectForKey: @"CFBundleName"];
+
+ if (![appName length])
+ appName = [[NSProcessInfo processInfo] processName];
+
+ return appName;
+}
+
+#if SDL_USE_NIB_FILE
+/* A helper category for NSString */
+@interface NSString (ReplaceSubString)
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
+@end
+#endif
+
+@interface SDLApplication : NSApplication
+@end
+
+@implementation SDLApplication
+/* Invoked from the Quit menu item */
+- (void)terminate:(id)sender
+{
+ /* Post a SDL_QUIT event */
+ SDL_Event event;
+ event.type = SDL_QUIT;
+ SDL_PushEvent(&event);
+}
+@end
+
+/* The main class of the application, the application's delegate */
+@implementation SDLMain
+
+/* Set the working directory to the .app's parent directory */
+- (void) setupWorkingDirectory:(BOOL)shouldChdir
+{
+ if (shouldChdir)
+ {
+ char parentdir[MAXPATHLEN];
+ CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
+ if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
+ assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
+ }
+ CFRelease(url);
+ CFRelease(url2);
+ }
+
+}
+
+#if SDL_USE_NIB_FILE
+
+/* Fix menu to contain the real app name instead of "SDL App" */
+- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
+{
+ NSRange aRange;
+ NSEnumerator *enumerator;
+ NSMenuItem *menuItem;
+
+ aRange = [[aMenu title] rangeOfString:@"SDL App"];
+ if (aRange.length != 0)
+ [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
+
+ enumerator = [[aMenu itemArray] objectEnumerator];
+ while ((menuItem = [enumerator nextObject]))
+ {
+ aRange = [[menuItem title] rangeOfString:@"SDL App"];
+ if (aRange.length != 0)
+ [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
+ if ([menuItem hasSubmenu])
+ [self fixMenu:[menuItem submenu] withAppName:appName];
+ }
+ [ aMenu sizeToFit ];
+}
+
+#else
+
+static void setApplicationMenu(void)
+{
+ /* warning: this code is very odd */
+ NSMenu *appleMenu;
+ NSMenuItem *menuItem;
+ NSString *title;
+ NSString *appName;
+
+ appName = getApplicationName();
+ appleMenu = [[NSMenu alloc] initWithTitle:@""];
+
+ /* Add menu items */
+ title = [@"About " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Hide " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
+
+ menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
+
+ [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ title = [@"Quit " stringByAppendingString:appName];
+ [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
+
+
+ /* Put menu into the menubar */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:appleMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Tell the application object that this is now the application menu */
+ [NSApp setAppleMenu:appleMenu];
+
+ /* Finally give up our references to the objects */
+ [appleMenu release];
+ [menuItem release];
+}
+
+/* Create a window menu */
+static void setupWindowMenu(void)
+{
+ NSMenu *windowMenu;
+ NSMenuItem *windowMenuItem;
+ NSMenuItem *menuItem;
+
+ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+
+ /* "Minimize" item */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+ [windowMenu addItem:menuItem];
+ [menuItem release];
+
+ /* Put menu into the menubar */
+ windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
+ [windowMenuItem setSubmenu:windowMenu];
+ [[NSApp mainMenu] addItem:windowMenuItem];
+
+ /* Tell the application object that this is now the window menu */
+ [NSApp setWindowsMenu:windowMenu];
+
+ /* Finally give up our references to the objects */
+ [windowMenu release];
+ [windowMenuItem release];
+}
+
+/* Replacement for NSApplicationMain */
+static void CustomApplicationMain (int argc, char **argv)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ SDLMain *sdlMain;
+
+ /* Ensure the application object is initialised */
+ [SDLApplication sharedApplication];
+
+#ifdef SDL_USE_CPS
+ {
+ CPSProcessSerNum PSN;
+ /* Tell the dock about us */
+ if (!CPSGetCurrentProcess(&PSN))
+ if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
+ if (!CPSSetFrontProcess(&PSN))
+ [SDLApplication sharedApplication];
+ }
+#endif /* SDL_USE_CPS */
+
+ /* Set up the menubar */
+ [NSApp setMainMenu:[[NSMenu alloc] init]];
+ setApplicationMenu();
+ setupWindowMenu();
+
+ /* Create SDLMain and make it the app delegate */
+ sdlMain = [[SDLMain alloc] init];
+ [NSApp setDelegate:sdlMain];
+
+ /* Start the main event loop */
+ [NSApp run];
+
+ [sdlMain release];
+ [pool release];
+}
+
+#endif
+
+
+/*
+ * Catch document open requests...this lets us notice files when the app
+ * was launched by double-clicking a document, or when a document was
+ * dragged/dropped on the app's icon. You need to have a
+ * CFBundleDocumentsType section in your Info.plist to get this message,
+ * apparently.
+ *
+ * Files are added to gArgv, so to the app, they'll look like command line
+ * arguments. Previously, apps launched from the finder had nothing but
+ * an argv[0].
+ *
+ * This message may be received multiple times to open several docs on launch.
+ *
+ * This message is ignored once the app's mainline has been called.
+ */
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+ const char *temparg;
+ size_t arglen;
+ char *arg;
+ char **newargv;
+
+ if (!gFinderLaunch) /* MacOS is passing command line args. */
+ return FALSE;
+
+ if (gCalledAppMainline) /* app has started, ignore this document. */
+ return FALSE;
+
+ temparg = [filename UTF8String];
+ arglen = SDL_strlen(temparg) + 1;
+ arg = (char *) SDL_malloc(arglen);
+ if (arg == NULL)
+ return FALSE;
+
+ newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
+ if (newargv == NULL)
+ {
+ SDL_free(arg);
+ return FALSE;
+ }
+ gArgv = newargv;
+
+ SDL_strlcpy(arg, temparg, arglen);
+ gArgv[gArgc++] = arg;
+ gArgv[gArgc] = NULL;
+ return TRUE;
+}
+
+
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification *) note
+{
+ int status;
+
+ /* Set the working directory to the .app's parent directory */
+ [self setupWorkingDirectory:gFinderLaunch];
+
+#if SDL_USE_NIB_FILE
+ /* Set the main menu to contain the real app name instead of "SDL App" */
+ [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
+#endif
+
+ /* Hand off to main application code */
+ gCalledAppMainline = TRUE;
+ status = SDL_main (gArgc, gArgv);
+
+ /* We're done, thank you for playing */
+ exit(status);
+}
+@end
+
+
+@implementation NSString (ReplaceSubString)
+
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
+{
+ unsigned int bufferSize;
+ unsigned int selfLen = [self length];
+ unsigned int aStringLen = [aString length];
+ unichar *buffer;
+ NSRange localRange;
+ NSString *result;
+
+ bufferSize = selfLen + aStringLen - aRange.length;
+ buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
+
+ /* Get first part into buffer */
+ localRange.location = 0;
+ localRange.length = aRange.location;
+ [self getCharacters:buffer range:localRange];
+
+ /* Get middle part into buffer */
+ localRange.location = 0;
+ localRange.length = aStringLen;
+ [aString getCharacters:(buffer+aRange.location) range:localRange];
+
+ /* Get last part into buffer */
+ localRange.location = aRange.location + aRange.length;
+ localRange.length = selfLen - localRange.location;
+ [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
+
+ /* Build output string */
+ result = [NSString stringWithCharacters:buffer length:bufferSize];
+
+ NSDeallocateMemoryPages(buffer, bufferSize);
+
+ return result;
+}
+
+@end
+
+
+
+#ifdef main
+# undef main
+#endif
+
+
+/* Main entry point to executable - should *not* be SDL_main! */
+int main (int argc, char **argv)
+{
+ /* Copy the arguments into a global variable */
+ /* This is passed if we are launched by double-clicking */
+ if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+ gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
+ gArgv[0] = argv[0];
+ gArgv[1] = NULL;
+ gArgc = 1;
+ gFinderLaunch = YES;
+ } else {
+ int i;
+ gArgc = argc;
+ gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
+ for (i = 0; i <= argc; i++)
+ gArgv[i] = argv[i];
+ gFinderLaunch = NO;
+ }
+
+#if SDL_USE_NIB_FILE
+ [SDLApplication poseAsClass:[NSApplication class]];
+ NSApplicationMain (argc, argv);
+#else
+ CustomApplicationMain (argc, argv);
+#endif
+ return 0;
+}
diff --git a/src/aethyra.rc b/src/aethyra.rc
index f35c547d..d2db954f 100644
--- a/src/aethyra.rc
+++ b/src/aethyra.rc
@@ -19,5 +19,4 @@ FILETYPE VFT_APP {
VALUE "ProductVersion", PACKAGE_VERSION
}
}
-}
-
+}
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
index c86c5392..ba71d0e0 100644
--- a/src/animatedsprite.cpp
+++ b/src/animatedsprite.cpp
@@ -55,7 +55,8 @@ AnimatedSprite *AnimatedSprite::load(const std::string& filename, int variant)
{
ResourceManager *resman = ResourceManager::getInstance();
SpriteDef *s = resman->getSprite(filename, variant);
- if (!s) return NULL;
+ if (!s)
+ return NULL;
AnimatedSprite *as = new AnimatedSprite(s);
s->decRef();
return as;
@@ -66,22 +67,18 @@ AnimatedSprite::~AnimatedSprite()
mSprite->decRef();
}
-void
-AnimatedSprite::reset()
+void AnimatedSprite::reset()
{
mFrameIndex = 0;
mFrameTime = 0;
mLastTime = 0;
}
-void
-AnimatedSprite::play(SpriteAction spriteAction)
+void AnimatedSprite::play(SpriteAction spriteAction)
{
Action *action = mSprite->getAction(spriteAction);
if (!action)
- {
return;
- }
mAction = action;
Animation *animation = mAction->getAnimation(mDirection);
@@ -95,20 +92,15 @@ AnimatedSprite::play(SpriteAction spriteAction)
}
}
-void
-AnimatedSprite::update(int time)
+void AnimatedSprite::update(int time)
{
// Avoid freaking out at first frame or when tick_time overflows
if (time < mLastTime || mLastTime == 0)
- {
mLastTime = time;
- }
// If not enough time has passed yet, do nothing
if (time <= mLastTime || !mAnimation)
- {
return;
- }
unsigned int dt = time - mLastTime;
mLastTime = time;
@@ -120,13 +112,10 @@ AnimatedSprite::update(int time)
}
}
-bool
-AnimatedSprite::updateCurrentAnimation(unsigned int time)
+bool AnimatedSprite::updateCurrentAnimation(unsigned int time)
{
if (!mFrame || Animation::isTerminator(*mFrame))
- {
return false;
- }
mFrameTime += time;
@@ -136,9 +125,7 @@ AnimatedSprite::updateCurrentAnimation(unsigned int time)
mFrameIndex++;
if (mFrameIndex == mAnimation->getLength())
- {
mFrameIndex = 0;
- }
mFrame = mAnimation->getFrame(mFrameIndex);
@@ -153,30 +140,24 @@ AnimatedSprite::updateCurrentAnimation(unsigned int time)
return true;
}
-bool
-AnimatedSprite::draw(Graphics* graphics, int posX, int posY) const
+bool AnimatedSprite::draw(Graphics* graphics, int posX, int posY) const
{
if (!mFrame || !mFrame->image)
- {
return false;
- }
return graphics->drawImage(mFrame->image,
posX + mFrame->offsetX,
posY + mFrame->offsetY);
}
-void
-AnimatedSprite::setDirection(SpriteDirection direction)
+void AnimatedSprite::setDirection(SpriteDirection direction)
{
if (mDirection != direction)
{
mDirection = direction;
if (!mAction)
- {
return;
- }
Animation *animation = mAction->getAnimation(mDirection);
@@ -189,14 +170,12 @@ AnimatedSprite::setDirection(SpriteDirection direction)
}
}
-int
-AnimatedSprite::getWidth() const
+int AnimatedSprite::getWidth() const
{
return mFrame ? mFrame->image->getWidth() : 0;
}
-int
-AnimatedSprite::getHeight() const
+int AnimatedSprite::getHeight() const
{
return mFrame ? mFrame->image->getHeight() : 0;
}
diff --git a/src/being.cpp b/src/being.cpp
index ded3abd8..d98af29c 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -49,6 +49,11 @@
#define BEING_EFFECTS_FILE "effects.xml"
+#include "utils/xml.h"
+
+#define BEING_EFFECTS_FILE "effects.xml"
+#define HAIR_FILE "hair.xml"
+
int Being::instances = 0;
int Being::mNumberOfHairstyles = 1;
ImageSet *Being::emotionSet = NULL;
@@ -77,7 +82,9 @@ Being::Being(int id, int job, Map *map):
mPx(0), mPy(0),
mSprites(VECTOREND_SPRITE, NULL),
mSpriteIDs(VECTOREND_SPRITE, 0),
- mSpriteColors(VECTOREND_SPRITE, "")
+ mSpriteColors(VECTOREND_SPRITE, ""),
+ mStatusParticleEffects(&mStunParticleEffects, false),
+ mChildParticleEffects(&mStatusParticleEffects, false)
{
setMap(map);
@@ -109,13 +116,6 @@ Being::~Being()
delete_all(mSprites);
clearPath();
- for ( std::list<Particle *>::iterator i = mChildParticleEffects.begin();
- i != mChildParticleEffects.end();
- i++)
- {
- (*i)->kill();
- }
-
setMap(NULL);
instances--;
@@ -250,12 +250,7 @@ void Being::setMap(Map *map)
void Being::controlParticle(Particle *particle)
{
- if (particle)
- {
- // The effect may not die without the beings permission or we segfault
- particle->disableAutoDelete();
- mChildParticleEffects.push_back(particle);
- }
+ mChildParticleEffects.addLocally(particle);
}
void Being::setAction(Action action)
@@ -323,7 +318,7 @@ void Being::setDirection(Uint8 direction)
for (int i = 0; i < VECTOREND_SPRITE; i++)
{
- if (mSprites[i] != NULL)
+ if (mSprites[i] != NULL)
mSprites[i]->setDirection(dir);
}
}
@@ -402,6 +397,7 @@ void Being::logic()
int oldPx = mPx;
int oldPy = mPy;
+
// Update pixel coordinates
mPx = mX * 32 + getXOffset();
mPy = mY * 32 + getYOffset();
@@ -428,24 +424,8 @@ void Being::logic()
}
}
- if (mParticleEffects)
- {
- //Update particle effects
- for (std::list<Particle *>::iterator i = mChildParticleEffects.begin();
- i != mChildParticleEffects.end();)
- {
- (*i)->setPosition((float)mPx + 16.0f, (float)mPy + 32.0f);
- if ((*i)->isExtinct())
- {
- (*i)->kill();
- i = mChildParticleEffects.erase(i);
- }
- else
- {
- i++;
- }
- }
- }
+ //Update particle effects
+ mChildParticleEffects.setPositions((float)mPx + 16.0f, (float)mPy + 32.0f);
}
void Being::draw(Graphics *graphics, int offsetX, int offsetY) const
diff --git a/src/being.h b/src/being.h
index 958e8f60..7202701a 100644
--- a/src/being.h
+++ b/src/being.h
@@ -27,10 +27,12 @@
#include <SDL_types.h>
#include <string>
#include <vector>
+#include <bitset>
#include "animatedsprite.h"
#include "effectmanager.h"
#include "map.h"
+#include "particlecontainer.h"
#include "sprite.h"
#include "gui/speechbubble.h"
@@ -38,6 +40,7 @@
#include "resources/colordb.h"
#define FIRST_IGNORE_EMOTE 14
+#define STATUS_EFFECTS 32
class AnimatedSprite;
class Equipment;
@@ -364,6 +367,12 @@ class Being : public Sprite
const std::auto_ptr<Equipment> mEquipment;
+ static int getHairColorsNr(void);
+
+ static int getHairStylesNr(void);
+
+ static std::string getHairColor(int index);
+
protected:
/**
* Sets the new path for this being.
@@ -393,6 +402,8 @@ class Being : public Sprite
bool mIsGM;
bool mParticleEffects; /**< Whether to display particles or not */
+ typedef std::bitset<STATUS_EFFECTS> StatusEffects;
+
/** Engine-related infos about weapon. */
const ItemInfo* mEquippedWeapon;
@@ -405,11 +416,15 @@ class Being : public Sprite
Uint8 mGender;
Uint32 mSpeechTime;
Sint32 mPx, mPy; /**< Pixel coordinates */
+ Uint16 mStunMode; /**< Stun mode; zero if not stunned */
+ StatusEffects mStatusEffects; /**< Bitset of active status effects */
std::vector<AnimatedSprite*> mSprites;
std::vector<int> mSpriteIDs;
std::vector<std::string> mSpriteColors;
- std::list<Particle *> mChildParticleEffects;
+ ParticleList mStunParticleEffects;
+ ParticleVector mStatusParticleEffects;
+ ParticleList mChildParticleEffects;
private:
/**
diff --git a/src/engine.cpp b/src/engine.cpp
index b51f4852..74e11336 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -114,6 +114,12 @@ void Engine::changeMap(const std::string &mapPath)
minimap->setProportion(0.5);
}
}
+ if (newMap->hasProperty("name"))
+ {
+ minimap->setCaption(newMap->getProperty("name"));
+ } else {
+ minimap->setCaption("Map");
+ }
minimap->setMapImage(mapImage);
beingManager->setMap(newMap);
particleEngine->setMap(newMap);
diff --git a/src/equipment.h b/src/equipment.h
index 2427539c..e6145d12 100644
--- a/src/equipment.h
+++ b/src/equipment.h
@@ -17,8 +17,6 @@
* 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
- *
- * $Id: equipment.h 4347 2008-06-12 09:06:01Z b_lindeijer $
*/
#ifndef _TMW_EQUIPMENT_H_
@@ -45,26 +43,22 @@ class Equipment
/**
* Set equipment at the given slot.
*/
- void
- setEquipment(int index, int inventoryIndex);
+ void setEquipment(int index, int inventoryIndex);
/**
* Remove equipment from the given slot.
*/
- void
- removeEquipment(int index) { if (index >= 0 && index < EQUIPMENT_SIZE) mEquipment[index] = 0; }
+ void removeEquipment(int index) { if (index >= 0 && index < EQUIPMENT_SIZE) mEquipment[index] = 0; }
/**
- * Get the item used in the arrow slot.
+ * Returns the item used in the arrow slot.
*/
- int
- getArrows() { return mArrows; }
+ int getArrows() const { return mArrows; }
/**
* Set the item used in the arrow slot.
*/
- void
- setArrows(int arrows) {mArrows = arrows;}
+ void setArrows(int arrows) { mArrows = arrows; }
private:
int mEquipment[EQUIPMENT_SIZE];
diff --git a/src/floor_item.h b/src/floor_item.h
index 7771d935..b747310b 100644
--- a/src/floor_item.h
+++ b/src/floor_item.h
@@ -17,8 +17,6 @@
* 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
- *
- * $Id: floor_item.h 4347 2008-06-12 09:06:01Z b_lindeijer $
*/
#ifndef _TMW_FLOORITEM_H_
diff --git a/src/game.cpp b/src/game.cpp
index e8ba9046..93bec013 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -68,6 +68,7 @@
#include "gui/trade.h"
#include "gui/viewport.h"
+#include "net/protocol.h"
#include "net/beinghandler.h"
#include "net/buysellhandler.h"
#include "net/chathandler.h"
@@ -81,6 +82,7 @@
#include "net/protocol.h"
#include "net/skillhandler.h"
#include "net/tradehandler.h"
+#include "net/messageout.h"
#include "resources/imagewriter.h"
@@ -489,7 +491,7 @@ void Game::handleInput()
// Keys pressed together with Alt/Meta
// Emotions and some internal gui windows
#ifndef __APPLE__
- if (event.key.keysym.mod & KMOD_ALT)
+ if (event.key.keysym.mod & KMOD_LALT)
#else
if (event.key.keysym.mod & KMOD_LMETA)
#endif
@@ -580,6 +582,7 @@ void Game::handleInput()
{
chatWindow->scroll(DEFAULT_CHAT_WINDOW_SCROLL);
used = true;
+ return;
}
break;
@@ -837,7 +840,8 @@ void Game::handleInput()
}
// Target the nearest player if 'q' is pressed
- if ( keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER) && !keyboard.isKeyActive(keyboard.KEY_TARGET) )
+ if ( keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER) &&
+ !keyboard.isKeyActive(keyboard.KEY_TARGET) )
{
Being *target = beingManager->findNearestLivingBeing(player_node, 20, Being::PLAYER);
@@ -845,7 +849,9 @@ void Game::handleInput()
}
// Target the nearest monster if 'a' pressed
- if ( keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) && !keyboard.isKeyActive(keyboard.KEY_TARGET) )
+ if ((keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
+ (joystick && joystick->buttonPressed(3))) &&
+ !keyboard.isKeyActive(keyboard.KEY_TARGET))
{
Being *target = beingManager->findNearestLivingBeing(x, y, 20, Being::MONSTER);
@@ -853,7 +859,8 @@ void Game::handleInput()
}
// Target the nearest npc if 'n' pressed
- if ( keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) && !keyboard.isKeyActive(keyboard.KEY_TARGET) )
+ if ( keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) &&
+ !keyboard.isKeyActive(keyboard.KEY_TARGET) )
{
Being *target = beingManager->findNearestLivingBeing(x, y, 20, Being::NPC);
diff --git a/src/gui/buddywindow.cpp b/src/gui/buddywindow.cpp
new file mode 100644
index 00000000..14a941a5
--- /dev/null
+++ b/src/gui/buddywindow.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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 "buddywindow.h"
+
+#include <guichan/widgets/listbox.hpp>
+
+#include "button.h"
+#include "chat.h"
+#include "scrollarea.h"
+
+#include "../resources/buddylist.h"
+
+extern ChatWindow *chatWindow;
+
+BuddyWindow::BuddyWindow():
+ Window("Buddy")
+{
+ setContentSize(124, 202);
+
+ mBuddyList = new BuddyList();
+
+ mListbox = new gcn::ListBox();
+ mListbox->setListModel(mBuddyList);
+
+ ScrollArea *scrollArea = new ScrollArea(mListbox);
+ scrollArea->setDimension(gcn::Rectangle(
+ 7, 5, 110, 170));
+ add(scrollArea);
+
+ Button *talk = new Button("Talk", "Talk", this);
+ Button *remove = new Button("Remove", "Remove", this);
+ Button *cancel = new Button("Cancel", "Cancel", this);
+
+ talk->setPosition(2,180);
+ remove->setPosition(talk->getWidth()+2,180);
+ cancel->setPosition(talk->getWidth()+remove->getWidth()+2,180);
+
+ add(talk);
+ add(remove);
+ add(cancel);
+}
+
+void BuddyWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "Talk") {
+ int selected = mListbox->getSelected();
+ if ( selected > -1 )
+ {
+ std::string who = mBuddyList->getElementAt(selected);
+ chatWindow->setInputText(who +": ");
+ }
+ }
+ else if (event.getId() == "Remove") {
+ int selected = mListbox->getSelected();
+ if ( selected > -1 )
+ {
+ std::string who = mBuddyList->getElementAt(selected);
+ mBuddyList->removeBuddy(who);
+ }
+ }
+ else if (event.getId() == "Cancel") {
+ setVisible(false);
+ }
+}
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index 93783ded..53cc1e8d 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -256,8 +256,6 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
int numberOfHairColors = ColorDB::size();
- printf("%d\n", numberOfHairColors);
-
mPlayer->setHairStyle(rand() % mPlayer->getNumOfHairstyles(), rand() % numberOfHairColors);
mNameField = new TextField("");
diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp
index 8f68e6e1..054aff84 100644
--- a/src/gui/char_server.cpp
+++ b/src/gui/char_server.cpp
@@ -45,8 +45,10 @@ class ServerListModel : public gcn::ListModel {
std::string getElementAt(int i);
};
-ServerSelectDialog::ServerSelectDialog(LoginData *loginData):
- Window("Select Server"), mLoginData(loginData)
+ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState):
+ Window("Select Server"),
+ mLoginData(loginData),
+ mNextState(nextState)
{
mServerListModel = new ServerListModel();
mServerList = new ListBox(mServerListModel);
@@ -103,10 +105,10 @@ ServerSelectDialog::action(const gcn::ActionEvent &event)
mLoginData->hostname = iptostring(si->address);
mLoginData->port = si->port;
mLoginData->updateHost = si->updateHost;
- state = UPDATE_STATE;
+ state = mNextState;
}
else if (event.getId() == "cancel") {
- state = LOGIN_STATE;
+ state = LOGIN_STATE;
}
}
diff --git a/src/gui/char_server.h b/src/gui/char_server.h
index bb81d3a5..e05792f8 100644
--- a/src/gui/char_server.h
+++ b/src/gui/char_server.h
@@ -44,7 +44,7 @@ class ServerSelectDialog : public Window, public gcn::ActionListener {
*
* @see Window::Window
*/
- ServerSelectDialog(LoginData *loginData);
+ ServerSelectDialog(LoginData *loginData, int nextState);
/**
* Destructor.
@@ -61,6 +61,7 @@ class ServerSelectDialog : public Window, public gcn::ActionListener {
ServerListModel *mServerListModel;
gcn::ListBox *mServerList;
gcn::Button *mOkButton;
+ int mNextState;
};
#endif
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index dd11cebb..3f12c462 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -257,7 +257,7 @@ bool ChatWindow::isInputFocused()
return mChatInput->isFocused();
}
-void ChatWindow::chatSend(const std::string & nick, std::string msg)
+void ChatWindow::chatSend(const std::string &nick, std::string msg)
{
/* Some messages are managed client side, while others
* require server handling by proper packet. Probably
@@ -302,37 +302,42 @@ void ChatWindow::chatSend(const std::string & nick, std::string msg)
trim(msg);
}
- if (command == "announce") {
+ if (command == "announce")
+ {
MessageOut outMsg(mNetwork);
outMsg.writeInt16(0x0099);
outMsg.writeInt16(msg.length() + 4);
outMsg.writeString(msg, msg.length());
return;
}
- if (command == "help") {
+ else if (command == "help")
+ {
+ msg.erase(0, 6);
+ trim(msg);
std::size_t space = msg.find(" ");
std::string msg1;
- if (space == std::string::npos) {
+ if (space == std::string::npos)
+ {
msg1 = "";
- } else {
+ }
+ else
+ {
msg1 = msg.substr(space + 1, msg.length());
msg = msg.substr(0, space);
}
- if (msg != "" && msg.at(0) == '/') {
+ if (msg != "" && msg.at(0) == '/')
+ {
msg.erase(0, 1);
}
- while (msg1 != "" && msg1.at(0) == ' ') {
- msg1.erase(0, 1);
- }
+ trim(msg1);
help(msg, msg1);
- return;
}
- if (command == "where") {
+ else if (command == "where")
+ {
// Display the current map, X, and Y
std::ostringstream where;
- where << map_path << " " << player_node->mX << " " << player_node->mY;
+ where << map_path << " " << player_node->mX << "," << player_node->mY;
chatLog(where.str(), BY_SERVER);
- return;
}
if (command == "who") {
MessageOut outMsg(mNetwork);
@@ -648,20 +653,23 @@ void ChatWindow::help(const std::string & msg1, const std::string & msg2)
chatLog("For more information, type /help <command>", BY_SERVER);
return;
}
- if (msg1 == "announce") {
+ if (msg1 == "announce")
+ {
chatLog("Command: /announce <msg>", BY_SERVER);
chatLog("*** only available to a GM ***", BY_SERVER);
chatLog("This command sends the message <msg> to "
"all players currently online.", BY_SERVER);
return;
}
- if (msg1 == "clear") {
+ if (msg1 == "clear")
+ {
chatLog("Command: /clear", BY_SERVER);
chatLog("This command clears the chat log of previous chat.",
BY_SERVER);
return;
}
- if (msg1 == "help") {
+ if (msg1 == "help")
+ {
chatLog("Command: /help", BY_SERVER);
chatLog("This command displays a list of all commands available.",
BY_SERVER);
@@ -669,22 +677,26 @@ void ChatWindow::help(const std::string & msg1, const std::string & msg2)
chatLog("This command displays help on <command>.", BY_SERVER);
return;
}
- if (msg1 == "party") {
+ if (msg1 == "party")
+ {
mParty->help(msg2);
return;
}
- if (msg1 == "present") {
+ if (msg1 == "present")
+ {
chatLog("Command: /present", BY_SERVER);
chatLog("This command gets a list of players within hearing "
"and sends it to either the record log if recording, or the "
"chat log otherwise.", BY_SERVER);
return;
}
- if (msg1 == "record") {
+ if (msg1 == "record")
+ {
mRecorder->help(msg2);
return;
}
- if (msg1 == "toggle") {
+ if (msg1 == "toggle")
+ {
chatLog("Command: /toggle <state>", BY_SERVER);
chatLog("This command sets whether the return key should toggle the "
"chat log, or whether the chat log turns off automatically.",
@@ -696,7 +708,8 @@ void ChatWindow::help(const std::string & msg1, const std::string & msg2)
chatLog("This command displays the return toggle status.", BY_SERVER);
return;
}
- if (msg1 == "where") {
+ if (msg1 == "where")
+ {
chatLog("Command: /where", BY_SERVER);
chatLog("This command displays the name of the current map.",
BY_SERVER);
@@ -709,7 +722,8 @@ void ChatWindow::help(const std::string & msg1, const std::string & msg2)
"double quotes (\").", BY_SERVER);
return;
}
- if (msg1 == "who") {
+ if (msg1 == "who")
+ {
chatLog("Command: /who", BY_SERVER);
chatLog("This command displays the number of players currently "
"online.", BY_SERVER);
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index bf85f033..7e1ef315 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -22,6 +22,8 @@
#include "equipmentwindow.h"
#include "../equipment.h"
+#include "../inventory.h"
+#include "../localplayer.h"
#include "../graphics.h"
#include "../inventory.h"
#include "../item.h"
@@ -40,7 +42,7 @@ EquipmentWindow::EquipmentWindow(Equipment *equipment):
setCloseButton(true);
setDefaultSize(5, 230, 200, 120);
loadWindowState();
- inventory = player_node->getInventory();
+ mInventory = player_node->getInventory();
}
EquipmentWindow::~EquipmentWindow()
@@ -62,7 +64,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
graphics->drawRectangle(gcn::Rectangle(10 + 36 * (i % 4),
36 * (i / 4) + 25, 32, 32));
- if (!(item = inventory->getItem(mEquipment->getEquipment(i))))
+ if (!(item = mInventory->getItem(mEquipment->getEquipment(i))))
continue;
image = item->getImage();
@@ -75,7 +77,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
graphics->drawRectangle(gcn::Rectangle(160, 25, 32, 32));
- if (!(item = inventory->getItem(mEquipment->getArrows())))
+ if (!(item = mInventory->getItem(mEquipment->getArrows())))
return;
image = item->getImage();
diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h
index 7aacfc1e..b669f5b1 100644
--- a/src/gui/equipmentwindow.h
+++ b/src/gui/equipmentwindow.h
@@ -23,6 +23,7 @@
#define _TMW_EQUIPMENT_H
#include "window.h"
+#include "../inventory.h"
#include "../guichanfwd.h"
#include "../inventory.h"
@@ -54,7 +55,7 @@ class EquipmentWindow : public Window
private:
Equipment *mEquipment;
- Inventory *inventory;
+ Inventory *mInventory;
};
extern EquipmentWindow *equipmentWindow;
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index a382ef85..70f82d9d 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -110,7 +110,7 @@ Gui::Gui(Graphics *graphics):
Window::setWindowContainer(guiTop);
setTop(guiTop);
- // Set global font
+ // Set global font (based on ISO-8859-15)
try {
mGuiFont = new gcn::ImageFont("graphics/gui/sansserif8.png",
" !\"#$%&'()*+,-./"
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index a8b20d40..424fca59 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -73,7 +73,7 @@ InventoryWindow::InventoryWindow():
mWeightLabel->setPosition(8, 8);
mSlots = "Slots: " +
toString(player_node->getInventory()->getNumberOfSlotsUsed()) +
- "/" + toString(player_node->getInventory()->getSize() - 2);
+ "/" + toString(player_node->getInventory()->getInventorySize());
mSlotsLabel = new TextBox();
mItemEffectLabel = new TextBox();
@@ -113,7 +113,7 @@ void InventoryWindow::logic()
mSlots = "Slots: " +
toString(player_node->getInventory()->getNumberOfSlotsUsed()) +
- "/" + toString(player_node->getInventory()->getSize() - 2);
+ "/" + toString(player_node->getInventory()->getInventorySize());
draw();
}
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index fca0c72d..9e17f3da 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -64,8 +64,7 @@ ItemContainer::~ItemContainer()
mSelImg->decRef();
}
-void
-ItemContainer::logic()
+void ItemContainer::logic()
{
gcn::Widget::logic();
@@ -78,8 +77,7 @@ ItemContainer::logic()
}
}
-void
-ItemContainer::draw(gcn::Graphics *graphics)
+void ItemContainer::draw(gcn::Graphics *graphics)
{
int columns = getWidth() / gridWidth;
@@ -146,8 +144,7 @@ void ItemContainer::recalculateHeight()
setHeight(height);
}
-Item*
-ItemContainer::getSelectedItem()
+Item *ItemContainer::getSelectedItem()
{
refindSelectedItem(); // Make sure that we're still current
@@ -157,8 +154,7 @@ ItemContainer::getSelectedItem()
return mInventory->getItem(mSelectedItemIndex);
}
-void
-ItemContainer::selectNone()
+void ItemContainer::selectNone()
{
setSelectedItemIndex(NO_ITEM);
}
@@ -166,15 +162,15 @@ ItemContainer::selectNone()
void ItemContainer::refindSelectedItem()
{
if (mSelectedItemIndex != NO_ITEM) {
-
+
if (mInventory->getItem(mSelectedItemIndex) &&
mInventory->getItem(mSelectedItemIndex)->getId() == mLastSelectedItemId)
return; // we're already fine
-
+
// Otherwise ensure the invariant: we must point to an item of the specified last ID,
// or nowhere at all.
- for (int i = 0; i <= mMaxItems + mOffset; i++)
+ for (int i = 0; i <= mMaxItems + 1; i++)
if (mInventory->getItem(i) &&
mInventory->getItem(i)->getId() == mLastSelectedItemId) {
mSelectedItemIndex = i;
@@ -198,7 +194,6 @@ void ItemContainer::setSelectedItemIndex(int index)
newSelectedItemIndex = NO_ITEM;
else
newSelectedItemIndex = index;
-
if (mSelectedItemIndex != newSelectedItemIndex)
{
mSelectedItemIndex = newSelectedItemIndex;
@@ -212,8 +207,7 @@ void ItemContainer::setSelectedItemIndex(int index)
}
}
-void
-ItemContainer::distributeValueChangedEvent()
+void ItemContainer::distributeValueChangedEvent()
{
gcn::SelectionEvent event(this);
std::list<gcn::SelectionListener*>::iterator i_end = mListeners.end();
@@ -225,8 +219,7 @@ ItemContainer::distributeValueChangedEvent()
}
}
-void
-ItemContainer::mousePressed(gcn::MouseEvent &event)
+void ItemContainer::mousePressed(gcn::MouseEvent &event)
{
int button = event.getButton();
@@ -243,8 +236,6 @@ ItemContainer::mousePressed(gcn::MouseEvent &event)
Item *item = mInventory->getItem(index);
if (item)
- {
itemShortcut->setItemSelected(item->getId());
- }
}
}
diff --git a/src/gui/itemcontainer.h b/src/gui/itemcontainer.h
index 5d22b658..8927b001 100644
--- a/src/gui/itemcontainer.h
+++ b/src/gui/itemcontainer.h
@@ -108,29 +108,30 @@ class ItemContainer : public gcn::Widget,
private:
/**
- * Find the current item index by the most recently used item ID
+
+ * Sets the currently selected item. Invalid (e.g., negative) indices set `no item'.
*/
- void refindSelectedItem(void);
+ void setSelectedItemIndex(int index);
/**
- * Sets the currently selected item. Invalid (e.g., negative) indices set `no item'.
+ * Find the current item index by the most recently used item ID
*/
- void setSelectedItemIndex(int index);
+ void refindSelectedItem(void);
/**
* Determine and set the height of the container.
*/
- void recalculateHeight();
+ void recalculateHeight(void);
/**
* Sends out selection events to the list of selection listeners.
*/
- void distributeValueChangedEvent();
+ void distributeValueChangedEvent(void);
Inventory *mInventory;
Image *mSelImg;
int mSelectedItemIndex;
- int mLastSelectedItemId; // last selected item ID. If we lose the item, find again by ID.
+ int mLastSelectedItemId; // last selected item ID. If we lose the item, find again by ID.
int mMaxItems;
int mOffset;
diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp
index f8a0959a..de5e1956 100644
--- a/src/gui/itemshortcutcontainer.cpp
+++ b/src/gui/itemshortcutcontainer.cpp
@@ -86,7 +86,7 @@ ItemShortcutContainer::draw(gcn::Graphics *graphics)
// Draw item keyboard shortcut.
const char *key = SDL_GetKeyName(
- (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_0+i));
+ (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_0 + i));
g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT);
if (itemShortcut->getItem(i) < 0)
@@ -100,6 +100,8 @@ ItemShortcutContainer::draw(gcn::Graphics *graphics)
item->isEquipped() ? "Eq." : toString(item->getQuantity());
Image* image = item->getImage();
if (image) {
+ const std::string label =
+ item->isEquipped() ? "Eq." : toString(item->getQuantity());
g->drawImage(image, itemX, itemY);
g->drawText(
label,
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
index 3a2e483d..8339e478 100644
--- a/src/gui/minimap.cpp
+++ b/src/gui/minimap.cpp
@@ -40,17 +40,13 @@ Minimap::Minimap():
Minimap::~Minimap()
{
if (mMapImage)
- {
mMapImage->decRef();
- }
}
void Minimap::setMapImage(Image *img)
{
if (mMapImage)
- {
mMapImage->decRef();
- }
mMapImage = img;
diff --git a/src/gui/newskill.cpp b/src/gui/newskill.cpp
new file mode 100644
index 00000000..20fc01bd
--- /dev/null
+++ b/src/gui/newskill.cpp
@@ -0,0 +1,193 @@
+/*
+ * 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
+ */
+
+ /* This file implements the new skill dialog for use under the latest
+ * version of the skill system as of 2005/02/20
+ */
+
+#include "newskill.h"
+
+#include <guichan/widgets/label.hpp>
+
+#include "button.h"
+#include "progressbar.h"
+
+#include "../graphics.h"
+
+const char *skill_name[] = {
+ // 0-99
+ // weapon skills 0-9
+ "Short Blades", "Long Blades", "Hammers", "Archery", "Whip",
+ "Staves", "Throwing", "Piercing", "Hand to Hand", NULL,
+ // magic skills 10-19
+ "Epyri (Fire)", "Merene (Water)", "Geon (Earth)", "Izurial (Air)",
+ "Lumine (Light)", "Tenebrae (Dark)", "Chronos (Time)", "Teless (Space)",
+ "Gen (Mana)", NULL,
+ // craft skills 20-29
+ "Metalworking", "Woodworking", "Jeweler", "Cook", "Tailor",
+ "Alchemist", "Artisan", "Synthesis", NULL, NULL,
+ // general skills 30-39
+ "Running", "Searching", "Sneak", "Trading", "Intimidate",
+ "Athletics", NULL, NULL, NULL,NULL,
+ // combat skills 40-49
+ "Dodge", "Accuracy", "Critical", "Block", "Parry", "Diehard", "Magic Aura",
+ "Counter", NULL, NULL,
+ // resistance skills 50-59
+ "Poison", "Silence", "Petrify", "Paralyze", "Blind", "Slow", "Zombie",
+ "Critical", NULL, NULL,
+ // element reistance 60-69
+ "Heat (Fire)", "Chill (Water)", "Stone (Earth)", "Wind (Air)",
+ "Shine (Light)", "Shadow (Dark)", "Decay (Time)", "Chaos (Space)", NULL,
+ NULL,
+ // hunting skills 70-79
+ "Insects", "Birds", "Lizards", "Amorphs", "Undead", "Machines", "Arcana",
+ "Humanoids", "Plantoids", NULL,
+ // stats 80-89
+ "Strength", "Fortitude", "Vitality", "Menality", "Awareness", "Mana",
+ "Dexterity", NULL, NULL, NULL,
+ // unused (reserved) 90-99
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+
+NewSkillDialog::NewSkillDialog():
+ Window("Skills")
+{
+ startPoint = 0;
+ for (int i = 0; i < N_SKILL_CAT_SIZE; i++)
+ {
+ mSkillLabel[i] = new gcn::Label("Empty ");
+ mSkillLevel[i] = new gcn::Label("00000");
+ mSkillbar[i] = new ProgressBar(0.0f,100,15,0,0,255);
+ mSkillLevel[i]->setAlignment(Graphics::RIGHT);
+ add(mSkillLabel[i],40,5+i*25);
+ add(mSkillLevel[i],150,5+i*25);
+ add(mSkillbar[i],180,5+i*25);
+ }
+ // initialize the skills
+ for (int i = 0; i < N_SKILL; i++)
+ {
+ mPlayerSkill[i].level = 0;
+ mPlayerSkill[i].exp = 0;
+ }
+ resetNSD();
+
+ // create controls
+ Button *catButton[N_SKILL_CAT];
+ catButton[0] = new Button("Weapons", "g1", this);
+ catButton[1] = new Button("Magic", "g2", this);
+ catButton[2] = new Button("Craft", "g3", this);
+ catButton[3] = new Button("General", "g4", this);
+ catButton[4] = new Button("Combat", "g5", this);
+ catButton[5] = new Button("E. Resist", "g6", this);
+ catButton[6] = new Button("S. Resist", "g7", this);
+ catButton[7] = new Button("Hunting", "g8", this);
+ catButton[8] = new Button("Stat", "g9", this);
+
+ setContentSize(350, 250);
+
+ for (int i = 0; i < 9; ++i) {
+ catButton[i]->setDimension(gcn::Rectangle(0, 0, 60, 20));
+ catButton[i]->setPosition(290, 20 * i);
+ add(catButton[i]);
+ }
+
+ Button *closeButton = new Button("Close", "close", this);
+ closeButton->setDimension(gcn::Rectangle(0,0,60,20));
+ closeButton->setPosition(290, 230);
+ add(closeButton);
+
+ // finsihing touches
+ setLocationRelativeTo(getParent());
+}
+
+void NewSkillDialog::action(const gcn::ActionEvent &event)
+{
+ int osp = startPoint;
+ if (event.getId() == "close")
+ {
+ setVisible(false);
+ }
+ else if (event.getId() == "g1") // weapons group 0-9
+ {
+ startPoint =0;
+ }
+ else if (event.getId() == "g2") // magic group 10-19
+ {
+ startPoint =10;
+ }
+ else if (event.getId() == "g3") // craft group 20-29
+ {
+ startPoint =20;
+ }
+ else if (event.getId() == "g4") // general group 30-39
+ {
+ startPoint =30;
+ }
+ else if (event.getId() == "g5") // combat group 40-49
+ {
+ startPoint =40;
+ }
+ else if (event.getId() == "g6") // e. resist group 50-59
+ {
+ startPoint =50;
+ }
+ else if (event.getId() == "g7") // s resist group 60-69
+ {
+ startPoint =60;
+ }
+ else if (event.getId() == "g8") // hunting group 70-79
+ {
+ startPoint =70;
+ }
+ else if (event.getId() == "g9") // stats group 80-89
+ {
+ startPoint =80;
+ }
+ if (osp != startPoint)
+ {
+ resetNSD();
+ }
+}
+
+void NewSkillDialog::resetNSD()
+{
+ for (int a = 0; a < N_SKILL_CAT_SIZE; a++)
+ {
+ if (skill_name[a + startPoint])
+ {
+ mSkillLabel[a]->setCaption(skill_name[a + startPoint]);
+ mSkillLabel[a]->setVisible(true);
+ char tmp[5];
+ sprintf(tmp, "%d", mPlayerSkill[a+startPoint].level);
+ mSkillLevel[a]->setCaption(tmp);
+ mSkillLevel[a]->setVisible(true);
+ mSkillbar[a]->setProgress(0.0f);
+ mSkillbar[a]->setVisible(true);
+ }
+ else
+ {
+ mSkillLevel[a]->setVisible(false);
+ mSkillLabel[a]->setVisible(false);
+ mSkillbar[a]->setVisible(false);
+ }
+ }
+}
diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp
index d83e9dea..b53de828 100644
--- a/src/gui/npc_text.cpp
+++ b/src/gui/npc_text.cpp
@@ -59,7 +59,6 @@ void NpcTextDialog::setText(const std::string &text)
{
const gcn::Rectangle &area = getChildrenArea();
const int width = area.width;
- const int height = area.height;
mText = text;
mTextBox->setMinWidth(width - 30);
diff --git a/src/gui/npclistdialog.h b/src/gui/npclistdialog.h
index 04c5c4d9..099d03c0 100644
--- a/src/gui/npclistdialog.h
+++ b/src/gui/npclistdialog.h
@@ -86,9 +86,9 @@ class NpcListDialog : public Window, public gcn::ActionListener,
private:
gcn::ListBox *mItemList;
- ScrollArea *scrollArea;
- Button *okButton;
- Button *cancelButton;
+ gcn::ScrollArea *scrollArea;
+ gcn::Button *okButton;
+ gcn::Button *cancelButton;
std::vector<std::string> mItems;
};
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index ec5b1d0a..15841615 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -289,11 +289,12 @@ void Setup_Video::apply()
bool fullscreen = mFsCheckBox->isSelected();
if (fullscreen != (config.getValue("screen", 0) == 1))
{
-
- /* Commented out the openGL test because
- * the fullscreen mode change works fine, but
- * will need to test it on windows so not
- * deleting entirely until then --kraant*/
+ /* The OpenGL test is only necessary on Windows, since switching
+ * to/from full screen works fine on Linux. On Windows we'd have to
+ * reinitialize the OpenGL state and reload all textures.
+ *
+ * See http://libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode
+ */
#ifdef WIN32
// checks for opengl usage
diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp
index 36c3a305..8e61dea4 100644
--- a/src/gui/skill.cpp
+++ b/src/gui/skill.cpp
@@ -87,7 +87,8 @@ public:
SkillInfo const *info;
char tmp[128];
- if (skill->id >= 0 && (unsigned int) skill->id < skill_db.size())
+ if (skill->id >= 0
+ && (unsigned int) skill->id < skill_db.size())
info = &skill_db[skill->id];
else
info = &fakeSkillInfo;
@@ -195,13 +196,14 @@ void SkillDialog::update()
if (selectedSkill >= 0) {
int skillId = mSkillList[selectedSkill]->id;
bool modifiable;
-
+
if (skillId >= 0 && (unsigned int) skillId < skill_db.size())
modifiable = skill_db[skillId].modifiable;
else
modifiable = false;
- mIncButton->setEnabled(modifiable && player_node->mSkillPoint > 0);
+ mIncButton->setEnabled(modifiable
+ && player_node->mSkillPoint > 0);
} else
mIncButton->setEnabled(false);
diff --git a/src/gui/skill.h b/src/gui/skill.h
index ee579dd5..2095e098 100644
--- a/src/gui/skill.h
+++ b/src/gui/skill.h
@@ -30,6 +30,7 @@
#include "scrollarea.h"
#include "table.h"
#include "window.h"
+#include "table.h"
#include "../guichanfwd.h"
diff --git a/src/gui/status.h b/src/gui/status.h
index 4fbce445..eb4171c9 100644
--- a/src/gui/status.h
+++ b/src/gui/status.h
@@ -68,7 +68,9 @@ class StatusWindow : public Window, public gcn::ActionListener
/**
* Status Part
*/
- gcn::Label *mLvlLabel, *mJobLvlLabel, *mGpLabel, *mHpLabel, *mHpValueLabel;
+ gcn::Label *mLvlLabel, *mJobLvlLabel;
+ gcn::Label *mGpLabel;
+ gcn::Label *mHpLabel, *mHpValueLabel;
gcn::Label *mMpLabel, *mMpValueLabel;
gcn::Label *mXpLabel, *mXpValueLabel, *mJobXpLabel, *mJobValueLabel;
ProgressBar *mHpBar, *mMpBar;
diff --git a/src/gui/table_model.h b/src/gui/table_model.h
index 4022e369..a52a7561 100644
--- a/src/gui/table_model.h
+++ b/src/gui/table_model.h
@@ -127,9 +127,9 @@ public:
*/
virtual void resize(void);
- virtual int getRows();
- virtual int getColumns();
- virtual int getRowHeight();
+ virtual int getRows(void);
+ virtual int getColumns(void);
+ virtual int getRowHeight(void);
virtual int getColumnWidth(int index);
virtual gcn::Widget *getElementAt(int row, int column);
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index 1097f072..36d00bec 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -309,14 +309,15 @@ int UpdaterWindow::downloadThread(void *ptr)
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
- struct curl_slist *pHeaders=NULL;
- if(uw->mDownloadStatus != UPDATE_RESOURCES){
- /*caching breaks things when resources2.txt is cached
- *so caching is turned off on the proxy with this header
- *change*/
- pHeaders = curl_slist_append(pHeaders, "pragma: no-cache");
- pHeaders = curl_slist_append(pHeaders, "Cache-Control: no-cache");
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pHeaders);
+ struct curl_slist *pHeaders = NULL;
+ if (uw->mDownloadStatus != UPDATE_RESOURCES)
+ {
+ // Make sure the resources2.txt and news.txt aren't cached,
+ // in order to always get the latest version.
+ pHeaders = curl_slist_append(pHeaders, "pragma: no-cache");
+ pHeaders =
+ curl_slist_append(pHeaders, "Cache-Control: no-cache");
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pHeaders);
}
if ((res = curl_easy_perform(curl)) != 0)
@@ -343,8 +344,9 @@ int UpdaterWindow::downloadThread(void *ptr)
curl_easy_cleanup(curl);
- if(uw->mDownloadStatus != UPDATE_RESOURCES){
- curl_slist_free_all(pHeaders);
+ if (uw->mDownloadStatus != UPDATE_RESOURCES)
+ {
+ curl_slist_free_all(pHeaders);
}
if (!uw->mStoreInMemory)
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 3f0f546e..e50903b6 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -48,6 +48,8 @@
extern volatile int tick_time;
+extern volatile int tick_time;
+
Viewport::Viewport():
mMap(0),
mPixelViewX(0.0f),
@@ -196,17 +198,16 @@ Viewport::draw(gcn::Graphics *gcnGraphics)
}
}
- // Draw names
+ // Draw text
if (textManager)
{
- textManager->draw(graphics, (int) mPixelViewX, (int) mPixelViewY);
+ textManager->draw(graphics, mPixelViewX, mPixelViewY);
}
- // Draw player speech, and emotion sprite as needed
+ // Draw player names, speech, and emotion sprite as needed
Beings &beings = beingManager->getAll();
for (BeingIterator i = beings.begin(); i != beings.end(); i++)
{
- (*i)->drawSpeech(graphics, -(int) mPixelViewX, -(int) mPixelViewY);
(*i)->drawEmotion(graphics, -(int) mPixelViewX, -(int) mPixelViewY);
}
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 48964121..30456a81 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -22,6 +22,7 @@
#include <algorithm>
#include <cassert>
#include <climits>
+#include <cassert>
#include <guichan/exception.hpp>
diff --git a/src/inventory.cpp b/src/inventory.cpp
index d346a50b..da9aed02 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -50,7 +50,7 @@ Inventory::~Inventory()
Item* Inventory::getItem(int index) const
{
- if (index < 0 || index >= mSize)
+ if (index < 0 || index >= INVENTORY_SIZE || !mItems[index] || mItems[index]->getQuantity() <= 0)
return 0;
return mItems[index];
@@ -146,3 +146,8 @@ int Inventory::getLastUsedSlot() const
return -1;
}
+
+int Inventory::getInventorySize() const
+{
+ return INVENTORY_SIZE - 2;
+}
diff --git a/src/inventory.h b/src/inventory.h
index 566ca17c..91bb7d04 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -24,6 +24,8 @@
class Item;
+#define INVENTORY_SIZE 102
+
class Inventory
{
public:
@@ -100,6 +102,11 @@ class Inventory
*/
int getLastUsedSlot() const;
+ /**
+ * Returns the number of slots available in the inventory.
+ */
+ int getInventorySize() const;
+
protected:
Item **mItems; /**< The holder of items */
int mSize; /**< The max number of inventory items */
diff --git a/src/joystick.cpp b/src/joystick.cpp
index b3aba4fc..4cee4464 100644
--- a/src/joystick.cpp
+++ b/src/joystick.cpp
@@ -25,6 +25,8 @@
#include "joystick.h"
#include "log.h"
+#include <cassert>
+
int Joystick::joystickCount = 0;
void Joystick::init()
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 7fdbc09b..292f70e0 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -30,6 +30,7 @@
#include "monster.h"
#include "particle.h"
#include "sound.h"
+#include "monster.h"
#include "gui/gui.h"
@@ -508,9 +509,9 @@ void LocalPlayer::stopAttack()
{
setAction(STAND);
mLastTarget = -1;
- setTarget(NULL);
- mLastTarget = -1;
}
+ setTarget(NULL);
+ mLastTarget = -1;
}
Being* LocalPlayer::getTarget() const
diff --git a/src/log.h b/src/log.h
index 6fe9dccd..30078e35 100644
--- a/src/log.h
+++ b/src/log.h
@@ -68,8 +68,8 @@ class Logger
;
/**
- * Log an error and quit. The error will pop-up in Windows and will be
- * printed to standard error everywhere else.
+ * Log an error and quit. The error will pop-up on Windows and Mac, and
+ * will be printed to standard error everywhere else.
*/
void error(const std::string &error_text);
diff --git a/src/logindata.h b/src/logindata.h
index d2fe3043..6b733269 100644
--- a/src/logindata.h
+++ b/src/logindata.h
@@ -17,8 +17,6 @@
* 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
- *
- * $Id: logindata.h 3606 2007-09-27 14:54:09Z b_lindeijer $
*/
#ifndef _TMW_LOGINDATA_H
diff --git a/src/main.cpp b/src/main.cpp
index 279bae71..4049aa78 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -60,6 +60,7 @@
#include "gui/progressbar.h"
#include "gui/register.h"
#include "gui/setup.h"
+#include "gui/updatewindow.h"
#include "gui/textfield.h"
#include "gui/updatewindow.h"
@@ -185,6 +186,10 @@ void setUpdatesDir()
config.getValue("updatehost", "http://www.aethyra.org/updates");
}
+ // Remove any trailing slash at the end of the update host
+ if (updateHost.at(updateHost.size() - 1) == '/')
+ updateHost.resize(updateHost.size() - 1);
+
// Parse out any "http://" or "ftp://", and set the updates directory
size_t pos;
pos = updateHost.find("://");
@@ -478,7 +483,7 @@ void printVersion()
void parseOptions(int argc, char *argv[], Options &options)
{
- const char *optstring = "hvuU:P:Dp:C:H:";
+ const char *optstring = "hvud:U:P:Dp:C:H:";
const struct option long_options[] = {
{ "configfile", required_argument, 0, 'C' },
@@ -498,9 +503,8 @@ void parseOptions(int argc, char *argv[], Options &options)
int result = getopt_long(argc, argv, optstring, long_options, NULL);
- if (result == -1) {
+ if (result == -1)
break;
- }
switch (result) {
case 'C':
@@ -583,9 +587,10 @@ void accountLogin(Network *network, LoginData *loginData)
outMsg.writeString(loginData->password, 24);
/*
- * eAthena calls the last byte "client version 2", but it isn't
- * used at all. We're retasking it, with bit 0 to indicate whether
- * the client can handle the 0x63 "update host" packet
+ * eAthena calls the last byte "client version 2", but it isn't used at
+ * at all. We're retasking it, with bit 0 to indicate whether the client
+ * can handle the 0x63 "update host" packet. Clients prior to 0.0.25 send
+ * 0 here.
*/
outMsg.writeInt8(0x01);
@@ -903,17 +908,25 @@ int main(int argc, char *argv[])
case CHAR_SERVER_STATE:
logger->log("State: CHAR_SERVER");
- if (n_server == 1) {
+
+ if (n_server == 1)
+ {
SERVER_INFO *si = *server_info;
loginData.hostname = iptostring(si->address);
loginData.port = si->port;
loginData.updateHost = si->updateHost;
state = UPDATE_STATE;
- } else {
- currentDialog = new ServerSelectDialog(&loginData);
+ }
+ else
+ {
+ int nextState = (options.skipUpdate) ?
+ LOADDATA_STATE : UPDATE_STATE;
+ currentDialog = new ServerSelectDialog(&loginData,
+ nextState);
positionDialog(currentDialog, screenWidth,
screenHeight);
- if (options.chooseDefault || options.playername != "") {
+ if (options.chooseDefault || options.playername != "")
+ {
((ServerSelectDialog*) currentDialog)->action(
gcn::ActionEvent(NULL, "ok"));
}
@@ -964,7 +977,7 @@ int main(int argc, char *argv[])
case UPDATE_STATE:
// Determine which source to use for the update host
- if(!options.updateHost.empty())
+ if (!options.updateHost.empty())
updateHost = options.updateHost;
else
updateHost = loginData.updateHost;
diff --git a/src/map.cpp b/src/map.cpp
index 612d9020..02b046fb 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -71,22 +71,22 @@ MapLayer::MapLayer(int x, int y, int width, int height, bool isFringeLayer):
mTiles = new Image*[size];
std::fill_n(mTiles, size, (Image*) 0);
}
-
+
MapLayer::~MapLayer()
{
delete[] mTiles;
}
-
+
void MapLayer::setTile(int x, int y, Image *img)
{
mTiles[x + y * mWidth] = img;
}
-
+
Image* MapLayer::getTile(int x, int y) const
{
return mTiles[x + y * mWidth];
}
-
+
void MapLayer::draw(Graphics *graphics,
int startX, int startY,
int endX, int endY,
@@ -97,43 +97,43 @@ void MapLayer::draw(Graphics *graphics,
startY -= mY;
endX -= mX;
endY -= mY;
-
+
if (startX < 0) startX = 0;
if (startY < 0) startY = 0;
if (endX > mWidth) endX = mWidth;
if (endY > mHeight) endY = mHeight;
-
+
Sprites::const_iterator si = sprites.begin();
-
+
for (int y = startY; y < endY; y++)
{
// If drawing the fringe layer, make sure all sprites above this row of
// tiles have been drawn
if (mIsFringeLayer) {
- player_node->drawTargetCursor(graphics, scrollX, scrollY);
- while (si != sprites.end() && (*si)->getPixelY() <= y * 32 - 32) {
- (*si)->draw(graphics, -scrollX, -scrollY);
- si++;
- }
+ player_node->drawTargetCursor(graphics, scrollX, scrollY);
+ while (si != sprites.end() && (*si)->getPixelY() <= y * 32 - 32) {
+ (*si)->draw(graphics, -scrollX, -scrollY);
+ si++;
+ }
}
for (int x = startX; x < endX; x++)
{
- Image *img = getTile(x, y);
- if (img) {
- const int px = (x + mX) * 32 - scrollX;
- const int py = (y + mY) * 32 - scrollY + 32 - img->getHeight();
- graphics->drawImage(img, px, py);
- }
- }
+ Image *img = getTile(x, y);
+ if (img) {
+ const int px = (x + mX) * 32 - scrollX;
+ const int py = (y + mY) * 32 - scrollY + 32 - img->getHeight();
+ graphics->drawImage(img, px, py);
+ }
+ }
}
-
+
// Draw any remaining sprites
if (mIsFringeLayer) {
- while (si != sprites.end()) {
- (*si)->draw(graphics, -scrollX, -scrollY);
- si++;
- }
+ while (si != sprites.end()) {
+ (*si)->draw(graphics, -scrollX, -scrollY);
+ si++;
+ }
}
}
@@ -186,7 +186,7 @@ void Map::initializeOverlays()
void Map::addLayer(MapLayer *layer)
{
- mLayers.push_back(layer);
+ mLayers.push_back(layer);
}
void Map::addTileset(Tileset *tileset)
@@ -273,7 +273,7 @@ void Map::drawOverlay(Graphics *graphics,
class ContainsGidFunctor
{
public:
- bool operator() (Tileset* set) const
+ bool operator() (const Tileset* set) const
{
return (set->getFirstGid() <= gid &&
gid - set->getFirstGid() < (int)set->size());
diff --git a/src/monster.cpp b/src/monster.cpp
index 62be513d..04624b8c 100644
--- a/src/monster.cpp
+++ b/src/monster.cpp
@@ -21,6 +21,7 @@
#include "animatedsprite.h"
#include "game.h"
+#include "localplayer.h"
#include "monster.h"
#include "particle.h"
#include "sound.h"
@@ -43,8 +44,8 @@ Monster::Monster(Uint32 id, Uint16 job, Map *map):
// Setup Monster sprites
int c = BASE_SPRITE;
-
const std::list<std::string> &sprites = info.getSprites();
+
for (std::list<std::string>::const_iterator i = sprites.begin();
i != sprites.end();
i++)
@@ -77,7 +78,10 @@ Monster::Monster(Uint32 id, Uint16 job, Map *map):
Monster::~Monster()
{
if (mText)
+ {
delete mText;
+ player_node->setTarget(NULL);
+ }
}
void Monster::logic()
@@ -166,7 +170,8 @@ void Monster::handleAttack(Being *victim, int damage)
Being::handleAttack(victim, damage);
const MonsterInfo &mi = getInfo();
- sound.playSfx(mi.getSound((damage > 0) ? MONSTER_EVENT_HIT : MONSTER_EVENT_MISS));
+ sound.playSfx(mi.getSound((damage > 0) ?
+ MONSTER_EVENT_HIT : MONSTER_EVENT_MISS));
}
void Monster::takeDamage(int amount)
diff --git a/src/monster.h b/src/monster.h
index 0906dff3..cb8f7f18 100644
--- a/src/monster.h
+++ b/src/monster.h
@@ -75,8 +75,12 @@ class Monster : public Being
* Update the text when the monster moves
*/
void updateCoords();
+
private:
- Text *mText; /**< holds a text object when the mod displays it's name, 0 otherwise */
+ /**
+ * holds a text object when the mod displays it's name, 0 otherwise
+ */
+ Text *mText;
};
#endif
diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp
index b016b5cf..3c022af6 100644
--- a/src/net/beinghandler.cpp
+++ b/src/net/beinghandler.cpp
@@ -204,21 +204,15 @@ void BeingHandler::handleMessage(MessageIn *msg)
// If this is player's current target, clear it.
if (dstBeing == player_node->getTarget())
- {
player_node->stopAttack();
- }
if (dstBeing == current_npc)
current_npc = NULL;
if (msg->readInt8() == 1)
- {
dstBeing->setAction(Being::DEAD);
- }
else
- {
beingManager->destroyBeing(dstBeing);
- }
break;
@@ -236,27 +230,26 @@ void BeingHandler::handleMessage(MessageIn *msg)
switch (type)
{
case 0x0a: // Critical Damage
- if (dstBeing) {
+ if (dstBeing)
dstBeing->showCrit();
- }
- case 0x00: // Damage
- if (dstBeing) {
+ case 0x00: // Damage
+ if (dstBeing)
dstBeing->takeDamage(param1);
- }
- if (srcBeing) {
+ if (srcBeing)
srcBeing->handleAttack(dstBeing, param1);
- }
break;
case 0x02: // Sit
- if (srcBeing) {
+ if (srcBeing)
+ {
srcBeing->mFrame = 0;
srcBeing->setAction(Being::SIT);
}
break;
case 0x03: // Stand up
- if (srcBeing) {
+ if (srcBeing)
+ {
srcBeing->mFrame = 0;
srcBeing->setAction(Being::STAND);
}
@@ -518,3 +511,4 @@ void BeingHandler::handleMessage(MessageIn *msg)
break;
}
}
+
diff --git a/src/net/buysellhandler.cpp b/src/net/buysellhandler.cpp
index ad613889..b2fe99b9 100644
--- a/src/net/buysellhandler.cpp
+++ b/src/net/buysellhandler.cpp
@@ -113,6 +113,8 @@ void BuySellHandler::handleMessage(MessageIn *msg)
if (msg->readInt8() == 0) {
chatWindow->chatLog("Thanks for buying", BY_SERVER);
} else {
+ // Reset player money since buy dialog already assumed purchase
+ // would go fine
buyDialog->setMoney(player_node->mGp);
chatWindow->chatLog("Unable to buy", BY_SERVER);
}
diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp
index 833732db..281923f8 100644
--- a/src/net/charserverhandler.cpp
+++ b/src/net/charserverhandler.cpp
@@ -178,7 +178,7 @@ void CharServerHandler::handleMessage(MessageIn *msg)
errorMessage = "Duplicated login";
break;
default:
- errorMessage = "Unkown error with 0x0081";
+ errorMessage = "Unknown error with 0x0081";
break;
}
mCharInfo->unlock();
diff --git a/src/net/equipmenthandler.cpp b/src/net/equipmenthandler.cpp
index 23a8063f..2e0cc562 100644
--- a/src/net/equipmenthandler.cpp
+++ b/src/net/equipmenthandler.cpp
@@ -117,6 +117,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
position++;
}
logger->log("Position %i", position);
+
item = player_node->getInventory()->getItem(player_node->mEquipment->getEquipment(position));
// Unequip any existing equipped item in this position
@@ -155,6 +156,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
break;
item->setEquipped(false);
+
if (equipPoint & 0x8000) { // Arrows
player_node->mEquipment->setArrows(0);
}
@@ -176,6 +178,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
break;
item = inventory->getItem(index);
+
if (item) {
item->setEquipped(true);
player_node->mEquipment->setArrows(index);
diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp
index 9a7aaabd..2b98e4e4 100644
--- a/src/net/loginhandler.cpp
+++ b/src/net/loginhandler.cpp
@@ -48,11 +48,11 @@ void LoginHandler::handleMessage(MessageIn *msg)
{
case 0x0063:
int len;
-
- len = msg->readInt16() - 4;
+
+ len = msg->readInt16() - 4;
mUpdateHost = msg->readString(len);
- logger->log("Received update host \"%s\" from login server",
+ logger->log("Received update host \"%s\" from login server",
mUpdateHost.c_str());
break;
@@ -107,10 +107,12 @@ void LoginHandler::handleMessage(MessageIn *msg)
errorMessage = "Rejected from server";
break;
case 4:
- errorMessage = "You have been blocked by the GM Team";
+
+ errorMessage = "You have been permanently banned from the game. Please contact the GM Team";
break;
case 6:
- errorMessage = "You have been temporarily banned from the game until " + msg->readString(20) + ".\n Please contact the GM team";
+ errorMessage = "You have been temporarily banned from the game until "
+ + msg->readString(20) + ".\n Please contact the GM team via the forums";
break;
case 9:
errorMessage = "This user name is already taken";
diff --git a/src/net/loginhandler.h b/src/net/loginhandler.h
index 1e087619..047434b4 100644
--- a/src/net/loginhandler.h
+++ b/src/net/loginhandler.h
@@ -25,6 +25,7 @@
#include <string>
#include "messagehandler.h"
+#include <string>
struct LoginData;
@@ -37,10 +38,8 @@ class LoginHandler : public MessageHandler
void setLoginData(LoginData *loginData) { mLoginData = loginData; };
- protected:
- LoginData *mLoginData;
-
private:
+ LoginData *mLoginData;
std::string mUpdateHost;
};
diff --git a/src/net/network.h b/src/net/network.h
index 856808a2..43b4dbbc 100644
--- a/src/net/network.h
+++ b/src/net/network.h
@@ -27,9 +27,9 @@
#include <SDL_thread.h>
#include <string>
-#define TMW_CLIENT_PROTOCOL_VERSION 1
- /***< Protocol version, reported to the eAthena char and mapserver who
- can adjust the protocol accordingly */
+#define TMW_CLIENT_PROTOCOL_VERSION 1
+ /**< Protocol version, reported to the eAthena char and mapserver who
+ can adjust the protocol accordingly */
class MessageHandler;
class MessageIn;
diff --git a/src/net/playerhandler.cpp b/src/net/playerhandler.cpp
index c8442a89..a4a2dcc9 100644
--- a/src/net/playerhandler.cpp
+++ b/src/net/playerhandler.cpp
@@ -133,7 +133,8 @@ void PlayerHandler::handleMessage(MessageIn *msg)
player_node->stopAttack();
nearby = (engine->getCurrentMapName() == mapPath);
- // Switch the actual map, deleting the previous one
+
+ // Switch the actual map, deleting the previous one if necessary
engine->changeMap(mapPath);
current_npc = 0;
diff --git a/src/net/protocol.h b/src/net/protocol.h
index fabe6911..783283ba 100644
--- a/src/net/protocol.h
+++ b/src/net/protocol.h
@@ -27,6 +27,7 @@
*********************************/
#define SMSG_LOGIN_SUCCESS 0x0073 /**< Contains starting location */
#define SMSG_SERVER_PING 0x007f /**< Contains server tick */
+#define SMSG_UPDATE_HOST 0x0063 /**< Custom update host packet */
#define SMSG_PLAYER_UPDATE_1 0x01d8
#define SMSG_PLAYER_UPDATE_2 0x01d9
#define SMSG_PLAYER_MOVE 0x01da /**< A nearby player moves */
diff --git a/src/net/tradehandler.cpp b/src/net/tradehandler.cpp
index 11fe2c19..746e1d06 100644
--- a/src/net/tradehandler.cpp
+++ b/src/net/tradehandler.cpp
@@ -127,7 +127,7 @@ void TradeHandler::handleMessage(MessageIn *msg)
chatWindow->chatLog("Trade with " + tradePartnerName +
" cancelled", BY_SERVER);
// otherwise ignore silently
-
+
tradeWindow->setVisible(false);
player_node->setTrading(false);
break;
@@ -186,7 +186,7 @@ void TradeHandler::handleMessage(MessageIn *msg)
"partner is over weighted.",
BY_SERVER);
break;
- case 2:
+ case 2:
// Add item failed - player has no free slot
chatWindow->chatLog("Failed adding item. Trade "
"partner has no free slot.",
diff --git a/src/npc.cpp b/src/npc.cpp
index 78670581..8dbbf83c 100644
--- a/src/npc.cpp
+++ b/src/npc.cpp
@@ -21,6 +21,7 @@
#include "animatedsprite.h"
#include "graphics.h"
+#include "localplayer.h"
#include "npc.h"
#include "particle.h"
#include "text.h"
@@ -42,7 +43,7 @@ NPC::NPC(Uint32 id, Uint16 job, Map *map, Network *network):
{
NPCInfo info = NPCDB::get(job);
- //setup NPC sprites
+ // Setup NPC sprites
int c = BASE_SPRITE;
for (std::list<NPCsprite*>::const_iterator i = info.sprites.begin();
i != info.sprites.end();
@@ -75,6 +76,7 @@ NPC::~NPC()
if (mName)
{
delete mName;
+ player_node->setTarget(NULL);
}
}
diff --git a/src/particlecontainer.cpp b/src/particlecontainer.cpp
new file mode 100644
index 00000000..12ef5733
--- /dev/null
+++ b/src/particlecontainer.cpp
@@ -0,0 +1,177 @@
+/*
+ * The Mana World
+ * Copyright 2008 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 <cassert>
+
+#include "particlecontainer.h"
+
+
+ParticleContainer::ParticleContainer(ParticleContainer *parent, bool delParent) :
+ mDelParent(delParent),
+ mNext(parent)
+{};
+
+ParticleContainer::~ParticleContainer()
+{
+ clearLocally();
+ if (mNext && mDelParent)
+ delete mNext;
+}
+
+void
+ParticleContainer::clear()
+{
+ clearLocally();
+ if (mNext)
+ mNext->clear();
+}
+
+
+void
+ParticleContainer::setPositions(float x, float y)
+{
+ if (mNext)
+ mNext->setPositions(x, y);
+}
+
+// -- particle list ----------------------------------------
+
+ParticleList::ParticleList(ParticleContainer *parent, bool delParent) :
+ ParticleContainer(parent, delParent) {};
+
+ParticleList::~ParticleList() {}
+
+void
+ParticleList::addLocally(Particle *particle)
+{
+ if (particle)
+ {
+ // The effect may not die without the beings permission or we segfault
+ particle->disableAutoDelete();
+ mElements.push_back(particle);
+ }
+}
+
+void
+ParticleList::removeLocally(Particle *particle)
+{
+ for (std::list<Particle *>::iterator it = mElements.begin();
+ it != mElements.end(); it++)
+ if (*it == particle) {
+ (*it)->kill();
+ mElements.erase(it);
+ }
+}
+
+void
+ParticleList::clearLocally()
+{
+ for (std::list<Particle *>::iterator it = mElements.begin();
+ it != mElements.end(); it++)
+ (*it)->kill();
+
+ mElements.clear();
+}
+
+void
+ParticleList::setPositions(float x, float y)
+{
+ ParticleContainer::setPositions(x, y);
+
+ for (std::list<Particle *>::iterator it = mElements.begin();
+ it != mElements.end();)
+ {
+ (*it)->setPosition(x, y);
+ if ((*it)->isExtinct())
+ {
+ (*it)->kill();
+ it = mElements.erase(it);
+ }
+ else
+ it++;
+ }
+}
+
+
+
+
+// -- particle vector ----------------------------------------
+
+ParticleVector::ParticleVector(ParticleContainer *parent, bool delParent) :
+ ParticleContainer(parent, delParent) {};
+
+ParticleVector::~ParticleVector() {};
+
+void
+ParticleVector::setLocally(int index, Particle *particle)
+{
+ assert(index >= 0);
+
+ delLocally(index);
+
+ if (mIndexedElements.size() <= (unsigned) index)
+ mIndexedElements.resize(index + 1, NULL);
+
+ mIndexedElements[index] = particle;
+}
+
+void
+ParticleVector::delLocally(int index)
+{
+ assert(index >= 0);
+
+ if (mIndexedElements.size() <= (unsigned) index)
+ return;
+
+ Particle *p = mIndexedElements[index];
+ if (p)
+ {
+ mIndexedElements[index] = NULL;
+ p->kill();
+ }
+}
+
+void
+ParticleVector::clearLocally()
+{
+ for (unsigned int i = 0; i < mIndexedElements.size(); i++)
+ delLocally(i);
+}
+
+void
+ParticleVector::setPositions(float x, float y)
+{
+ ParticleContainer::setPositions(x, y);
+
+ for (std::vector<Particle *>::iterator it = mIndexedElements.begin();
+ it != mIndexedElements.end(); it++)
+ if (*it)
+ {
+ (*it)->setPosition(x, y);
+
+ if ((*it)->isExtinct())
+ {
+ (*it)->kill();
+ *it = NULL;
+ }
+ }
+}
+
diff --git a/src/particlecontainer.h b/src/particlecontainer.h
new file mode 100644
index 00000000..cf002fbc
--- /dev/null
+++ b/src/particlecontainer.h
@@ -0,0 +1,125 @@
+/*
+ * The Mana World
+ * Copyright 2008 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
+ */
+
+#ifndef _PARTICLE_CONTAINER_H
+#define _PARTICLE_CONTAINER_H
+
+#include <list>
+#include <vector>
+
+#include "particle.h"
+
+
+/**
+ * Set of particle effects. May be stacked with other ParticleContainers. All
+ * operations herein affect such stacked containers, unless the operations end
+ * in `Locally'.
+ */
+class ParticleContainer
+{
+public:
+ /**
+ * Constructs a new particle container and assumes responsibility for
+ * its parent (for all operations defined herein, except when ending in `Locally')
+ *
+ * delParent means that the destructor should also free the parent.
+ */
+ ParticleContainer(ParticleContainer *parent = NULL, bool delParent = true);
+ virtual ~ParticleContainer();
+
+ /**
+ * Kills and removes all particle effects
+ */
+ void clear();
+
+ /**
+ * Kills and removes all particle effects (only in this container)
+ */
+ virtual void clearLocally() {};
+
+ /**
+ * Sets the positions of all elements
+ */
+ virtual void setPositions(float x, float y);
+
+protected:
+ bool mDelParent; /**< Delete mNext in destructor */
+ ParticleContainer *mNext; /**< Contained container, if any */
+};
+
+
+
+/**
+ * Linked list of particle effects.
+ */
+class ParticleList : public ParticleContainer
+{
+public:
+ ParticleList(ParticleContainer *parent = NULL, bool delParent = true);
+ virtual ~ParticleList();
+
+ /**
+ * Takes control of and adds a particle
+ */
+ void addLocally(Particle *);
+
+ /**
+ * `kills' and removes a particle
+ */
+ void removeLocally(Particle *);
+
+ virtual void clearLocally();
+
+ virtual void setPositions(float x, float y);
+
+protected:
+ std::list<Particle *> mElements; /**< Contained particle effects */
+};
+
+
+/**
+ * Particle container with indexing facilities
+ */
+class ParticleVector : public ParticleContainer
+{
+public:
+ ParticleVector(ParticleContainer *parent = NULL, bool delParent = true);
+ virtual ~ParticleVector();
+
+ /**
+ * Sets a particle at a specified index. Kills the previous particle
+ * there, if needed.
+ */
+ virtual void setLocally(int index, Particle *particle);
+
+ /**
+ * Removes a particle at a specified index
+ */
+ virtual void delLocally(int index);
+
+ virtual void clearLocally();
+ virtual void setPositions(float x, float y);
+
+protected:
+ std::vector<Particle *> mIndexedElements;
+};
+
+#endif
diff --git a/src/player.cpp b/src/player.cpp
index 1a7480db..e6244bb5 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -212,3 +212,4 @@ void Player::updateCoords()
mName->adviseXY(mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET);
}
}
+
diff --git a/src/player_relations.cpp b/src/player_relations.cpp
index 157cc09b..ef00a738 100644
--- a/src/player_relations.cpp
+++ b/src/player_relations.cpp
@@ -337,9 +337,9 @@ public:
virtual void
ignore(Player *player, unsigned int flags)
- {
- player->flash(200);
- }
+ {
+ player->flash(200);
+ }
};
class PIS_emote : public PlayerIgnoreStrategy
diff --git a/src/resources/colordb.cpp b/src/resources/colordb.cpp
index 46acaf39..3d2e15e0 100644
--- a/src/resources/colordb.cpp
+++ b/src/resources/colordb.cpp
@@ -56,8 +56,7 @@ void ColorDB::load()
TMWHair = true;
- if (doc)
- delete doc;
+ delete doc;
doc = new XML::Document(TMW_COLOR_FILE);
root = doc->rootNode();
@@ -67,8 +66,7 @@ void ColorDB::load()
mColors[0] = mFail;
mLoaded = true;
- if (doc)
- delete doc;
+ delete doc;
return;
}
@@ -91,8 +89,7 @@ void ColorDB::load()
}
}
- if (doc)
- delete doc;
+ delete doc;
mLoaded = true;
}
diff --git a/src/resources/imageset.h b/src/resources/imageset.h
index c7915212..26ce99ea 100644
--- a/src/resources/imageset.h
+++ b/src/resources/imageset.h
@@ -47,17 +47,17 @@ class ImageSet : public Resource
/**
* Returns the width of the images in the image set.
*/
- int getWidth() { return mWidth; };
+ int getWidth() const { return mWidth; };
/**
* Returns the height of the images in the image set.
*/
- int getHeight() { return mHeight; };
+ int getHeight() const { return mHeight; };
typedef std::vector<Image*>::size_type size_type;
Image* get(size_type i) const;
- size_type size() { return mImages.size(); }
+ size_type size() const { return mImages.size(); }
private:
std::vector<Image*> mImages;
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index 894cc4fc..b4beb558 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -240,7 +240,8 @@ MapReader::readMap(xmlNodePtr node, const std::string &path)
{
if (xmlStrEqual(objectNode->name, BAD_CAST "object"))
{
- const std::string objType = XML::getProperty(objectNode, "type", "");
+ const std::string objType =
+ XML::getProperty(objectNode, "type", "");
if (objType == "WARP" || objType == "NPC" ||
objType == "SCRIPT" || objType == "SPAWN")
@@ -249,12 +250,14 @@ MapReader::readMap(xmlNodePtr node, const std::string &path)
continue;
}
- const std::string objName = XML::getProperty(objectNode, "name", "");
+ const std::string objName =
+ XML::getProperty(objectNode, "name", "");
const int objX = XML::getProperty(objectNode, "x", 0);
const int objY = XML::getProperty(objectNode, "y", 0);
logger->log("- Loading object name: %s type: %s at %d:%d",
- objName.c_str(), objType.c_str(), objX, objY);
+ objName.c_str(), objType.c_str(),
+ objX, objY);
if (objType == "PARTICLE_EFFECT")
{
@@ -263,7 +266,9 @@ MapReader::readMap(xmlNodePtr node, const std::string &path)
continue;
}
- map->addParticleEffect(objName, objX + offsetX, objY + offsetY);
+ map->addParticleEffect(objName,
+ objX + offsetX,
+ objY + offsetY);
}
else
{
@@ -302,13 +307,14 @@ static void setTile(Map *map, MapLayer *layer, int x, int y, int gid)
// Set regular tile on a layer
Image * const img = set ? set->get(gid - set->getFirstGid()) : 0;
layer->setTile(x, y, img);
- } else {
+ } else {
// Set collision tile
map->setWalk(x, y, (!set || (gid - set->getFirstGid() == 0)));
- }
+ }
}
-void MapReader::readLayer(xmlNodePtr node, Map *map)
+void
+MapReader::readLayer(xmlNodePtr node, Map *map)
{
// Layers are not necessarily the same size as the map
const int w = XML::getProperty(node, "width", map->getWidth());
@@ -323,25 +329,25 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
MapLayer *layer = 0;
if (!isCollisionLayer) {
- layer = new MapLayer(offsetX, offsetY, w, h, isFringeLayer);
- map->addLayer(layer);
+ layer = new MapLayer(offsetX, offsetY, w, h, isFringeLayer);
+ map->addLayer(layer);
}
logger->log("- Loading layer \"%s\"", name.c_str());
int x = 0;
int y = 0;
-
+
// Load the tile data
for_each_xml_child_node(childNode, node)
{
if (!xmlStrEqual(childNode->name, BAD_CAST "data"))
- continue;
-
+ continue;
+
const std::string encoding =
- XML::getProperty(childNode, "encoding", "");
+ XML::getProperty(childNode, "encoding", "");
const std::string compression =
- XML::getProperty(childNode, "compression", "");
-
+ XML::getProperty(childNode, "compression", "");
+
if (encoding == "base64")
{
if (!compression.empty() && compression != "gzip") {
@@ -382,11 +388,11 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
unsigned char *inflated;
unsigned int inflatedSize =
inflateMemory(binData, binLen, inflated);
-
+
free(binData);
binData = inflated;
binLen = inflatedSize;
-
+
if (!inflated) {
logger->log("Error: Could not decompress layer!");
return;
@@ -400,11 +406,12 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
binData[i + 3] << 24;
setTile(map, layer, x, y, gid);
-
+
x++;
- if (x == w)
- {
+ if (x == w) {
x = 0; y++;
+
+ // When we're done, don't crash on too much data
if (y == h)
break;
}
@@ -418,17 +425,17 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
{
if (!xmlStrEqual(childNode2->name, BAD_CAST "tile"))
continue;
-
- const int gid = XML::getProperty(childNode2, "gid", -1);
- setTile(map, layer, x, y, gid);
-
- x++;
- if (x == w) {
- x = 0; y++;
- if (y >= h)
- break;
- }
- }
+
+ const int gid = XML::getProperty(childNode2, "gid", -1);
+ setTile(map, layer, x, y, gid);
+
+ x++;
+ if (x == w) {
+ x = 0; y++;
+ if (y >= h)
+ break;
+ }
+ }
}
if (y < h)
diff --git a/src/text.h b/src/text.h
index a370771d..173a5686 100644
--- a/src/text.h
+++ b/src/text.h
@@ -31,43 +31,41 @@ class TextManager;
class Text
{
- friend class TextManager;
+ friend class TextManager;
+
public:
/**
- * Constructor creates a text object to display on the screen
+ * Constructor creates a text object to display on the screen.
*/
Text(const std::string &text, int x, int y,
gcn::Graphics::Alignment alignment, gcn::Font *font,
gcn::Color colour);
/**
- * Allows the originator of the text to specify the ideal coordinates
+ * Destructor. The text is removed from the screen.
*/
- void
- adviseXY(int x, int y);
+ virtual ~Text();
/**
- * Remove the text from the screen
+ * Allows the originator of the text to specify the ideal coordinates.
*/
- virtual ~Text();
+ void adviseXY(int x, int y);
/**
- * Draws the text
+ * Draws the text.
*/
- virtual void
- draw(Graphics *graphics, int xOff, int yOff);
-
- protected:
+ virtual void draw(Graphics *graphics, int xOff, int yOff);
- int mX; /**< Actual x-value of left of text written */
- int mY; /**< Actual y-value of top of text written */
- int mWidth; /**< The width of the text */
- int mHeight; /**< The height of the text */
- int mXOffset; /**< The offset of mX from the desired x */
- static int mInstances; /**< Instances of text */
- gcn::Font *mFont; /**< The font used */
- std::string mText; /**< The text to display */
- gcn::Color mColour; /**< The colour of the text */
+ private:
+ int mX; /**< Actual x-value of left of text written. */
+ int mY; /**< Actual y-value of top of text written. */
+ int mWidth; /**< The width of the text. */
+ int mHeight; /**< The height of the text. */
+ int mXOffset; /**< The offset of mX from the desired x. */
+ static int mInstances; /**< Instances of text. */
+ gcn::Font *mFont; /**< The font used. */
+ std::string mText; /**< The text to display. */
+ gcn::Color mColour; /**< The colour of the text. */
};
class FlashText : public Text
@@ -90,10 +88,9 @@ class FlashText : public Text
/**
* Draws the text
*/
- virtual void
- draw(Graphics *graphics, int xOff, int yOff);
+ virtual void draw(Graphics *graphics, int xOff, int yOff);
private:
- int mTime; /**< Time left for flashing */
+ int mTime; /**< Time left for flashing */
};
#endif
diff --git a/src/tileset.h b/src/tileset.h
index fb5593ef..fb855831 100644
--- a/src/tileset.h
+++ b/src/tileset.h
@@ -17,8 +17,6 @@
* 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
- *
- * $Id: tileset.h 3753 2007-11-20 12:27:56Z b_lindeijer $
*/
#ifndef _TMW_TILESET_H_
diff --git a/src/utils/fastsqrt.h b/src/utils/fastsqrt.h
index 8da1d354..78768149 100644
--- a/src/utils/fastsqrt.h
+++ b/src/utils/fastsqrt.h
@@ -1,24 +1,24 @@
-/* A very fast function to calculate the approximate inverse square root of a
- * floating point value and a helper function that uses it for getting the
- * normal squareroot. For an explanation of the inverse squareroot function
- * read:
- * http://www.math.purdue.edu/~clomont/Math/Papers/2003/InvSqrt.pdf
- *
- * Unfortunately the original creator of this function seems to be unknown.
- */
-
-float fastInvSqrt(float x)
-{
- union { int i; float x; } tmp;
- float xhalf = 0.5f * x;
- tmp.x = x;
- tmp.i = 0x5f375a86 - (tmp.i >> 1);
- x = tmp.x;
- x = x * (1.5f - xhalf * x * x);
- return x;
-}
-
-float fastSqrt(float x)
-{
- return 1.0f / fastInvSqrt(x);
-}
+/* A very fast function to calculate the approximate inverse square root of a
+ * floating point value and a helper function that uses it for getting the
+ * normal squareroot. For an explanation of the inverse squareroot function
+ * read:
+ * http://www.math.purdue.edu/~clomont/Math/Papers/2003/InvSqrt.pdf
+ *
+ * Unfortunately the original creator of this function seems to be unknown.
+ */
+
+float fastInvSqrt(float x)
+{
+ union { int i; float x; } tmp;
+ float xhalf = 0.5f * x;
+ tmp.x = x;
+ tmp.i = 0x5f375a86 - (tmp.i >> 1);
+ x = tmp.x;
+ x = x * (1.5f - xhalf * x * x);
+ return x;
+}
+
+float fastSqrt(float x)
+{
+ return 1.0f / fastInvSqrt(x);
+}
diff --git a/src/winver.h b/src/winver.h
index 3c6e7aed..f56d0c6b 100644
--- a/src/winver.h
+++ b/src/winver.h
@@ -3,4 +3,4 @@
#define VER_MINOR 0
#define VER_RELEASE 27
#define VER_BUILD 0
-#define PACKAGE_VERSION "0.0.27"
+#define PACKAGE_VERSION "0.0.27"