summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/TODO.txt53
-rw-r--r--src/being.cpp257
-rw-r--r--src/being.h42
-rw-r--r--src/game.cpp1122
4 files changed, 744 insertions, 730 deletions
diff --git a/docs/TODO.txt b/docs/TODO.txt
index 946383a6..81d3d364 100644
--- a/docs/TODO.txt
+++ b/docs/TODO.txt
@@ -1,26 +1,27 @@
-1) Gui
- - Fix drag & drop (ElvenProgrammer)
- - Add iconify button (ElvenProgrammer)
- - Trading system (SimEdw)
- - Add config dialog (SimEdw)
-2) Sound engine
- - ogg/mp3 playback (kth5)
-3) Npc
- - Quest system (SimEdw)
-4) Chat
- - Linewrapping in chatbox (kth5)
-5) Graphics & animation
- - Animated and transparent tiles (ElvenProgrammer)
- - Fix fringe layer (ElvenProgrammer)
-6) Battle system
- - General fixes (ElvenProgrammer)
- - Long range weapons
- - Magic attacks
-7) Misc
- - Keyboard shortcuts
- - Clothing and hairstyling system
- - Item drops (ElvenProgrammer)
- - Minimap
-8) Optimization
- - Bubble sort->quick sort
- - Fix A*
+Gui
+ - Fix drag & drop (ElvenProgrammer)
+ - Add iconify button (ElvenProgrammer)
+ - Trading system (SimEdw)
+ - Add config dialog (SimEdw)
+
+Npc
+ - Quest system (SimEdw)
+
+Graphics & animation
+ - Animated and transparent tiles (ElvenProgrammer)
+ - Fix fringe layer (ElvenProgrammer)
+
+Battle system
+ - General fixes (ElvenProgrammer)
+ - Long range weapons
+ - Magic attacks
+
+Misc
+ - Keyboard shortcuts
+ - Clothing and hairstyling system
+ - Item drops (ElvenProgrammer)
+ - Minimap
+
+Optimization
+ - Bubble sort->quick sort
+ - Fix A*
diff --git a/src/being.cpp b/src/being.cpp
index 31b87d73..4404854a 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -30,6 +30,7 @@ NODE *player_node = NULL;
NODE *head = NULL; // First node of the list
unsigned int b_count = 0; // Number of beings in the list
+
PATH_NODE::PATH_NODE(unsigned short x, unsigned short y):
next(NULL)
{
@@ -44,172 +45,174 @@ PATH_NODE *calculate_path(
return find_path(1, src_x, src_y, dest_x, dest_y);
}
-/** Returns the first node of the list */
-NODE *get_head() {
- return head;
-}
-
-/** Creates a empty node */
NODE::NODE():
- id(0), job(0),
- next(NULL),
- action(0), frame(0),
- path(NULL),
- speech(NULL), speech_time(0),
- tick_time(0), speed(150),
- emotion(0), emotion_time(0),
- text_x(0), text_y(0),
- hair_style(1), hair_color(1),
- weapon(0)
+ id(0), job(0),
+ next(NULL),
+ action(0), frame(0),
+ path(NULL),
+ speech(NULL), speech_time(0),
+ tick_time(0), speed(150),
+ emotion(0), emotion_time(0),
+ text_x(0), text_y(0),
+ hair_style(1), hair_color(1),
+ weapon(0)
{
memset(coordinates, 0, 3);
speech_color = makecol(0, 0, 0);
}
-/** Returns number of beings in the list */
+NODE *get_head() {
+ return head;
+}
+
unsigned int get_count() {
- return b_count;
+ return b_count;
}
-/** Removes all beings from the list */
void empty() {
- NODE *node = head;
- NODE *next;
- while(node) {
- next = node->next;
- delete node;
- node = next;
- }
- b_count = 0;
- head = NULL;
+ NODE *node = head;
+ NODE *next;
+ while(node) {
+ next = node->next;
+ delete node;
+ node = next;
+ }
+ b_count = 0;
+ head = NULL;
}
-/** Add a node to the list */
void add_node(NODE *node) {
- NODE *temp = head;
- if(temp) {
- while(temp->next)
- temp = temp->next;
- temp->next = node;
- } else head = node;
- b_count++;
+ NODE *temp = head;
+ if(temp) {
+ while(temp->next)
+ temp = temp->next;
+ temp->next = node;
+ } else head = node;
+ b_count++;
}
-/** Remove a node */
void remove_node(unsigned int id) {
- unsigned int temp;
- NODE *node_old, *node_new;
- node_old = head;
- node_new = NULL;
- while(node_old) {
- temp = get_id(node_old);
- if(temp==id) {
- if(node_new==NULL) {
- head = node_old->next;
- delete node_old;
- b_count--;
- return;
- } else {
+ unsigned int temp;
+ NODE *node_old, *node_new;
+ node_old = head;
+ node_new = NULL;
+ while (node_old) {
+ temp = get_id(node_old);
+ if (temp==id) {
+ if (node_new==NULL) {
+ head = node_old->next;
+ delete node_old;
+ b_count--;
+ return;
+ } else {
node_new->next = node_old->next;
- delete node_old;
- b_count--;
- return;
- }
+ delete node_old;
+ b_count--;
+ return;
+ }
} else {
- node_new = node_old;
- node_old = node_old->next;
+ node_new = node_old;
+ node_old = node_old->next;
+ }
}
- }
}
-/** Returns the id of a being in the list */
unsigned int get_id(NODE *node) {
- return node->id;
+ return node->id;
}
-/** Find a NPC id based on its coordinates */
unsigned int find_npc(unsigned short x, unsigned short y) {
- NODE *node = head;
- while(node) {
- if((node->job>=46)&&(node->job<=125)) { // Check if is a NPC (only low job ids)
- if((get_x(node->coordinates)==x)&&(get_y(node->coordinates)==y))
- return node->id;
- else node = node->next;
- } else {
- node = node->next;
- //alert("id","","","","",0,0);
- }
- }
- return 0;
+ NODE *node = head;
+ while (node) {
+ // Check if is a NPC (only low job ids)
+ if ((node->job >= 46) && (node->job <= 125)) {
+ if ((get_x(node->coordinates) == x) &&
+ (get_y(node->coordinates) == y))
+ {
+ return node->id;
+ }
+ else {
+ node = node->next;
+ }
+ } else {
+ node = node->next;
+ }
+ }
+ return 0;
}
-/** Find a MONSTER id based on its coordinates */
unsigned int find_monster(unsigned short x, unsigned short y) {
- NODE *node = head;
- while(node) {
- if(node->job>200) { // Check if is a MONSTER
- if(get_x(node->coordinates)==x && get_y(node->coordinates)==y)
- return node->id;
+ NODE *node = head;
+ while (node) {
+ // Check if is a MONSTER
+ if (node->job > 200) {
+ if (get_x(node->coordinates) == x &&
+ get_y(node->coordinates) == y)
+ {
+ return node->id;
+ }
+ }
+ node = node->next;
}
- node = node->next;
- }
- return 0;
+ return 0;
}
-/** Return a specific id node */
NODE *find_node(unsigned int id) {
- NODE *node = head;
- while(node)
- if(node->id==id)
- return node;
- else node = node->next;
- return NULL;
+ NODE *node = head;
+ while (node) {
+ if (node->id == id) {
+ return node;
+ }
+ else {
+ node = node->next;
+ }
+ return NULL;
+ }
}
-/** Sort beings in vertical order using bubble sort */
void sort() {
- NODE *p, *q, *r, *s, *temp;
- s = NULL;
-
- while(s!=head->next) {
- r = p = head;
- q = p->next;
-
- while(p!=s) {
- if(get_y(p->coordinates)>get_y(q->coordinates)) {
- if(p==head) {
- temp = q->next;
- q->next = p;
- p->next = temp;
- head = q;
- r = q;
- } else {
- temp = q->next;
- q->next = p;
- p->next = temp;
- r->next = q;
- r = q;
+ NODE *p, *q, *r, *s, *temp;
+ s = NULL;
+
+ // Bubble sort
+ while (s != head->next) {
+ r = p = head;
+ q = p->next;
+
+ while (p != s) {
+ if (get_y(p->coordinates) > get_y(q->coordinates)) {
+ if (p == head) {
+ temp = q->next;
+ q->next = p;
+ p->next = temp;
+ head = q;
+ r = q;
+ } else {
+ temp = q->next;
+ q->next = p;
+ p->next = temp;
+ r->next = q;
+ r = q;
+ }
+ } else {
+ r = p;
+ p = p->next;
+ }
+ q = p->next;
+ if (q == s) s = p;
}
- } else {
- r = p;
- p = p->next;
- }
- q = p->next;
- if(q==s)s = p;
}
- }
}
-/** Remove all path nodes from a being */
void empty_path(NODE *node) {
- if(node) {
- PATH_NODE *temp = node->path;
- PATH_NODE *next;
- while(temp) {
- next = temp->next;
- delete temp;
- temp = next;
+ if (node) {
+ PATH_NODE *temp = node->path;
+ PATH_NODE *next;
+ while (temp) {
+ next = temp->next;
+ delete temp;
+ temp = next;
+ }
+ node->path = NULL;
}
- node->path = NULL;
- }
}
diff --git a/src/being.h b/src/being.h
index f45023a1..a64e41e2 100644
--- a/src/being.h
+++ b/src/being.h
@@ -67,35 +67,43 @@ struct NODE {
short weapon;
};
+/** Removes all beings from the list */
void empty();
+
+/** Returns the first node of the list */
NODE *get_head();
+
+/** Add a node to the list */
void add_node(NODE *node);
+
+/** Return a specific id node */
NODE *find_node(unsigned int id);
+
+/** Remove a node */
void remove_node(unsigned int id);
+
+/** Returns number of beings in the list */
unsigned int get_count();
-bool remove_being(char *data);
-void remove_being(unsigned int id);
-int get_beings_size();
-bool is_being(int id);
-void popup_being(unsigned char type, char *data);
-void move_being(char *data);
-PATH_NODE *calculate_path(unsigned short src_x, unsigned short src_y, unsigned short dest_x, unsigned short dest_y);
+
+PATH_NODE *calculate_path(
+ unsigned short src_x, unsigned short src_y,
+ unsigned short dest_x, unsigned short dest_y);
+
+/** Returns the id of a being in the list */
unsigned int get_id(NODE *node);
+
+/** Find a NPC id based on its coordinates */
unsigned int find_npc(unsigned short x, unsigned short y);
+
+/** Find a MONSTER id based on its coordinates */
unsigned int find_monster(unsigned short x, unsigned short y);
+
+/** Sort beings in vertical order */
void sort();
+
+/** Remove all path nodes from a being */
void empty_path(NODE *node);
extern NODE *player_node;
-class Being {
- public:
- unsigned int id;
- unsigned short x, y, direction;
- unsigned short image;
- unsigned char action, frame;
-};
-
-//std::vector<Being *> beings;
-
#endif
diff --git a/src/game.cpp b/src/game.cpp
index c84d8b3c..82973850 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -372,569 +372,571 @@ void do_parse() {
NODE *node = NULL;
PATH_NODE *pn;
int len;
-
- // We need at least 2 bytes to identify a packet
- if(in_size>=2) {
- // Check if the received packet is complete
- while(in_size>=(len = get_packet_length(id = RFIFOW(0)))) {
- // Add infos to log file and dump the latest received packet
- char pkt_nfo[60];
- sprintf(pkt_nfo,"In-buffer size: %i Packet id: %x Packet length: %i",in_size,RFIFOW(0),len);
- /*log_hex("Packet", "Packet_ID", RFIFOW(0));
- log_int("Packet", "Packet_length", get_length(RFIFOW(0)));
- log_int("Packet", "Packet_in_size", RFIFOW(2));
- log_int("Packet", "In_size", in_size);
- FILE *file = fopen("packet.dump", "wb");
- for(int i=0;i<len;i++) {
- fprintf(file, "%x|%i|%c ", RFIFOB(i), RFIFOB(i), RFIFOB(i));
- if((i+1)%10==0)fprintf(file, "\n");
- }
- fclose(file);*/
+
+ // We need at least 2 bytes to identify a packet
+ if (in_size >= 2) {
+ // Check if the received packet is complete
+ while (in_size >= (len = get_packet_length(id = RFIFOW(0)))) {
+ // Add infos to log file and dump the latest received packet
+ char pkt_nfo[60];
+ sprintf(pkt_nfo,"In-buffer size: %i Packet id: %x Packet length: %i",in_size,RFIFOW(0),len);
+ /*
+ log_hex("Packet", "Packet_ID", RFIFOW(0));
+ log_int("Packet", "Packet_length", get_length(RFIFOW(0)));
+ log_int("Packet", "Packet_in_size", RFIFOW(2));
+ log_int("Packet", "In_size", in_size);
+ FILE *file = fopen("packet.dump", "wb");
+ for(int i=0;i<len;i++) {
+ fprintf(file, "%x|%i|%c ", RFIFOB(i), RFIFOB(i), RFIFOB(i));
+ if((i+1)%10==0)fprintf(file, "\n");
+ }
+ fclose(file);
+ */
#ifdef DEBUG
- FILE *file = fopen("./docs/packet.list", "ab");
- fprintf(file, "%x\n", RFIFOW(0));
- fclose(file);
+ FILE *file = fopen("./docs/packet.list", "ab");
+ fprintf(file, "%x\n", RFIFOW(0));
+ fclose(file);
#endif
- // Parse packet based on their id
- switch(id) {
- // Received speech
- case 0x008d:
- temp = (char *)malloc(RFIFOW(2)-7);
- memset(temp, '\0', RFIFOW(2)-7);
- memcpy(temp, RFIFOP(8), RFIFOW(2)-8);
- node = find_node(RFIFOL(4));
- if(node!=NULL) {
- if(node->speech!=NULL) {
- free(node->speech);
- node->speech = NULL;
- node->speech_time = 0;
- }
- node->speech = temp;
- node->speech_time = SPEECH_TIME;
- node->speech_color = makecol(255, 255, 255);
- chatlog.chat_log(node->speech, BY_OTHER, font);
- }
- 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
-
- player_node->speech_time = SPEECH_TIME;
- player_node->speech_color = makecol(255, 255, 255);
-
- if(id==0x008e) {
- chatlog.chat_log(player_node->speech, BY_PLAYER, font);
- }
- else {
- chatlog.chat_log(player_node->speech, BY_GM, font);
- }
- }
- break;
- // Success to walk request
- case 0x0087:
- if(walk_status==1) {
- if(RFIFOL(2)>server_tick) {
- walk_status = 2;
- server_tick = RFIFOL(2);
- }
- }
- break;
- // Add new being / stop monster
- case 0x0078:
- if(find_node(RFIFOL(2))==NULL) {
- node = new NODE();
- node->id = RFIFOL(2);
- node->speed = RFIFOW(6);
- if(node->speed==0) {
- node->speed = 150; // Else division by 0 when calculating frame
- }
- node->job = RFIFOW(14);
- empty_path(node);
- memcpy(node->coordinates, RFIFOP(46), 3);
- node->hair_color = RFIFOW(28);
- node->hair_style = RFIFOW(16);
- add_node(node);
- }
- else {
- if(node) {
- empty_path(node);
- memcpy(node->coordinates, RFIFOP(46), 3);
- node->frame = 0;
- node->tick_time = tick_time;
- node->action = STAND;
- }
- }
- break;
- // Remove a being
- case 0x0080:
- node = find_node(RFIFOL(2));
- if(node!=NULL) {
- if(RFIFOB(6)==1) { // Death
- if(node->job>110) {
- node->action = MONSTER_DEAD;
- node->frame = 0;
- node->tick_time = tick_time;
- }
- else remove_node(RFIFOL(2));
- }
- else remove_node(RFIFOL(2));
- }
- break;
- // Player moving
- case 0x01d8:
- case 0x01d9:
- node = find_node(RFIFOL(2));
- if(node==NULL) {
- node = new NODE();
- node->id = RFIFOL(2);
- node->job = RFIFOW(14);
- memcpy(node->coordinates, RFIFOP(46), 3);
- add_node(node);
- node->tick_time = tick_time;
- node->frame = 0;
- node->speed = RFIFOW(6);
- node->hair_color = RFIFOW(28);
- node->hair_style = RFIFOW(16);
- }
- break;
- // Monster moving
- case 0x007b:
- //case 0x01da:
- node = find_node(RFIFOL(2));
- if(node==NULL) {
- node = new NODE();
- node->action = STAND;
- set_coordinates(node->coordinates,
- get_src_x(RFIFOP(50)),
- get_src_y(RFIFOP(50)), 0);
- node->id = RFIFOL(2);
- node->speed = RFIFOW(6);
- node->job = RFIFOW(14);
- add_node(node);
- }
- empty_path(node);
- node->path = calculate_path(get_src_x(RFIFOP(50)),
- get_src_y(RFIFOP(50)),get_dest_x(RFIFOP(50)),
- get_dest_y(RFIFOP(50)));
- if(node->path!=NULL) {
- direction = 0;
- if(node->path->next) {
- if(node->path->next->x>node->path->x && node->path->next->y>node->path->y)direction = SE;
- else if(node->path->next->x<node->path->x && node->path->next->y>node->path->y)direction = SW;
- else if(node->path->next->x>node->path->x && node->path->next->y<node->path->y)direction = NE;
- else if(node->path->next->x<node->path->x && node->path->next->y<node->path->y)direction = NW;
- else if(node->path->next->x>node->path->x)direction = EAST;
- else if(node->path->next->x<node->path->x)direction = WEST;
- else if(node->path->next->y>node->path->y)direction = SOUTH;
- else if(node->path->next->y<node->path->y)direction = NORTH;
- }
- pn = node->path;
- node->path = node->path->next;
- free(pn);
- set_coordinates(node->coordinates, node->path->x, node->path->y, direction);
- node->action = WALK;
- node->tick_time = tick_time;
- node->frame = 0;
- }
- break;
- // Being moving
- case 0x01da:
- node = find_node(RFIFOL(2));
- if(node==NULL) {
- node = new NODE();
- node->id = RFIFOL(2);
- node->job = RFIFOW(14);
- set_coordinates(node->coordinates, get_src_x(RFIFOP(50)), get_src_y(RFIFOP(50)), 0);
- add_node(node);
- }
- if(node->action!=WALK) {
- direction = get_direction(node->coordinates);
- node->action = WALK;
- if(get_dest_x(RFIFOP(50))>get_x(node->coordinates))direction = EAST;
- else if(get_dest_x(RFIFOP(50))<get_x(node->coordinates))direction = WEST;
- else if(get_dest_y(RFIFOP(50))>get_y(node->coordinates))direction = SOUTH;
- else if(get_dest_y(RFIFOP(50))<get_y(node->coordinates))direction = NORTH;
- else node->action = STAND;
- if(node->action==WALK)node->tick_time = tick_time;
- set_coordinates(node->coordinates, get_dest_x(RFIFOP(50)), get_dest_y(RFIFOP(50)), direction);
- }
- break;
- // NPC dialog
- case 0x00b4:
- npcTextDialog->addText(RFIFOP(8));
- npcListDialog->setVisible(false);
- npcTextDialog->setVisible(true);
- break;
- // Get the items
- case 0x01ee:
- for (int loop = 0; loop < (RFIFOW(2) - 4) / 18; loop++) {
- inventoryWindow->addItem(RFIFOW(4 + loop * 18),
- RFIFOW(4 + loop * 18 + 2), RFIFOW(4 + loop * 18 + 6));
- }
- break;
- // Can I use the item?
- case 0x00a8:
- // index RFIFOW(2)
- // succes or not RFIFOB(6);
- //if (RFIFOB(6))
- // inventoryWindow->addItem(RFIFOW(2), RFIFOW(4));
- break;
- // Warp
- case 0x0091:
- memset(map_path, '\0', 480);
- append_filename(map_path, "./data/map/", RFIFOP(2), 480);
- if (load_map(map_path)) {
- empty();
- player_node = new NODE();
- player_node->job = 0;
- player_node->action = STAND;
- player_node->frame = 0;
- player_node->type = ACTION_NODE;
- player_node->speed = 150;
- player_node->id = account_ID;
- set_coordinates(player_node->coordinates, RFIFOW(18), RFIFOW(20), 0);
- add_node(player_node);
- walk_status = 0;
- // Send "map loaded"
- WFIFOW(0) = net_w_value(0x007d);
- WFIFOSET(2);
- while(out_size>0)flush();
- }
- else {
- error("Could not find map file");
- }
- break;
- // Skill ...
- case 0x011a:
- break;
- case 0x01a4:
- break;
- // Action failed (ex. sit because you have not reached the right level)
- case 0x0110:
- CHATSKILL action;
- action.skill = RFIFOW(2);
- action.bskill = RFIFOW(4);
- action.unused = RFIFOW(6);
- action.success = RFIFOB(8);
- action.reason = RFIFOB(9);
- if(action.success != SKILL_FAILED &&
- action.bskill == BSKILL_EMOTE ) {
- printf("Action: %d/%d", action.bskill, action.success);
- }
- chatlog.chat_log(action, font);
- break;
- // Update stat values
- case 0x00b0:
- switch(RFIFOW(2)) {
- /*case 0x0000:
- player_node->speed;
- break;*/
- case 0x0005:
- char_info->hp = RFIFOW(4);
- break;
- case 0x0006:
- char_info->max_hp = RFIFOW(4);
- break;
- case 0x0007:
- char_info->sp = RFIFOW(4);
- break;
- case 0x0008:
- char_info->max_sp = RFIFOW(4);
- break;
- case 0x000b:
- char_info->lv = RFIFOW(4);
- break;
- case 0x000c:
- char_info->skill_point = RFIFOW(4);
- sprintf(skill_points, "Skill points: %i", char_info->skill_point);
- break;
- case 0x0037:
- char_info->job_lv = RFIFOW(4);
- break;
- }
- statusWindow->update();
- if(char_info->hp==0) {
- OkDialog *death = new OkDialog(guiTop,
- "You're now dead, press ok to restart");
- alert("","","","","",0,0);
- WFIFOW(0) = net_w_value(0x00b2);
- WFIFOB(2) = 0;
- WFIFOSET(3);
- }
- break;
- // Stop walking
- /*case 0x0088: // Disabled because giving some problems
- if(node = find_node(RFIFOL(2))) {
- if(node->id!=player_node->id) {
- char ids[20];
- sprintf(ids,"%i",RFIFOL(2));
- alert(ids,"","","","",0,0);
- node->action = STAND;
- node->frame = 0;
- set_coordinates(node->coordinates, RFIFOW(6), RFIFOW(8), get_direction(node->coordinates));
- }
- }
- break;*/
- // Damage, sit, stand up
- case 0x008a:
- switch(RFIFOB(26)) {
- case 0: // Damage
- node = find_node(RFIFOL(6));
- if(node!=NULL) {
- if(node->speech!=NULL) {
- free(node->speech);
- node->speech = NULL;
- //node->speech_time = SPEECH_TIME;
- }
- node->speech = (char *)malloc(5);
- memset(node->speech, '\0', 5);
- if(RFIFOW(22)==0) {
- sprintf(node->speech, "miss");
- node->speech_color = makecol(255, 255, 0);
- } else {
- sprintf(node->speech, "%i", RFIFOW(22));
- if(node->id!=player_node->id)node->speech_color = makecol(0, 0, 255);
- else node->speech_color = makecol(255, 0, 0);
- }
- node->speech_time = SPEECH_TIME;
- if(RFIFOL(2)!=player_node->id) { // buggy
- node = find_node(RFIFOL(2));
- if(node!=NULL) {
- if(node->job<10)
- node->action = ATTACK;
- else node->action = MONSTER_ATTACK;
- node->frame = 0;
- }
- }
- }
- break;
- case 2: // Sit
- case 3: // Stand up
- node = find_node(RFIFOL(2));
- if(node!=NULL) {
- node->frame = 0;
- if(RFIFOB(26)==2) {
- node->action = SIT;
- //alert("","","","","",0,0);
- walk_status = 0;
- }
- else if(RFIFOB(26)==3)
- node->action = STAND;
- }
- break;
- }
- break;
- // Status change
- case 0x00b1:
- switch(RFIFOW(2)) {
- case 1:
- char_info->xp = RFIFOL(4);
- break;
- case 2:
- char_info->job_xp = RFIFOL(4);
- break;
- case 20:
- char_info->gp = RFIFOL(4);
- break;
- // case 16 and 17 missing
- }
- break;
- // Level up
- case 0x019b:
- if(RFIFOL(2)==player_node->id) {
+ // Parse packet based on their id
+ switch(id) {
+ // Received speech
+ case 0x008d:
+ temp = (char *)malloc(RFIFOW(2)-7);
+ memset(temp, '\0', RFIFOW(2)-7);
+ memcpy(temp, RFIFOP(8), RFIFOW(2)-8);
+ node = find_node(RFIFOL(4));
+ if(node!=NULL) {
+ if(node->speech!=NULL) {
+ free(node->speech);
+ node->speech = NULL;
+ node->speech_time = 0;
+ }
+ node->speech = temp;
+ node->speech_time = SPEECH_TIME;
+ node->speech_color = makecol(255, 255, 255);
+ chatlog.chat_log(node->speech, BY_OTHER, font);
+ }
+ 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
+
+ player_node->speech_time = SPEECH_TIME;
+ player_node->speech_color = makecol(255, 255, 255);
+
+ if(id==0x008e) {
+ chatlog.chat_log(player_node->speech, BY_PLAYER, font);
+ }
+ else {
+ chatlog.chat_log(player_node->speech, BY_GM, font);
+ }
+ }
+ break;
+ // Success to walk request
+ case 0x0087:
+ if(walk_status==1) {
+ if(RFIFOL(2)>server_tick) {
+ walk_status = 2;
+ server_tick = RFIFOL(2);
+ }
+ }
+ break;
+ // Add new being / stop monster
+ case 0x0078:
+ if(find_node(RFIFOL(2))==NULL) {
+ node = new NODE();
+ node->id = RFIFOL(2);
+ node->speed = RFIFOW(6);
+ if(node->speed==0) {
+ node->speed = 150; // Else division by 0 when calculating frame
+ }
+ node->job = RFIFOW(14);
+ empty_path(node);
+ memcpy(node->coordinates, RFIFOP(46), 3);
+ node->hair_color = RFIFOW(28);
+ node->hair_style = RFIFOW(16);
+ add_node(node);
+ }
+ else {
+ if(node) {
+ empty_path(node);
+ memcpy(node->coordinates, RFIFOP(46), 3);
+ node->frame = 0;
+ node->tick_time = tick_time;
+ node->action = STAND;
+ }
+ }
+ break;
+ // Remove a being
+ case 0x0080:
+ node = find_node(RFIFOL(2));
+ if(node!=NULL) {
+ if(RFIFOB(6)==1) { // Death
+ if(node->job>110) {
+ node->action = MONSTER_DEAD;
+ node->frame = 0;
+ node->tick_time = tick_time;
+ }
+ else remove_node(RFIFOL(2));
+ }
+ else remove_node(RFIFOL(2));
+ }
+ break;
+ // Player moving
+ case 0x01d8:
+ case 0x01d9:
+ node = find_node(RFIFOL(2));
+ if(node==NULL) {
+ node = new NODE();
+ node->id = RFIFOL(2);
+ node->job = RFIFOW(14);
+ memcpy(node->coordinates, RFIFOP(46), 3);
+ add_node(node);
+ node->tick_time = tick_time;
+ node->frame = 0;
+ node->speed = RFIFOW(6);
+ node->hair_color = RFIFOW(28);
+ node->hair_style = RFIFOW(16);
+ }
+ break;
+ // Monster moving
+ case 0x007b:
+ //case 0x01da:
+ node = find_node(RFIFOL(2));
+ if(node==NULL) {
+ node = new NODE();
+ node->action = STAND;
+ set_coordinates(node->coordinates,
+ get_src_x(RFIFOP(50)),
+ get_src_y(RFIFOP(50)), 0);
+ node->id = RFIFOL(2);
+ node->speed = RFIFOW(6);
+ node->job = RFIFOW(14);
+ add_node(node);
+ }
+ empty_path(node);
+ node->path = calculate_path(get_src_x(RFIFOP(50)),
+ get_src_y(RFIFOP(50)),get_dest_x(RFIFOP(50)),
+ get_dest_y(RFIFOP(50)));
+ if(node->path!=NULL) {
+ direction = 0;
+ if(node->path->next) {
+ if(node->path->next->x>node->path->x && node->path->next->y>node->path->y)direction = SE;
+ else if(node->path->next->x<node->path->x && node->path->next->y>node->path->y)direction = SW;
+ else if(node->path->next->x>node->path->x && node->path->next->y<node->path->y)direction = NE;
+ else if(node->path->next->x<node->path->x && node->path->next->y<node->path->y)direction = NW;
+ else if(node->path->next->x>node->path->x)direction = EAST;
+ else if(node->path->next->x<node->path->x)direction = WEST;
+ else if(node->path->next->y>node->path->y)direction = SOUTH;
+ else if(node->path->next->y<node->path->y)direction = NORTH;
+ }
+ pn = node->path;
+ node->path = node->path->next;
+ free(pn);
+ set_coordinates(node->coordinates, node->path->x, node->path->y, direction);
+ node->action = WALK;
+ node->tick_time = tick_time;
+ node->frame = 0;
+ }
+ break;
+ // Being moving
+ case 0x01da:
+ node = find_node(RFIFOL(2));
+ if(node==NULL) {
+ node = new NODE();
+ node->id = RFIFOL(2);
+ node->job = RFIFOW(14);
+ set_coordinates(node->coordinates, get_src_x(RFIFOP(50)), get_src_y(RFIFOP(50)), 0);
+ add_node(node);
+ }
+ if(node->action!=WALK) {
+ direction = get_direction(node->coordinates);
+ node->action = WALK;
+ if(get_dest_x(RFIFOP(50))>get_x(node->coordinates))direction = EAST;
+ else if(get_dest_x(RFIFOP(50))<get_x(node->coordinates))direction = WEST;
+ else if(get_dest_y(RFIFOP(50))>get_y(node->coordinates))direction = SOUTH;
+ else if(get_dest_y(RFIFOP(50))<get_y(node->coordinates))direction = NORTH;
+ else node->action = STAND;
+ if(node->action==WALK)node->tick_time = tick_time;
+ set_coordinates(node->coordinates, get_dest_x(RFIFOP(50)), get_dest_y(RFIFOP(50)), direction);
+ }
+ break;
+ // NPC dialog
+ case 0x00b4:
+ npcTextDialog->addText(RFIFOP(8));
+ npcListDialog->setVisible(false);
+ npcTextDialog->setVisible(true);
+ break;
+ // Get the items
+ case 0x01ee:
+ for (int loop = 0; loop < (RFIFOW(2) - 4) / 18; loop++) {
+ inventoryWindow->addItem(RFIFOW(4 + loop * 18),
+ RFIFOW(4 + loop * 18 + 2), RFIFOW(4 + loop * 18 + 6));
+ }
+ break;
+ // Can I use the item?
+ case 0x00a8:
+ // index RFIFOW(2)
+ // succes or not RFIFOB(6);
+ //if (RFIFOB(6))
+ // inventoryWindow->addItem(RFIFOW(2), RFIFOW(4));
+ break;
+ // Warp
+ case 0x0091:
+ memset(map_path, '\0', 480);
+ append_filename(map_path, "./data/map/", RFIFOP(2), 480);
+ if (load_map(map_path)) {
+ empty();
+ player_node = new NODE();
+ player_node->job = 0;
+ player_node->action = STAND;
+ player_node->frame = 0;
+ player_node->type = ACTION_NODE;
+ player_node->speed = 150;
+ player_node->id = account_ID;
+ set_coordinates(player_node->coordinates, RFIFOW(18), RFIFOW(20), 0);
+ add_node(player_node);
+ walk_status = 0;
+ // Send "map loaded"
+ WFIFOW(0) = net_w_value(0x007d);
+ WFIFOSET(2);
+ while(out_size>0)flush();
+ }
+ else {
+ error("Could not find map file");
+ }
+ break;
+ // Skill ...
+ case 0x011a:
+ break;
+ case 0x01a4:
+ break;
+ // Action failed (ex. sit because you have not reached the right level)
+ case 0x0110:
+ CHATSKILL action;
+ action.skill = RFIFOW(2);
+ action.bskill = RFIFOW(4);
+ action.unused = RFIFOW(6);
+ action.success = RFIFOB(8);
+ action.reason = RFIFOB(9);
+ if(action.success != SKILL_FAILED &&
+ action.bskill == BSKILL_EMOTE ) {
+ printf("Action: %d/%d", action.bskill, action.success);
+ }
+ chatlog.chat_log(action, font);
+ break;
+ // Update stat values
+ case 0x00b0:
+ switch(RFIFOW(2)) {
+ //case 0x0000:
+ // player_node->speed;
+ // break;
+ case 0x0005:
+ char_info->hp = RFIFOW(4);
+ break;
+ case 0x0006:
+ char_info->max_hp = RFIFOW(4);
+ break;
+ case 0x0007:
+ char_info->sp = RFIFOW(4);
+ break;
+ case 0x0008:
+ char_info->max_sp = RFIFOW(4);
+ break;
+ case 0x000b:
+ char_info->lv = RFIFOW(4);
+ break;
+ case 0x000c:
+ char_info->skill_point = RFIFOW(4);
+ sprintf(skill_points, "Skill points: %i", char_info->skill_point);
+ break;
+ case 0x0037:
+ char_info->job_lv = RFIFOW(4);
+ break;
+ }
+ statusWindow->update();
+ if(char_info->hp==0) {
+ OkDialog *death = new OkDialog(guiTop,
+ "You're now dead, press ok to restart");
+ alert("","","","","",0,0);
+ WFIFOW(0) = net_w_value(0x00b2);
+ WFIFOB(2) = 0;
+ WFIFOSET(3);
+ }
+ break;
+ // Stop walking
+ case 0x0088: // Disabled because giving some problems
+ //if (node = find_node(RFIFOL(2))) {
+ // if (node->id!=player_node->id) {
+ // char ids[20];
+ // sprintf(ids,"%i",RFIFOL(2));
+ // alert(ids,"","","","",0,0);
+ // node->action = STAND;
+ // node->frame = 0;
+ // set_coordinates(node->coordinates, RFIFOW(6), RFIFOW(8), get_direction(node->coordinates));
+ // }
+ //}
+ //break;
+ // Damage, sit, stand up
+ case 0x008a:
+ switch(RFIFOB(26)) {
+ case 0: // Damage
+ node = find_node(RFIFOL(6));
+ if(node!=NULL) {
+ if(node->speech!=NULL) {
+ free(node->speech);
+ node->speech = NULL;
+ //node->speech_time = SPEECH_TIME;
+ }
+ node->speech = (char *)malloc(5);
+ memset(node->speech, '\0', 5);
+ if(RFIFOW(22)==0) {
+ sprintf(node->speech, "miss");
+ node->speech_color = makecol(255, 255, 0);
+ } else {
+ sprintf(node->speech, "%i", RFIFOW(22));
+ if(node->id!=player_node->id)node->speech_color = makecol(0, 0, 255);
+ else node->speech_color = makecol(255, 0, 0);
+ }
+ node->speech_time = SPEECH_TIME;
+ if(RFIFOL(2)!=player_node->id) { // buggy
+ node = find_node(RFIFOL(2));
+ if(node!=NULL) {
+ if(node->job<10)
+ node->action = ATTACK;
+ else node->action = MONSTER_ATTACK;
+ node->frame = 0;
+ }
+ }
+ }
+ break;
+ case 2: // Sit
+ case 3: // Stand up
+ node = find_node(RFIFOL(2));
+ if(node!=NULL) {
+ node->frame = 0;
+ if(RFIFOB(26)==2) {
+ node->action = SIT;
+ //alert("","","","","",0,0);
+ walk_status = 0;
+ }
+ else if(RFIFOB(26)==3)
+ node->action = STAND;
+ }
+ break;
+ }
+ break;
+ // Status change
+ case 0x00b1:
+ switch(RFIFOW(2)) {
+ case 1:
+ char_info->xp = RFIFOL(4);
+ break;
+ case 2:
+ char_info->job_xp = RFIFOL(4);
+ break;
+ case 20:
+ char_info->gp = RFIFOL(4);
+ break;
+ // case 16 and 17 missing
+ }
+ break;
+ // Level up
+ case 0x019b:
+ if(RFIFOL(2)==player_node->id) {
#ifndef WIN32
- SOUND_SID sound_id = sound.loadItem("./data/sound/wavs/level.wav");
- sound.startItem(sound_id, 64);
- sound.clearCache();
+ SOUND_SID sound_id = sound.loadItem("./data/sound/wavs/level.wav");
+ sound.startItem(sound_id, 64);
+ sound.clearCache();
#endif /* not WIN32 */
- }
- break;
- // Emotion
- case 0x00c0:
- node = find_node(RFIFOL(2));
- if(node) {
- node->emotion = RFIFOB(6);
- node->emotion_time = EMOTION_TIME;
- }
- break;
- // Update skill values
- case 0x0141:
- switch(RFIFOL(2)) {
- case 0x000d:
- char_info->STR = RFIFOL(6) + RFIFOL(10); // Base + Bonus
- break;
- case 0x000e:
- char_info->AGI = RFIFOL(6) + RFIFOL(10);
- break;
- case 0x000f:
- char_info->VIT = RFIFOL(6) + RFIFOL(10);
- break;
- case 0x0010:
- char_info->INT = RFIFOL(6) + RFIFOL(10);
- break;
- case 0x0011:
- char_info->DEX = RFIFOL(6) + RFIFOL(10);
- break;
- case 0x0012:
- char_info->LUK = RFIFOL(6) + RFIFOL(10);
- break;
- }
- break;
- // Buy/Sell dialog
- case 0x00c4:
- buyDialog->setVisible(false);
- sellDialog->setVisible(false);
- buySellDialog->setVisible(true);
- current_npc = RFIFOL(2);
- break;
- // Buy dialog
- case 0x00c6:
- n_items = (len - 4) / 11;
- buyDialog->reset();
- buyDialog->setMoney(char_info->gp);
- buyDialog->setVisible(true);
- for (int k = 0; k < n_items; k++) {
- buyDialog->addItem(RFIFOW(4 + 11 * k + 9), RFIFOL(4 + 11 * k));
- }
- break;
- // Sell dialog
- case 0x00c7:
- n_items = (len - 4) / 10;
- if (n_items > 0) {
- sellDialog->reset();
- sellDialog->setVisible(true);
- for (int k = 0; k < n_items; k++) {
- sellDialog->addItem(
- RFIFOW(4 + 10 * k), RFIFOL(4 + 10 * k + 2));
- }
- }
- else {
- chatlog.chat_log("Nothing to sell", BY_SERVER, font);
- }
- break;
- // Answer to buy
- case 0x00ca:
- if(RFIFOB(2)==0)
- chatlog.chat_log("Thanks for buying", BY_SERVER, font);
- else
- chatlog.chat_log("Unable to buy", BY_SERVER, font);
- break;
- // Answer to sell
- case 0x00cb:
- if(RFIFOB(2)==0)
- chatlog.chat_log("Thanks for selling", BY_SERVER, font);
- else
- chatlog.chat_log("Unable to sell", BY_SERVER, font);
- break;
- // Add item to inventory after you bought it
- case 0x00a0:
- if(RFIFOB(22)>0)
- chatlog.chat_log("Unable to pick up item", BY_SERVER, font);
- else
- inventoryWindow->addItem(RFIFOW(2), RFIFOW(6), RFIFOW(4));
- break;
- // Remove item to inventory after you sold it
- case 0x00af:
- printf("sell %i\n", -RFIFOW(4));
- inventoryWindow->increaseQuantity(RFIFOW(2), -RFIFOW(4));
- break;
- // Use an item
- case 0x01c8:
- inventoryWindow->changeQuantity(RFIFOW(2), RFIFOW(10));
- break;
- // ??
- case 0x0119:
- sprintf(pkt_nfo, "%i %i %i %i", RFIFOL(2), RFIFOW(6), RFIFOW(8), RFIFOW(10));
- //alert(pkt_nfo,"","","","",0,0);
- break;
- // Skill list
- case 0x010f:
- //n_skills = 0;
- //SKILL *temp_skill = NULL;
- //n_skills = (len-4)/37;
- for(int k=0;k<(len-4)/37;k++) {
- if(RFIFOW(4+k*37+6)!=0 || RFIFOB(4+k*37+36)!=0) {
- SKILL *temp_skill = is_skill(RFIFOW(4+k*37));
- if(temp_skill) {
- temp_skill->lv = RFIFOW(4+k*37+6);
- temp_skill->sp = RFIFOW(4+k*37+36);
- if(temp_skill->sp<0)temp_skill->sp = 0;
- } else {
- n_skills++;
- add_skill(RFIFOW(4+k*37), RFIFOW(4+k*37+6), RFIFOW(4+k*37+8));
- }
- }
- }
- break;
- // MVP experience
- case 0x010b:
- break;
- // Display MVP payer
- case 0x010c:
- chatlog.chat_log("MVP player", BY_SERVER, font);
- break;
- // Item drop
- case 0x009e:
- WFIFOW(0) = net_w_value(0x009f);
- WFIFOL(2) = net_l_value(RFIFOL(2));
- WFIFOSET(6);
- break;
- // Next button in NPC dialog
- case 0x00b5:
- strcpy(npc_button, "Next");
- current_npc = RFIFOL(2);
- break;
- // Close button in NPC dialog
- case 0x00b6:
- strcpy(npc_button, "Close");
- current_npc = RFIFOL(2);
- break;
- // List in NPC dialog
- case 0x00b7:
- current_npc = RFIFOL(4);
- // Hammerbear: Second argument here shouldn't be neccesary, instead
- // make sure the string is \0 terminated.
- //parse_items(RFIFOP(8), RFIFOW(2));
- npcListDialog->parseItems(RFIFOP(8));
- RFIFOW(2);
- npcListDialog->setVisible(true);
- break;
- // Look change
- case 0x00c3:
- // Change hair color
- if (RFIFOB(6) == 6) {
- node = find_node(RFIFOL(2));
- node->hair_color = RFIFOB(7);
- /*char prova[100];
- sprintf(prova, "%i %i %i", RFIFOL(2), RFIFOB(6), RFIFOB(7));
- alert(prova,"","","","",0,0);*/
- } else if (RFIFOB(6) == 1) {
- node = find_node(RFIFOL(2));
- node->hair_style = RFIFOB(7);
- }
- break;
- case 0x00a4:
- for (int i = 0; i < (RFIFOW(2) - 4) / 20; i++)
- inventoryWindow->addItem(RFIFOW(4 + 20 * i), RFIFOW(6 + 20 * i), 1);
- break;
-
- // Manage non implemented packets
- default:
- //printf("%x\n",id);
- //alert(pkt_nfo,"","","","",0,0);
- break;
- }
- //alert(pkt_nfo,"","","","",0,0);
-
- RFIFOSKIP(len);
+ }
+ break;
+ // Emotion
+ case 0x00c0:
+ node = find_node(RFIFOL(2));
+ if(node) {
+ node->emotion = RFIFOB(6);
+ node->emotion_time = EMOTION_TIME;
+ }
+ break;
+ // Update skill values
+ case 0x0141:
+ switch(RFIFOL(2)) {
+ case 0x000d:
+ char_info->STR = RFIFOL(6) + RFIFOL(10); // Base + Bonus
+ break;
+ case 0x000e:
+ char_info->AGI = RFIFOL(6) + RFIFOL(10);
+ break;
+ case 0x000f:
+ char_info->VIT = RFIFOL(6) + RFIFOL(10);
+ break;
+ case 0x0010:
+ char_info->INT = RFIFOL(6) + RFIFOL(10);
+ break;
+ case 0x0011:
+ char_info->DEX = RFIFOL(6) + RFIFOL(10);
+ break;
+ case 0x0012:
+ char_info->LUK = RFIFOL(6) + RFIFOL(10);
+ break;
+ }
+ break;
+ // Buy/Sell dialog
+ case 0x00c4:
+ buyDialog->setVisible(false);
+ sellDialog->setVisible(false);
+ buySellDialog->setVisible(true);
+ current_npc = RFIFOL(2);
+ break;
+ // Buy dialog
+ case 0x00c6:
+ n_items = (len - 4) / 11;
+ buyDialog->reset();
+ buyDialog->setMoney(char_info->gp);
+ buyDialog->setVisible(true);
+ for (int k = 0; k < n_items; k++) {
+ buyDialog->addItem(RFIFOW(4 + 11 * k + 9), RFIFOL(4 + 11 * k));
+ }
+ break;
+ // Sell dialog
+ case 0x00c7:
+ n_items = (len - 4) / 10;
+ if (n_items > 0) {
+ sellDialog->reset();
+ sellDialog->setVisible(true);
+ for (int k = 0; k < n_items; k++) {
+ sellDialog->addItem(
+ RFIFOW(4 + 10 * k), RFIFOL(4 + 10 * k + 2));
+ }
+ }
+ else {
+ chatlog.chat_log("Nothing to sell", BY_SERVER, font);
+ }
+ break;
+ // Answer to buy
+ case 0x00ca:
+ if(RFIFOB(2)==0)
+ chatlog.chat_log("Thanks for buying", BY_SERVER, font);
+ else
+ chatlog.chat_log("Unable to buy", BY_SERVER, font);
+ break;
+ // Answer to sell
+ case 0x00cb:
+ if(RFIFOB(2)==0)
+ chatlog.chat_log("Thanks for selling", BY_SERVER, font);
+ else
+ chatlog.chat_log("Unable to sell", BY_SERVER, font);
+ break;
+ // Add item to inventory after you bought it
+ case 0x00a0:
+ if(RFIFOB(22)>0)
+ chatlog.chat_log("Unable to pick up item", BY_SERVER, font);
+ else
+ inventoryWindow->addItem(RFIFOW(2), RFIFOW(6), RFIFOW(4));
+ break;
+ // Remove item to inventory after you sold it
+ case 0x00af:
+ printf("sell %i\n", -RFIFOW(4));
+ inventoryWindow->increaseQuantity(RFIFOW(2), -RFIFOW(4));
+ break;
+ // Use an item
+ case 0x01c8:
+ inventoryWindow->changeQuantity(RFIFOW(2), RFIFOW(10));
+ break;
+ // ??
+ case 0x0119:
+ sprintf(pkt_nfo, "%i %i %i %i", RFIFOL(2), RFIFOW(6), RFIFOW(8), RFIFOW(10));
+ //alert(pkt_nfo,"","","","",0,0);
+ break;
+ // Skill list
+ case 0x010f:
+ //n_skills = 0;
+ //SKILL *temp_skill = NULL;
+ //n_skills = (len-4)/37;
+ for(int k=0;k<(len-4)/37;k++) {
+ if(RFIFOW(4+k*37+6)!=0 || RFIFOB(4+k*37+36)!=0) {
+ SKILL *temp_skill = is_skill(RFIFOW(4+k*37));
+ if(temp_skill) {
+ temp_skill->lv = RFIFOW(4+k*37+6);
+ temp_skill->sp = RFIFOW(4+k*37+36);
+ if(temp_skill->sp<0)temp_skill->sp = 0;
+ } else {
+ n_skills++;
+ add_skill(RFIFOW(4+k*37), RFIFOW(4+k*37+6), RFIFOW(4+k*37+8));
+ }
+ }
+ }
+ break;
+ // MVP experience
+ case 0x010b:
+ break;
+ // Display MVP payer
+ case 0x010c:
+ chatlog.chat_log("MVP player", BY_SERVER, font);
+ break;
+ // Item drop
+ case 0x009e:
+ WFIFOW(0) = net_w_value(0x009f);
+ WFIFOL(2) = net_l_value(RFIFOL(2));
+ WFIFOSET(6);
+ break;
+ // Next button in NPC dialog
+ case 0x00b5:
+ strcpy(npc_button, "Next");
+ current_npc = RFIFOL(2);
+ break;
+ // Close button in NPC dialog
+ case 0x00b6:
+ strcpy(npc_button, "Close");
+ current_npc = RFIFOL(2);
+ break;
+ // List in NPC dialog
+ case 0x00b7:
+ current_npc = RFIFOL(4);
+ // Hammerbear: Second argument here shouldn't be neccesary,
+ // instead make sure the string is \0 terminated.
+ //parse_items(RFIFOP(8), RFIFOW(2));
+ npcListDialog->parseItems(RFIFOP(8));
+ RFIFOW(2);
+ npcListDialog->setVisible(true);
+ break;
+ // Look change
+ case 0x00c3:
+ // Change hair color
+ if (RFIFOB(6) == 6) {
+ node = find_node(RFIFOL(2));
+ node->hair_color = RFIFOB(7);
+ //char prova[100];
+ //sprintf(prova, "%i %i %i", RFIFOL(2), RFIFOB(6), RFIFOB(7));
+ //alert(prova,"","","","",0,0);
+ } else if (RFIFOB(6) == 1) {
+ node = find_node(RFIFOL(2));
+ node->hair_style = RFIFOB(7);
+ }
+ break;
+ case 0x00a4:
+ for (int i = 0; i < (RFIFOW(2) - 4) / 20; i++)
+ inventoryWindow->addItem(RFIFOW(4 + 20 * i), RFIFOW(6 + 20 * i), 1);
+ break;
+
+ // Manage non implemented packets
+ default:
+ //printf("%x\n",id);
+ //alert(pkt_nfo,"","","","",0,0);
+ break;
+ }
+ //alert(pkt_nfo,"","","","",0,0);
+
+ RFIFOSKIP(len);
+ }
}
- }
}