summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp135
-rw-r--r--src/being.h44
-rw-r--r--src/engine.cpp46
-rw-r--r--src/game.cpp141
-rw-r--r--src/gui/setup.cpp2
-rw-r--r--src/main.cpp20
-rw-r--r--src/map.cpp22
-rw-r--r--src/map.h4
-rw-r--r--src/net/protocol.h2
-rw-r--r--src/sound.cpp5
10 files changed, 195 insertions, 226 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 6ae01f77..93496ea6 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -30,18 +30,10 @@ Being *player_node = NULL;
std::list<Being*> beings;
PATH_NODE::PATH_NODE(unsigned short x, unsigned short y):
- x(x), y(y), next(NULL)
+ x(x), y(y)
{
}
-void empty() {
- std::list<Being *>::iterator i;
- for (i = beings.begin(); i != beings.end(); i++) {
- delete (*i);
- }
- beings.clear();
-}
-
void add_node(Being *being) {
beings.push_back(being);
}
@@ -109,11 +101,11 @@ void sort() {
}
Being::Being():
- path(NULL),
+ speech_time(0),
id(0), job(0),
x(0), y(0), destX(0), destY(0), direction(0),
type(0), action(0), frame(0),
- speech(NULL), speech_time(0), speech_color(0),
+ speech_color(0),
walk_time(0),
speed(150),
emotion(0), emotion_time(0),
@@ -125,91 +117,64 @@ Being::Being():
Being::~Being() {
clearPath();
- if (speech) {
- free(speech);
- }
}
void Being::clearPath() {
- PATH_NODE *temp = path;
- PATH_NODE *next;
- while (temp) {
- next = temp->next;
- delete temp;
- temp = next;
- }
- path = NULL;
+ path.clear();
}
-
-void Being::setPath(PATH_NODE *path)
+void Being::setPath(std::list<PATH_NODE> path)
{
- clearPath();
this->path = path;
- if (path != NULL) {
- direction = 0;
- if (path->next) {
- if (path->next->x > path->x && path->next->y > path->y)
- direction = SE;
- else if (path->next->x < path->x && path->next->y > path->y)
- direction = SW;
- else if (path->next->x > path->x && path->next->y < path->y)
- direction = NE;
- else if (path->next->x < path->x && path->next->y < path->y)
- direction = NW;
- else if (path->next->x > path->x)
- direction = EAST;
- else if (path->next->x < path->x)
- direction = WEST;
- else if (path->next->y > path->y)
- direction = SOUTH;
- else if (path->next->y < path->y)
- direction = NORTH;
- }
- PATH_NODE *pn = path;
- this->path = path->next;
- delete pn;
- x = this->path->x;
- y = this->path->y;
- action = WALK;
- walk_time = tick_time;
- frame = 0;
- }
+ nextStep();
}
-bool Being::hasPath()
+void Being::setHairColor(int color)
{
- return path != NULL;
+ hair_color = color;
+}
+
+void Being::setHairStyle(int style)
+{
+ hair_style = style;
+}
+
+void Being::setSpeech(const std::string &text, int time)
+{
+ speech = text;
+ speech_time = time;
}
void Being::nextStep()
{
- if (path && path->next) {
- int old_x, old_y, new_x, new_y;
- old_x = path->x;
- old_y = path->y;
- path = path->next;
- new_x = path->x;
- new_y = path->y;
+ if (!path.empty()) {
+ PATH_NODE node = path.front();
+ path.pop_front();
+
+ int oldX = x;
+ int oldY = y;
+ int newX = node.x;
+ int newY = node.y;
direction = 0;
- if (new_x > old_x) {
- if (new_y > old_y) direction = SE;
- else if (new_y < old_y) direction = NE;
+ if (newX > oldX) {
+ if (newY > oldY) direction = SE;
+ else if (newY < oldY) direction = NE;
else direction = EAST;
}
- else if (new_x < old_x) {
- if (new_y > old_y) direction = SW;
- else if (new_y < old_y) direction = NW;
+ else if (newX < oldX) {
+ if (newY > oldY) direction = SW;
+ else if (newY < oldY) direction = NW;
else direction = WEST;
}
else {
- if (new_y > old_y) direction = SOUTH;
- else if (new_y < old_y) direction = NORTH;
+ if (newY > oldY) direction = SOUTH;
+ else if (newY < oldY) direction = NORTH;
}
- x = path->x;
- y = path->y;
+ x = newX;
+ y = newY;
+ action = WALK;
} else {
action = STAND;
if (this == player_node) {
@@ -219,3 +184,27 @@ void Being::nextStep()
frame = 0;
walk_time = tick_time;
}
+
+void Being::drawSpeech(Graphics *graphics)
+{
+ // Draw speech above this being
+ if (speech_time > 0) {
+ //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 + 60, text_y - 60,
+ gcn::Graphics::CENTER);
+ //}
+ }
+}
+
+void Being::tick()
+{
+ if (speech_time > 0) {
+ speech_time--;
+ }
+}
diff --git a/src/being.h b/src/being.h
index 657a0658..cc357ff3 100644
--- a/src/being.h
+++ b/src/being.h
@@ -25,6 +25,8 @@
#define _TMW_BEING_H
#include <list>
+#include <string>
+#include "graphics.h"
struct PATH_NODE {
/**
@@ -33,12 +35,13 @@ struct PATH_NODE {
PATH_NODE(unsigned short x, unsigned short y);
unsigned short x, y;
- PATH_NODE *next;
};
class Being {
private:
- PATH_NODE *path;
+ std::list<PATH_NODE> path;
+ std::string speech;
+ unsigned char speech_time;
public:
unsigned int id;
@@ -49,8 +52,6 @@ class Being {
unsigned char type;
unsigned char action;
unsigned char frame;
- char *speech;
- unsigned char speech_time;
int speech_color;
unsigned short walk_time;
unsigned short speed;
@@ -78,21 +79,44 @@ class Being {
/**
* Sets the new path for this being.
*/
- void setPath(PATH_NODE *path);
+ void setPath(std::list<PATH_NODE> path);
+
+ /**
+ * Puts a "speech balloon" above this being for the specified amount
+ * of time.
+ *
+ * @param text The text that should appear.
+ * @param time The amount of time the text should stay in milliseconds.
+ */
+ void setSpeech(const std::string &text, int time);
+
+ /**
+ * Sets the hair color for this being.
+ */
+ void setHairColor(int color);
/**
- * Returns wether this being has a path to follow.
+ * Sets the hair style for this being.
*/
- bool hasPath();
+ void setHairStyle(int style);
/**
* Makes this being take the next step of his path.
*/
void nextStep();
-};
-/** Removes all beings from the list */
-void empty();
+ /**
+ * Draws the speech text above the being.
+ */
+ void drawSpeech(Graphics *graphics);
+
+ /**
+ * Tick gives the being a sense of time. It should be called either a
+ * specific amount of times per second, or be modified to be passed a
+ * number that tells it the time since the last call.
+ */
+ void tick();
+};
/** Add a Being to the list */
void add_node(Being *being);
diff --git a/src/engine.cpp b/src/engine.cpp
index 8ba4e7ea..36e6c212 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -407,10 +407,8 @@ void Engine::draw()
being->frame =
(get_elapsed_time(being->walk_time) * 4) / (being->speed);
- if (being->frame >= 4) {
- if (being->action != MONSTER_DEAD && being->hasPath()) {
- being->nextStep();
- }
+ if (being->frame >= 4 && being->action != MONSTER_DEAD) {
+ being->nextStep();
}
}
}
@@ -436,28 +434,26 @@ void Engine::draw()
// purposes.
if (displayPathToMouse)
{
- PATH_NODE *debugPath = tiledMap->findPath(
+ std::list<PATH_NODE> debugPath = tiledMap->findPath(
player_node->x, player_node->y,
mouseX / 32 + camera_x, mouseY / 32 + camera_y);
- while (debugPath)
+ while (!debugPath.empty())
{
- int squareX = (debugPath->x - camera_x) * 32 - offset_x + 12;
- int squareY = (debugPath->y - camera_y) * 32 - offset_y + 12;
+ PATH_NODE node = debugPath.front();
+ debugPath.pop_front();
+
+ int squareX = (node.x - camera_x) * 32 - offset_x + 12;
+ int squareY = (node.y - camera_y) * 32 - offset_y + 12;
guiGraphics->setColor(gcn::Color(255, 0, 0));
guiGraphics->fillRectangle(gcn::Rectangle(squareX, squareY, 8, 8));
- MetaTile *tile = tiledMap->getMetaTile(debugPath->x, debugPath->y);
+ MetaTile *tile = tiledMap->getMetaTile(node.x, node.y);
std::stringstream cost;
cost << tile->Gcost;
guiGraphics->drawText(cost.str(), squareX + 4, squareY + 12,
gcn::Graphics::CENTER);
-
- // Move to the next node
- PATH_NODE *temp = debugPath->next;
- delete debugPath;
- debugPath = temp;
}
}
@@ -466,24 +462,10 @@ void Engine::draw()
while (beingIterator != beings.end()) {
Being *being = (*beingIterator);
- if (being->speech != NULL) {
- //if (being->speech_color == makecol(255, 255, 255)) {
- // guiGraphics->drawText(being->speech,
- // being->text_x + 16, being->text_y - 60,
- // gcn::Graphics::CENTER);
- //}
- //else {
- guiGraphics->drawText(being->speech,
- being->text_x + 60, being->text_y - 60,
- gcn::Graphics::CENTER);
- //}
-
- being->speech_time--;
- if (being->speech_time == 0) {
- free(being->speech);
- being->speech = NULL;
- }
- }
+ // Tick the beings (gives them a sense of time)
+ being->tick();
+
+ being->drawSpeech(guiGraphics);
beingIterator++;
}
diff --git a/src/game.cpp b/src/game.cpp
index 2342168e..f217f356 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -39,10 +39,11 @@
#include "resources/mapreader.h"
#include "net/protocol.h"
#include <SDL.h>
+#include <sstream>
char map_path[480];
-unsigned short dest_x, dest_y, src_x, src_y;
+unsigned short src_x, src_y;
bool refresh_beings = false;
unsigned char keyb_state;
volatile int tick_time;
@@ -140,20 +141,20 @@ void do_init()
SDL_AddTimer(1000, second, NULL);
// Initialize beings
- empty();
player_node = new Being();
player_node->id = account_ID;
player_node->x = x;
player_node->y = y;
player_node->speed = 150;
- player_node->hair_color = char_info->hair_color;
- player_node->hair_style = char_info->hair_style;
- std::cout << char_info->weapon << "\n";
+ player_node->setHairColor(char_info->hair_color);
+ player_node->setHairStyle(char_info->hair_style);
+
if (char_info->weapon == 11) {
char_info->weapon = 2;
- std::cout << char_info->weapon << "\n";
}
+
player_node->weapon = char_info->weapon;
+
add_node(player_node);
remove("./docs/packet.list");
@@ -505,38 +506,32 @@ void do_parse() {
memcpy(temp, RFIFOP(8), RFIFOW(2)-8);
being = find_node(RFIFOL(4));
if (being != NULL) {
- if (being->speech != NULL) {
- free(being->speech);
- being->speech = NULL;
- being->speech_time = 0;
- }
- being->speech = temp;
- being->speech_time = SPEECH_TIME;
- being->speech_color = 0;//makecol(255, 255, 255);
- chatBox->chat_log(being->speech, BY_OTHER);
+ // White
+ being->setSpeech(temp, SPEECH_TIME);
+ chatBox->chat_log(temp, BY_OTHER);
}
+ free(temp);
break;
case 0x008e:
case 0x009a:
if (RFIFOW(2) > 4) {
- if(player_node->speech!=NULL) {
- free(player_node->speech);
- player_node->speech = NULL;
- }
-
- player_node->speech = (char *)malloc(RFIFOW(2)-3);
- memset(player_node->speech, '\0', RFIFOW(2)-3);
- memcpy(player_node->speech, RFIFOP(4), RFIFOW(2)-4); // receive 1 byte less than expected, server might be sending garbage instead of '\0' /-kth5
+ // 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);
- player_node->speech_time = SPEECH_TIME;
- player_node->speech_color = 0;//makecol(255, 255, 255);
+ // White
+ player_node->setSpeech(temp, SPEECH_TIME);
if (id == 0x008e) {
- chatBox->chat_log(player_node->speech, BY_PLAYER);
+ chatBox->chat_log(temp, BY_PLAYER);
}
else {
- chatBox->chat_log(player_node->speech, BY_GM);
+ chatBox->chat_log(temp, BY_GM);
}
+
+ free(temp);
}
break;
// Success to walk request
@@ -562,8 +557,8 @@ void do_parse() {
being->x = get_x(RFIFOP(46));
being->y = get_y(RFIFOP(46));
being->direction = get_direction(RFIFOP(46));
- being->hair_color = RFIFOW(28);
- being->hair_style = RFIFOW(16);
+ being->setHairColor(RFIFOW(28));
+ being->setHairStyle(RFIFOW(16));
add_node(being);
}
else {
@@ -616,8 +611,8 @@ void do_parse() {
being->walk_time = tick_time;
being->frame = 0;
being->speed = RFIFOW(6);
- being->hair_color = RFIFOW(28);
- being->hair_style = RFIFOW(16);
+ being->setHairColor(RFIFOW(28));
+ being->setHairStyle(RFIFOW(16));
break;
case SMSG_MOVE_BEING:
@@ -660,8 +655,8 @@ void do_parse() {
being->y = get_src_y(RFIFOP(50));
being->destX = get_dest_x(RFIFOP(50));
being->destY = get_dest_y(RFIFOP(50));
- being->hair_style = RFIFOW(16);
- being->hair_color = RFIFOW(32);
+ being->setHairStyle(RFIFOW(16));
+ being->setHairColor(RFIFOW(32));
being->setPath(tiledMap->findPath(
being->x, being->y,
@@ -734,26 +729,30 @@ void do_parse() {
memset(map_path, '\0', 480);
strcat(map_path, "./data/map/");
strncat(map_path, RFIFOP(2), 497 - strlen(map_path));
+ log("Warping to %s (%d, %d)\n",
+ map_path, RFIFOW(18), RFIFOW(20));
+
if (tiledMap) delete tiledMap;
tiledMap = Map::load(map_path);
+
if (tiledMap) {
- Being *temp;
- temp = new Being();
- memcpy(temp, player_node, sizeof(Being));
- empty();
- /*player_node = new Being();
- player_node->job = 0;
- player_node->action = STAND;
- player_node->frame = 0;
- player_node->speed = 150;
- player_node->id = account_ID;*/
- add_node(temp);
- player_node = temp;
+ // Delete all beings except the local player
+ std::list<Being *>::iterator i;
+ for (i = beings.begin(); i != beings.end(); i++) {
+ if ((*i) != player_node) {
+ delete (*i);
+ }
+ }
+ beings.clear();
+
+ // Re-add the local player node
+ add_node(player_node);
+
player_node->action = STAND;
- current_npc = 0;
player_node->frame = 0;
player_node->x = RFIFOW(18);
player_node->y = RFIFOW(20);
+ current_npc = 0;
walk_status = 0;
// Send "map loaded"
WFIFOW(0) = net_w_value(0x007d);
@@ -828,8 +827,7 @@ void do_parse() {
deathNotice = new OkDialog("Message",
"You're now dead, press ok to restart",
&deathNoticeListener);
- //remove_node(char_info->id);
- being->action = DEAD;
+ player_node->action = DEAD;
}
break;
// Stop walking
@@ -851,26 +849,17 @@ void do_parse() {
case 0: // Damage
being = find_node(RFIFOL(6));
if (being != NULL) {
- if (being->speech != NULL) {
- free(being->speech);
- being->speech = NULL;
- //being->speech_time = SPEECH_TIME;
- }
- being->speech = (char *)malloc(5);
- memset(being->speech, '\0', 5);
+
if (RFIFOW(22) == 0) {
- sprintf(being->speech, "miss");
- being->speech_color = 0;//makecol(255, 255, 0);
+ // Yellow
+ being->setSpeech("miss", SPEECH_TIME);
} else {
- sprintf(being->speech, "%i", RFIFOW(22));
- if (being->id != player_node->id) {
- being->speech_color = 0;//makecol(0,0,255);
- }
- else {
- being->speech_color = 0;//makecol(255,0,0);
- }
+ // Blue for monster, red for player
+ std::stringstream ss;
+ ss << RFIFOW(22);
+ being->setSpeech(ss.str(), SPEECH_TIME);
}
- being->speech_time = SPEECH_TIME;
+
if (RFIFOL(2) != player_node->id) { // buggy
being = find_node(RFIFOL(2));
if (being != NULL) {
@@ -1122,17 +1111,18 @@ void do_parse() {
npcListDialog->parseItems(RFIFOP(8));
npcListDialog->setVisible(true);
break;
- // Look change
- case 0x00c3:
- // Change hair color
- if (RFIFOB(6) == 6) {
- being = find_node(RFIFOL(2));
- being->hair_color = RFIFOB(7);
- } else if (RFIFOB(6) == 1) {
- being = find_node(RFIFOL(2));
- being->hair_style = RFIFOB(7);
+
+ case SMSG_CHANGE_BEING_LOOKS:
+ being = find_node(RFIFOL(2));
+ if (being) {
+ if (RFIFOB(6) == 6) {
+ being->setHairColor(RFIFOB(7));
+ } else if (RFIFOB(6) == 1) {
+ being->setHairStyle(RFIFOB(7));
+ }
}
break;
+
// Answer to equip item
case 0x00aa:
if (RFIFOB(6) == 0)
@@ -1162,7 +1152,7 @@ void do_parse() {
// Trick to use the proper graphic until I find
// the right packet
- switch(inventoryWindow->items->getId(RFIFOW(2))) {
+ switch (inventoryWindow->items->getId(RFIFOW(2))) {
case 1201:
player_node->weapon = 1;
break;
@@ -1299,7 +1289,6 @@ void do_parse() {
// Manage non implemented packets
default:
log("Unhandled packet: %x", id);
- //alert(pkt_nfo,"","","","",0,0);
break;
}
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index 4f71e94d..2f1fc36b 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -223,7 +223,7 @@ void Setup::action(const std::string &eventId)
// Sound settings
if (soundCheckBox->isMarked()) {
- config.setValue("sound",1);
+ config.setValue("sound", 1);
try {
sound.init(32, 20);
}
diff --git a/src/main.cpp b/src/main.cpp
index 69ffd431..a48b184b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -76,20 +76,6 @@ Sound sound;
// ini file configuration reader
Configuration config;
-// macros for safe object deletion
-#define SAFE_DELETE(object) { \
- if (object != NULL) { \
- delete object; \
- } \
-}
-
-#define SAFE_DELETE_ARRAY(array) { \
- if (array != NULL) { \
- delete [] array; \
- } \
-}
-
-
/**
* Listener used for responding to map start error dialog.
*/
@@ -313,9 +299,9 @@ void init_engine()
void exit_engine()
{
config.write(dir);
- SAFE_DELETE_ARRAY(dir);
- SAFE_DELETE(gui);
- SAFE_DELETE(graphics);
+ delete[] dir;
+ delete gui;
+ delete graphics;
// Shutdown libxml
xmlCleanupParser();
diff --git a/src/map.cpp b/src/map.cpp
index d4fb9dde..9419233d 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -272,13 +272,17 @@ int Map::getTileHeight()
return tileHeight;
}
-PATH_NODE *Map::findPath(int startX, int startY, int destX, int destY)
+std::list<PATH_NODE> Map::findPath(
+ int startX, int startY, int destX, int destY)
{
+ // Path to be built up (empty by default)
+ std::list<PATH_NODE> path;
+
// Declare open list, a list with open tiles sorted on F cost
std::priority_queue<Location> openList;
// Return when destination not walkable
- if (!getWalk(destX, destY)) return NULL;
+ if (!getWalk(destX, destY)) return path;
// Reset starting tile's G cost to 0
MetaTile *startTile = getMetaTile(startX, startY);
@@ -402,26 +406,20 @@ PATH_NODE *Map::findPath(int startX, int startY, int destX, int destY)
// to extract it.
if (foundPath)
{
- PATH_NODE *path = new PATH_NODE(destX, destY);
int pathX = destX;
int pathY = destY;
while (pathX != startX || pathY != startY)
{
+ // Add the new path node to the start of the path list
+ path.push_front(PATH_NODE(pathX, pathY));
+
// Find out the next parent
MetaTile *tile = getMetaTile(pathX, pathY);
pathX = tile->parentX;
pathY = tile->parentY;
-
- // Add the new path node to the start of the path list
- PATH_NODE *pn = new PATH_NODE(pathX, pathY);
- pn->next = path;
- path = pn;
}
-
- return path;
}
- // No path found
- return NULL;
+ return path;
}
diff --git a/src/map.h b/src/map.h
index 7c00bfa8..d56928d0 100644
--- a/src/map.h
+++ b/src/map.h
@@ -27,6 +27,7 @@
#include "being.h"
#include "graphics.h"
#include "resources/image.h"
+#include <list>
/**
* A meta tile stores additional information about a location on a tile map.
@@ -155,7 +156,8 @@ class Map
/**
* Find a path from one location to the next.
*/
- PATH_NODE *findPath(int startX, int startY, int destX, int destY);
+ std::list<PATH_NODE> findPath(
+ int startX, int startY, int destX, int destY);
private:
int width, height;
diff --git a/src/net/protocol.h b/src/net/protocol.h
index 2f4911d5..ea746412 100644
--- a/src/net/protocol.h
+++ b/src/net/protocol.h
@@ -31,7 +31,7 @@
#define SMSG_PLAYER_UPDATE_1 0x01d8 //
#define SMSG_PLAYER_UPDATE_2 0x01d9 //
#define SMSG_MOVE_PLAYER_BEING 0x01da // A nearby player moves
-
+#define SMSG_CHANGE_BEING_LOOKS 0x00c3 //
/** Packet length by id */
diff --git a/src/sound.cpp b/src/sound.cpp
index 20530750..6e2c19fe 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -30,9 +30,8 @@
void Sound::init(int voices, int mod_voices)
{
- if (isOk == 0) {
- throw("Sound engine cannot be initialized twice!\n");
- }
+ // Don't initialize sound engine twice
+ if (isOk == 0) return;
bgm = NULL;
int audio_rate = 44100;