summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--README4
-rwxr-xr-xconfigure.ac2
-rw-r--r--src/being.cpp49
-rw-r--r--src/being.h36
-rw-r--r--src/engine.cpp14
-rw-r--r--src/game.cpp174
-rw-r--r--src/game.h1
-rw-r--r--src/gui/chat.cpp14
-rw-r--r--src/gui/chat.h8
-rw-r--r--src/gui/gui.cpp13
-rw-r--r--src/gui/window.h2
-rw-r--r--src/main.cpp18
-rw-r--r--src/map.cpp29
-rw-r--r--src/map.h7
-rw-r--r--src/net/protocol.h3
-rw-r--r--src/resources/resourcemanager.cpp11
-rw-r--r--src/resources/resourcemanager.h35
-rw-r--r--src/sound.cpp44
-rw-r--r--src/sound.h11
20 files changed, 250 insertions, 228 deletions
diff --git a/ChangeLog b/ChangeLog
index 16e1e520..b92e463c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,7 +7,7 @@
- Added register button in login screen
- Added warning message to use at least 4 characters as user name
- Improved skin on scrollbars, arrows and slider
-- Improved sound engine and fade in and out option for music
+- Improved sound engine and added fade in and out option for music
- Now you can use right mouse button to attack (enables also ranged attacks)
- Sound samples are now loaded through resource manager
- Item information is now stored in an XML file
@@ -18,6 +18,7 @@
- Fixed speech and emoticons position
- Fixed long nicknames to be clipped in chat window
- Fixed speech and damage display to be framerate independent
+- Fixed rendering of some monsters and items in OpenGL mode
0.0.11.2 (8 April 2005)
- Damage text now floats upwards
diff --git a/README b/README
index d045f584..6d8f38f1 100644
--- a/README
+++ b/README
@@ -58,7 +58,7 @@ point to spend on basic skills.
Level 1: enables the ability to trade with others
Level 2: enables the ability to express emotions
-Level 3:enables character to sit
+Level 3: enables character to sit
Other levels are still not implemented.
@@ -73,4 +73,4 @@ or come visit us on our IRC channel:
- #manaworld @ irc.freenode.net
Otherwise check the AUTHORS file to have a list of developers and how to
-contact them. \ No newline at end of file
+contact them.
diff --git a/configure.ac b/configure.ac
index 41be8258..c5c90612 100755
--- a/configure.ac
+++ b/configure.ac
@@ -10,8 +10,6 @@ AC_PROG_INSTALL
AC_PROG_MAKE_SET
# Checks for libraries
-# (someone may want to exchange these symbols with
-# something more meaningful in the future /- kth5)
AC_CHECK_LIB([guichan], [gcnGuichanVersion], ,
AC_MSG_ERROR([ *** Unable to find Guichan library (guichan.sf.net)]))
diff --git a/src/being.cpp b/src/being.cpp
index 03649dc6..dd2b2333 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -148,7 +148,6 @@ void sort() {
}
Being::Being():
- damage(""),
id(0), job(0),
x(0), y(0), destX(0), destY(0), direction(0),
type(0), action(0), frame(0),
@@ -157,21 +156,23 @@ Being::Being():
speed(150),
emotion(0), emotion_time(0),
text_x(0), text_y(0),
- hairStyle(1), hairColor(1),
weapon(0),
speech_time(0),
damage_time(0),
showSpeech(false), showDamage(false),
- aspd(350)
+ aspd(350),
+ hairStyle(1), hairColor(1)
{
strcpy(name, "");
}
-Being::~Being() {
+Being::~Being()
+{
clearPath();
}
-void Being::clearPath() {
+void Being::clearPath()
+{
path.clear();
}
@@ -182,6 +183,13 @@ void Being::setPath(std::list<PATH_NODE> path)
walk_time = tick_time;
}
+void Being::setDestination(int destX, int destY)
+{
+ this->destX = destX;
+ this->destY = destY;
+ setPath(tiledMap->findPath(x, y, destX, destY));
+}
+
void Being::setHairColor(int color)
{
hairColor = color;
@@ -261,6 +269,9 @@ void Being::nextStep()
y = newY;
action = WALK;
walk_time += speed / 10;
+ if (this == player_node) {
+ walk_status = 1;
+ }
} else {
action = STAND;
if (this == player_node) {
@@ -274,16 +285,9 @@ void Being::drawSpeech(Graphics *graphics)
{
// Draw speech above this being
if (showSpeech) {
- //if (being->speech_color == makecol(255, 255, 255)) {
- // guiGraphics->drawText(being->speech,
- // being->text_x + 16, being->text_y - 60,
- // gcn::Graphics::CENTER);
- //}
- //else {
graphics->drawText(speech,
text_x + 20, text_y - 60,
gcn::Graphics::CENTER);
- //}
}
if (showDamage) {
graphics->drawText(damage,
@@ -293,20 +297,17 @@ void Being::drawSpeech(Graphics *graphics)
}
}
-bool Being::isPlayer() {
- if (job < 10)
- return true;
- return false;
+bool Being::isPlayer()
+{
+ return job < 10;
}
-bool Being::isNpc() {
- if (job > 45 && job <126)
- return true;
- return false;
+bool Being::isNpc()
+{
+ return job > 45 && job < 126;
}
-bool Being::isMonster() {
- if (job > 200)
- return true;
- return false;
+bool Being::isMonster()
+{
+ return job > 200;
}
diff --git a/src/being.h b/src/being.h
index dc90942d..c246aeaa 100644
--- a/src/being.h
+++ b/src/being.h
@@ -37,13 +37,8 @@ struct PATH_NODE {
unsigned short x, y;
};
-class Being {
- private:
- std::list<PATH_NODE> path;
- std::string speech;
- std::string damage;
- unsigned short hairStyle, hairColor;
-
+class Being
+{
public:
unsigned int id;
unsigned short job;
@@ -83,9 +78,9 @@ class Being {
void clearPath();
/**
- * Sets the new path for this being.
+ * Sets a new destination for this being to walk to.
*/
- void setPath(std::list<PATH_NODE> path);
+ void setDestination(int x, int y);
/**
* Puts a "speech balloon" above this being for the specified amount
@@ -104,7 +99,7 @@ class Being {
* @param time The amount of time the text should stay in milliseconds.
*/
void setDamage(const std::string &text, int time);
-
+
/**
* Sets the name for the being
*
@@ -121,12 +116,12 @@ class Being {
* Sets the hair style for this being.
*/
void setHairStyle(int style);
-
+
/**
* Gets the hair color for this being.
*/
unsigned short getHairColor();
-
+
/**
* Gets the hair style for this being.
*/
@@ -141,21 +136,32 @@ class Being {
* Draws the speech text above the being.
*/
void drawSpeech(Graphics *graphics);
-
+
/**
* Checks if the being is a player.
*/
bool isPlayer();
-
+
/**
* Checks if the being is a npc.
*/
bool isNpc();
-
+
/**
* Checks if the being is a monster.
*/
bool isMonster();
+
+ private:
+ /**
+ * Sets the new path for this being.
+ */
+ void setPath(std::list<PATH_NODE> path);
+
+ std::list<PATH_NODE> path;
+ std::string speech;
+ std::string damage;
+ unsigned short hairStyle, hairColor;
};
/** Add a Being to the list */
diff --git a/src/engine.cpp b/src/engine.cpp
index bed0b1d1..e013041f 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -145,7 +145,7 @@ Engine::Engine()
guiTop->add(debugInfo);
// Create dialogs
- chatWindow = new ChatWindow("./docs/chatlog.txt", 20);
+ chatWindow = new ChatWindow("chatlog.txt", 20);
statusWindow = new StatusWindow();
buyDialog = new BuyDialog();
sellDialog = new SellDialog();
@@ -183,7 +183,7 @@ Engine::Engine()
requestTradeDialog->setPosition(screen->w - statusWindow->getWidth() -
requestTradeDialog->getWidth() - 10,
chatWindow->getHeight() + 15);
-
+
// Set initial window visibility
chatWindow->setVisible(true);
statusWindow->setVisible(true);
@@ -204,7 +204,7 @@ Engine::Engine()
requestTradeDialog->setVisible(false);
// Do not focus any text field
gui->focusNone();
-
+
// Load the sprite sets
ResourceManager *resman = ResourceManager::getInstance();
Image *npcbmp = resman->getImage(
@@ -225,7 +225,7 @@ Engine::Engine()
emotionset = new Spriteset(emotionbmp, 19, 19);
weaponset = new Spriteset(weaponbitmap, 160, 120);
itemset = new Spriteset(itembitmap, 20, 20);
-
+
// Loads all the monsters
for (int i = 0; i < MONSTERS_NUMBER; i++)
{
@@ -289,7 +289,7 @@ void Engine::logic()
break;
}
}
-
+
if (get_elapsed_time(being->speech_time) > 5000)
being->showSpeech = false;
if (get_elapsed_time(being->damage_time) > 3000)
@@ -427,7 +427,7 @@ void Engine::draw()
being->text_y = sy * 32 - 65 + get_y_offset(being) - offset_y;
int mf = being->frame + being->action;
-
+
if (being->action == MONSTER_DEAD) {
monsterset[being->job - 1002]->spriteset[dir + 4 * MONSTER_DEAD]->draw(screen,
being->text_x + 30, being->text_y + 40);
@@ -446,7 +446,7 @@ void Engine::draw()
}
}
}
-
+
beingIterator++;
// nodes are ordered so if the next being y is > then the
diff --git a/src/game.cpp b/src/game.cpp
index ffc6ebd9..87c59354 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -182,7 +182,7 @@ void do_init()
add_node(player_node);
- remove("./docs/packet.list");
+ remove("packet.list");
}
void do_exit()
@@ -402,13 +402,14 @@ void do_input()
keys = SDL_GetKeyState(NULL);
int xDirection = 0;
int yDirection = 0;
- int Direction = 0;
+ int Direction = DIR_NONE;
if (walk_status == 0 && player_node->action != DEAD && current_npc == 0)
{
int x = player_node->x;
int y = player_node->y;
+ // Translate pressed keys to movement
if (keys[SDLK_UP] || keys[SDLK_KP8])
{
yDirection = -1;
@@ -446,92 +447,68 @@ void do_input()
yDirection = -1;
}
- if ( xDirection == 1 && yDirection == 0 ) // Right
+ // Translate movement to direction
+ if (xDirection == 1 && yDirection == 0) // Right
{
Direction = EAST;
}
- if ( xDirection == -1 && yDirection == 0 ) // Left
+ if (xDirection == -1 && yDirection == 0) // Left
{
Direction = WEST;
}
- if ( xDirection == 0 && yDirection == -1 ) // Up
+ if (xDirection == 0 && yDirection == -1) // Up
{
Direction = NORTH;
}
- if ( xDirection == 0 && yDirection == 1 ) // Down
+ if (xDirection == 0 && yDirection == 1) // Down
{
Direction = SOUTH;
}
- if ( xDirection == 1 && yDirection == 1 ) // Bottom-Right
+ if (xDirection == 1 && yDirection == 1) // Bottom-Right
{
Direction = SE;
}
- if ( xDirection == -1 && yDirection == -1 ) // Top-left
+ if (xDirection == -1 && yDirection == -1) // Top-left
{
Direction = NW;
}
- if ( xDirection == 1 && yDirection == -1 ) // Top-Right
+ if (xDirection == 1 && yDirection == -1) // Top-Right
{
Direction = NE;
}
- if ( xDirection == -1 && yDirection == 1 ) // Bottom-Left
+ if (xDirection == -1 && yDirection == 1) // Bottom-Left
{
Direction = SW;
}
- if ( xDirection != 0 || yDirection != 0 )
+ // Update the player direction to where he wants to walk
+ // Warning: Not communicated to the server yet
+ if (Direction != DIR_NONE) {
+ player_node->direction = Direction;
+ }
+
+ // Prevent skipping corners over colliding tiles
+ if (xDirection != 0 && tiledMap->tileCollides(x + xDirection, y)) {
+ xDirection = 0;
+ }
+ if (yDirection != 0 && tiledMap->tileCollides(x, y + yDirection)) {
+ yDirection = 0;
+ }
+
+ // Choose a straight direction when diagonal target is blocked
+ if (yDirection != 0 && xDirection != 0 &&
+ !tiledMap->getWalk(x + xDirection, y + yDirection)) {
+ xDirection = 0;
+ }
+
+ // Walk to where the player can actually go
+ if ((xDirection != 0 || yDirection != 0) &&
+ tiledMap->getWalk(x + xDirection, y + yDirection))
{
- if (tiledMap->getWalk(x + xDirection, y + yDirection) != 0)
- {
- walk(x + xDirection, y + yDirection, Direction);
- walk_status = 1;
- player_node->action = WALK;
- player_node->walk_time = tick_time;
- player_node->x = x + xDirection;
- player_node->y = y + yDirection;
- player_node->direction = Direction;
- }
- else if (tiledMap->getWalk(x + xDirection, y) != 0)
- { // Going back to straight direction Left or right
- if ( xDirection == 1 ) //right
- {
- Direction = EAST;
- }
- else // left
- {
- Direction = WEST;
- }
- yDirection = 0;
- walk(x + xDirection, y + yDirection, Direction);
- walk_status = 1;
- player_node->action = WALK;
- player_node->walk_time = tick_time;
- player_node->x = x + xDirection;
- player_node->y = y + yDirection;
- player_node->direction = Direction;
- }
- else if (tiledMap->getWalk(x, y + yDirection) != 0)
- { // Going back to straight direction up or down
- if ( yDirection == 1 ) //Down
- {
- Direction = SOUTH;
- }
- else // Up
- {
- Direction = NORTH;
- }
- xDirection = 0;
- walk(x + xDirection, y + yDirection, Direction);
- walk_status = 1;
- player_node->action = WALK;
- player_node->walk_time = tick_time;
- player_node->x = x + xDirection;
- player_node->y = y + yDirection;
- player_node->direction = Direction;
- }
- else player_node->direction = Direction;
+ walk(x + xDirection, y + yDirection, Direction);
+ player_node->setDestination(x + xDirection, y + yDirection);
}
-
+
if (player_node->action == STAND)
{
if (keys[SDLK_LCTRL])
@@ -541,24 +518,27 @@ void do_input()
player_node->y,
player_node->direction);
player_node->walk_time = tick_time;
-
- if (player_node->weapon == 2)
+
+ if (player_node->weapon == 2) {
sound.playSfx("sfx/bow_shoot_1.ogg");
- else
+ }
+ else {
sound.playSfx("sfx/fist-swish.ogg");
+ }
}
}
-
- } // End if alive
+ }
}
-int get_packet_length(short id) {
+int get_packet_length(short id)
+{
int len = get_length(id);
if (len == -1) len = RFIFOW(2);
return len;
}
-void do_parse() {
+void do_parse()
+{
unsigned short id;
char *temp;
Being *being = NULL;
@@ -585,7 +565,7 @@ void do_parse() {
fclose(file);
*/
#ifdef __DEBUG
- FILE *file = fopen("./docs/packet.list", "a");
+ FILE *file = fopen("packet.list", "a");
fprintf(file, "%x\n", RFIFOW(0));
fclose(file);
#endif
@@ -597,32 +577,39 @@ void do_parse() {
player_node->y = get_y(RFIFOP(6));
break;
- // Received speech
- case 0x008d:
- temp = (char *)malloc(RFIFOW(2)-7);
- memset(temp, '\0', RFIFOW(2)-7);
- memcpy(temp, RFIFOP(8), RFIFOW(2)-8);
+ // Received speech from being
+ case SMSG_BEING_CHAT:
being = findNode(RFIFOL(4));
if (being != NULL) {
- // White
- being->setSpeech(temp, SPEECH_TIME);
+ int length = RFIFOW(2) - 8;
+ temp = (char*)malloc(length + 1);
+ temp[length] = '\0';
+ memcpy(temp, RFIFOP(8), length);
+ std::string msg = std::string(temp);
+ msg.erase(0, msg.find(" : ", 0) + 3);
+
+ being->setSpeech(msg, SPEECH_TIME);
chatWindow->chat_log(temp, BY_OTHER);
+
+ free(temp);
}
- free(temp);
break;
- case 0x008e:
- case 0x009a:
- if (RFIFOW(2) > 4) {
- // Receiving 1 byte less than expected, server might be
- // sending garbage instead of '\0' /-kth5
- temp = (char *)malloc(RFIFOW(2) - 3);
- memset(temp, '\0', RFIFOW(2) - 3);
- memcpy(temp, RFIFOP(4), RFIFOW(2) - 4);
- // White
- player_node->setSpeech(temp, SPEECH_TIME);
+ case SMSG_MY_BEING_CHAT:
+ case SMSG_GM_CHAT:
+ if (RFIFOW(2) > 4) {
+ int length = RFIFOW(2) - 4;
+ temp = (char*)malloc(length + 1);
+ temp[length] = '\0';
+ memcpy(temp, RFIFOP(4), length);
+ std::string msg = std::string(temp);
+ unsigned int pos = msg.find(" : ", 0);
if (id == 0x008e) {
+ if (pos != std::string::npos) {
+ msg.erase(0, pos + 3);
+ }
+ player_node->setSpeech(msg, SPEECH_TIME);
chatWindow->chat_log(temp, BY_PLAYER);
}
else {
@@ -632,6 +619,7 @@ void do_parse() {
free(temp);
}
break;
+
// Success to walk request
case 0x0087:
if (walk_status == 1) {
@@ -734,9 +722,9 @@ void do_parse() {
being->job = RFIFOW(14);
being->weapon = RFIFOW(18);
- being->setPath(tiledMap->findPath(
- being->x, being->y,
- being->destX, being->destY));
+ being->setDestination(
+ get_dest_x(RFIFOP(50)),
+ get_dest_y(RFIFOP(50)));
break;
case SMSG_MOVE_PLAYER_BEING:
@@ -759,9 +747,9 @@ void do_parse() {
being->setHairStyle(RFIFOW(16));
being->setHairColor(RFIFOW(32));
- being->setPath(tiledMap->findPath(
- being->x, being->y,
- being->destX, being->destY));
+ being->setDestination(
+ get_dest_x(RFIFOP(50)),
+ get_dest_y(RFIFOP(50)));
break;
// NPC dialog
diff --git a/src/game.h b/src/game.h
index 96c6ca5c..5759e617 100644
--- a/src/game.h
+++ b/src/game.h
@@ -47,6 +47,7 @@
#define LOCK 254
#define IDLE 255
+#define DIR_NONE -1
#define SOUTH 0
#define SW 1
#define WEST 2
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index b7051a3b..fac868c5 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -69,15 +69,15 @@ void ChatWindow::chat_log(std::string line, int own)
pos = 0;
pos = (int)line.find(" : ", 0);
if (pos > 0) {
- tmp.nick = line.substr(0,pos);
+ tmp.nick = line.substr(0, pos);
switch (own) {
- case ACT_IS :
+ case ACT_IS:
tmp.nick += CAT_IS;
break;
- case ACT_WHISPER :
+ case ACT_WHISPER:
tmp.nick += CAT_WHISPER;
break;
- default :
+ default:
tmp.nick += CAT_NORMAL;
}
line.erase(0, pos + 3);
@@ -85,7 +85,7 @@ void ChatWindow::chat_log(std::string line, int own)
tmp.nick = "";
}
tmp.own = own;
-
+
// A try to get text sentences no too long...
bool finished = false;
unsigned int maxLength = 80;
@@ -94,7 +94,7 @@ void ChatWindow::chat_log(std::string line, int own)
{
std::string tempText;
if (line.length() > maxLength)
- {
+ {
tempText = line;
if (line.length() > maxLength)
@@ -108,7 +108,7 @@ void ChatWindow::chat_log(std::string line, int own)
chatlog.push_front(tmp);
}
else // Normal message
- {
+ {
tmp.text = line;
//chatlog_file << tmp.nick << tmp.text << "\n";
//chatlog_file.flush();
diff --git a/src/gui/chat.h b/src/gui/chat.h
index ad3d5e39..4aabe4c2 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -136,14 +136,14 @@ class ChatWindow : public Window, public gcn::ActionListener {
* Request focus.
*/
void requestFocus();
-
+
/**
- * Checks wether ChatWindow is Focused or not
+ * Checks whether ChatWindow is Focused or not.
*/
bool isFocused();
-
+
/*
- * Determines wether to send a command or an ordinary message, then
+ * Determines whether to send a command or an ordinary message, then
* contructs packets & sends them
*
* @param nick The character's name to display in front.
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 6a57f214..d9ab90bd 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -34,7 +34,8 @@ Graphics *guiGraphics; // Graphics driver
gcn::SDLInput *guiInput; // GUI input
WindowContainer *guiTop; // The top container
-Gui::Gui(Graphics *graphics)
+Gui::Gui(Graphics *graphics):
+ hostImageLoader(NULL)
{
// Set graphics
guiGraphics = graphics;
@@ -75,9 +76,9 @@ Gui::~Gui()
delete guiFont;
delete guiTop;
delete imageLoader;
-#ifdef USE_OPENGL
- delete hostImageLoader;
-#endif
+ if (hostImageLoader) {
+ delete hostImageLoader;
+ }
delete guiInput;
}
@@ -108,9 +109,7 @@ void Gui::mousePress(int mx, int my, int button)
if (state == GAME && tiledMap->getWalk(tilex, tiley)) {
walk(tilex, tiley, 0);
- player_node->setPath(tiledMap->findPath(
- player_node->x, player_node->y,
- tilex, tiley));
+ player_node->setDestination(tilex, tiley);
}
}
}
diff --git a/src/gui/window.h b/src/gui/window.h
index f2f87cc0..4a0f08c3 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -163,7 +163,7 @@ class Window : public gcn::Window, public ConfigListener
Window *getParentWindow();
/**
- * Returns wether this window is modal. This doesn't necessarily mean
+ * Returns whether this window is modal. This doesn't necessarily mean
* that is gets input as a child modal window could get it.
*/
bool isModal();
diff --git a/src/main.cpp b/src/main.cpp
index 5c62700f..0037e4f4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -66,6 +66,7 @@ char map_name[16];
unsigned char state;
unsigned char screen_mode;
char *dir = NULL;
+char *homeDir = NULL;
int displayFlags, screenW, screenH, bitDepth;
bool useOpenGL = false;
@@ -120,11 +121,15 @@ void init_engine()
dir = new char[400];
strcpy(dir, "");
+ homeDir = new char[256];
#ifndef __USE_UNIX98
// WIN32 and others
strcpy(dir, "config.xml");
+
+ // In Windows and other systems we currently store data next to executable.
+ strcpy(homeDir, "");
#else
- // UNIX
+ // In UNIX we store data in ~/.manaworld/
char *userHome;
char *name = getlogin();
passwd *pass;
@@ -152,6 +157,8 @@ void init_engine()
exit(1);
}
sprintf(dir, "%s/.manaworld/config.xml", userHome);
+
+ //strcpy(homeDir, "%s/.manaworld/", userHome);
#endif
// Checking if the configuration file exists... otherwise creates it with
@@ -177,18 +184,9 @@ void init_engine()
config.setValue("screen", 0);
config.setValue("sound", 1);
config.setValue("guialpha", 0.8f);
-#ifdef __USE_UNIX98
- char *chatlogFilename = new char[400];
- sprintf(chatlogFilename, "%s/.manaworld/chatlog.txt", userHome);
- config.setValue("chatlog", chatlogFilename);
- delete chatlogFilename;
-#else
- config.setValue("chatlog", "chatlog.txt");
-#endif
config.setValue("remember", 1);
config.setValue("sfxVolume", 100);
config.setValue("musicVolume", 60);
-
config.write(dir);
}
}
diff --git a/src/map.cpp b/src/map.cpp
index df9aafc5..a658d8c6 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -222,27 +222,32 @@ void Map::setWalk(int x, int y, bool walkable)
bool Map::getWalk(int x, int y)
{
- // You can't walk outside of the map
- if (x < 0 || y < 0 || x >= width || y >= height) {
- return false;
- }
-
- // Check if the tile is walkable
- bool ret = metaTiles[x + y * width].walkable;
-
// If walkable, check for colliding into a being
- if (ret) {
+ if (!tileCollides(x, y)) {
std::list<Being*>::iterator i = beings.begin();
- while (i != beings.end() && ret) {
+ while (i != beings.end()) {
Being *being = (*i);
if (being->x == x && being->y == y) {
return false;
}
i++;
}
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+bool Map::tileCollides(int x, int y)
+{
+ // You can't walk outside of the map
+ if (x < 0 || y < 0 || x >= width || y >= height) {
+ return true;
}
- return ret;
+ // Check if the tile is walkable
+ return !metaTiles[x + y * width].walkable;
}
void Map::setTile(int x, int y, int layer, Image *img)
@@ -405,7 +410,7 @@ std::list<PATH_NODE> Map::findPath(
}
}
- // Two new values to indicate wether a tile is on the open or closed list,
+ // Two new values to indicate whether a tile is on the open or closed list,
// this way we don't have to clear all the values between each pathfinding.
onClosedList += 2;
onOpenList += 2;
diff --git a/src/map.h b/src/map.h
index d56928d0..38d63285 100644
--- a/src/map.h
+++ b/src/map.h
@@ -129,11 +129,16 @@ class Map
void setWalk(int x, int y, bool walkable);
/**
- * Tell if a tile is walkable or not
+ * Tell if a tile is walkable or not, includes checking beings.
*/
bool getWalk(int x, int y);
/**
+ * Tell if a tile collides, not including a check on beings.
+ */
+ bool tileCollides(int x, int y);
+
+ /**
* Returns the width of this map.
*/
int getWidth();
diff --git a/src/net/protocol.h b/src/net/protocol.h
index ea746412..9a755e63 100644
--- a/src/net/protocol.h
+++ b/src/net/protocol.h
@@ -32,6 +32,9 @@
#define SMSG_PLAYER_UPDATE_2 0x01d9 //
#define SMSG_MOVE_PLAYER_BEING 0x01da // A nearby player moves
#define SMSG_CHANGE_BEING_LOOKS 0x00c3 //
+#define SMSG_BEING_CHAT 0x008d // A being talks
+#define SMSG_MY_BEING_CHAT 0x008e // My being talks
+#define SMSG_GM_CHAT 0x009a // GM announce
/** Packet length by id */
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index b26aeb5d..8606816e 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -286,16 +286,19 @@ void *ResourceManager::loadFile(const std::string &fileName, int &fileSize)
PHYSFS_file* file = PHYSFS_openRead(fileName.c_str());
// If the handler is an invalid pointer indicate failure
- if (file == NULL) return NULL;
+ if (file == NULL) {
+ logger.log("Warning: %s failed to load!", fileName.c_str());
+ return NULL;
+ }
- // Print file information message
+ // Get the size of the file
fileSize = PHYSFS_fileLength(file);
- // Allocate memory in the buffer and load the file
+ // Allocate memory and load the file
void *buffer = malloc(fileSize);
PHYSFS_read(file, buffer, 1, fileSize);
- // Close the file and let the user deallocate the memory (safe?)
+ // Close the file and let the user deallocate the memory
PHYSFS_close(file);
return buffer;
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index d8f4cb90..3c72eb43 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -88,13 +88,36 @@ class ResourceManager
int flags = 0);
/**
- * Convenience wrappers around ResourceManager::create.
+ * Convenience wrapper around ResourceManager::create for loading
+ * images.
*/
Image *getImage(const std::string &idPath, int flags = 0);
+
+ /**
+ * Convenience wrapper around ResourceManager::create for loading
+ * songs.
+ */
Music *getMusic(const std::string &idPath);
+
+ /**
+ * Convenience wrapper around ResourceManager::create for loading
+ * samples.
+ */
SoundEffect *getSoundEffect(const std::string &idPath);
/**
+ * Allocates data into a buffer pointer for raw data loading. The
+ * returned data is expected to be freed using <code>free()</code>.
+ *
+ * @param fileName The name of the file to be loaded.
+ * @param fileSize The size of the file that was loaded.
+ *
+ * @return An allocated byte array containing the data that was loaded,
+ * or <code>NULL</code> on fail.
+ */
+ void *loadFile(const std::string &fileName, int &fileSize);
+
+ /**
* Returns an instance of the class, creating one if it does not
* already exist.
*/
@@ -111,16 +134,6 @@ class ResourceManager
*/
void searchAndAddZipFiles();
- /**
- * Allocates data into a buffer pointer for raw data loading
- *
- * @param fileName The name of the file to be loaded
- * @param buffer The empty buffer into which the data will be loaded
- *
- * @return The size of the file that was loaded
- */
- void *loadFile(const std::string &fileName, int &fileSize);
-
static ResourceManager *instance;
std::map<std::string, ResourceEntry> resources;
diff --git a/src/sound.cpp b/src/sound.cpp
index 9b16a063..332fc3a2 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -42,31 +42,31 @@ void Sound::init()
{
// Don't initialize sound engine twice
if (installed) return;
-
+
logger.log("Sound::init() Initializing sound...");
-
+
if (SDL_InitSubSystem(SDL_INIT_AUDIO) == -1) {
logger.log("Sound::init() Failed to initialize audio subsystem");
return;
}
- const size_t audioBuffer = 4096;
+ const size_t audioBuffer = 4096;
- const int res = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT,
+ const int res = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT,
2, audioBuffer);
- if (res >= 0) {
- Mix_AllocateChannels(16);
- } else {
- logger.log("Sound::init Could not initialize audio: %s",
+ if (res >= 0) {
+ Mix_AllocateChannels(16);
+ } else {
+ logger.log("Sound::init Could not initialize audio: %s",
Mix_GetError());
return;
- }
-
- info();
+ }
+
+ info();
music = NULL;
-
- installed = true;
+
+ installed = true;
}
void Sound::info() {
@@ -77,12 +77,12 @@ void Sound::info() {
int rate = 0;
Uint16 audioFormat = 0;
int channels = 0;
-
+
MIX_VERSION(&compiledVersion);
linkedVersion = Mix_Linked_Version();
-
+
SDL_AudioDriverName(driver, 40);
-
+
Mix_QuerySpec(&rate, &audioFormat, &channels);
switch (audioFormat) {
case AUDIO_U8: format = "U8"; break;
@@ -92,7 +92,7 @@ void Sound::info() {
case AUDIO_U16MSB: format = "U16MSB"; break;
case AUDIO_S16MSB: format = "S16MSB"; break;
}
-
+
logger.log("Sound::info() SDL_mixer: %i.%i.%i (compiled)",
compiledVersion.major,
compiledVersion.minor,
@@ -110,7 +110,7 @@ void Sound::info() {
void Sound::setMusicVolume(int volume)
{
if (!installed) return;
-
+
musicVolume = volume;
Mix_VolumeMusic(volume);
}
@@ -118,7 +118,7 @@ void Sound::setMusicVolume(int volume)
void Sound::setSfxVolume(int volume)
{
if (!installed) return;
-
+
sfxVolume = volume;
Mix_Volume(-1, volume);
}
@@ -126,11 +126,11 @@ void Sound::setSfxVolume(int volume)
void Sound::playMusic(const char *path, int loop)
{
if (!installed) return;
-
+
if (music != NULL) {
stopMusic();
}
-
+
logger.log("Sound::startMusic() Playing \"%s\" %i times", path, loop);
music = Mix_LoadMUS(path);
@@ -147,7 +147,7 @@ void Sound::stopMusic()
if (!installed) return;
logger.log("Sound::stopMusic()");
-
+
if (music != NULL) {
Mix_HaltMusic();
Mix_FreeMusic(music);
diff --git a/src/sound.h b/src/sound.h
index 27748fb6..401a90f4 100644
--- a/src/sound.h
+++ b/src/sound.h
@@ -50,7 +50,7 @@ class Sound {
* Installs the sound engine.
*/
void init();
-
+
/**
* Logs various info about sound device.
*/
@@ -73,7 +73,7 @@ class Sound {
* Stops currently running background music track.
*/
void stopMusic();
-
+
/**
* Fades in background music.
*
@@ -89,7 +89,7 @@ class Sound {
* \param ms Duration of fade-out effect (ms)
*/
void fadeOutMusic(int ms);
-
+
/**
* Sets music volume.
*
@@ -110,11 +110,12 @@ class Sound {
* \param path Full path to file
*/
void playSfx(const char *path);
-
+
private:
bool installed;
- int musicVolume, sfxVolume;
+ int sfxVolume;
+ int musicVolume;
Mix_Music *music;
};