From 38725ab31230282aa04d6da8b865c75c36387b67 Mon Sep 17 00:00:00 2001 From: ai4rei Date: Sun, 15 May 2011 05:30:25 +0000 Subject: [PATCH] * Merged changes from trunk [14784:14819/trunk]. git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/renewal@14821 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Renewal.txt | 2 + conf/Changelog.txt | 3 + conf/battle/misc.conf | 11 ++ conf/maps_athena.conf | 18 +++ conf/msg_athena.conf | 5 +- db/Changelog.txt | 2 + db/item_db.txt | 2 + db/map_cache.dat | Bin 1940566 -> 1952236 bytes db/map_index.txt | 10 ++ db/mob_skill_db.txt | 2 +- db/packet_db.txt | 21 ++- doc/script_commands.txt | 124 +++++++++----- sql-files/main.sql | 3 +- sql-files/mob_db.sql | 12 +- sql-files/mob_db2.sql | 12 +- sql-files/upgrade_svn14796.sql | 1 + sql-files/upgrade_svn14797.sql | 1 + src/char/char.c | 39 ++++- src/char_sql/char.c | 22 ++- src/common/grfio.c | 71 +------- src/common/grfio.h | 5 +- src/common/mapindex.c | 10 -- src/common/mapindex.h | 3 - src/common/mmo.h | 3 + src/map/Makefile.in | 4 +- src/map/atcommand.c | 19 ++- src/map/atcommand.h | 2 +- src/map/battle.c | 2 + src/map/battle.h | 2 + src/map/battleground.c | 30 ++-- src/map/battleground.h | 4 +- src/map/chat.h | 2 +- src/map/clif.c | 226 ++++++++++++++++---------- src/map/clif.h | 4 +- src/map/duel.c | 189 ++++++++++++++++++++++ src/map/duel.h | 29 ++++ src/map/guild.c | 21 ++- src/map/instance.c | 13 +- src/map/intif.c | 2 +- src/map/map.c | 33 +++- src/map/map.h | 20 ++- src/map/mob.c | 54 +++---- src/map/mob.h | 28 ++-- src/map/npc.c | 30 ++-- src/map/npc.h | 1 + src/map/pc.c | 268 ++++++++++--------------------- src/map/pc.h | 137 ++++++++-------- src/map/quest.c | 20 +-- src/map/script.c | 43 +++-- src/map/status.c | 25 ++- src/map/status.h | 3 +- src/map/unit.c | 3 +- src/map/unit.h | 3 +- src/tool/mapcache.c | 2 +- tools/mob_db.pl | 12 +- vcproj-10/map-server_sql.vcxproj | 2 + vcproj-10/map-server_txt.vcxproj | 2 + vcproj-6/map-server_sql.dsp | 8 + vcproj-6/map-server_txt.dsp | 8 + vcproj-7.1/map-server_sql.vcproj | 6 + vcproj-7.1/map-server_txt.vcproj | 6 + vcproj-8/map-server_sql.vcproj | 8 + vcproj-8/map-server_txt.vcproj | 8 + vcproj-9/map-server_sql.vcproj | 8 + vcproj-9/map-server_txt.vcproj | 8 + 65 files changed, 1037 insertions(+), 640 deletions(-) create mode 100644 sql-files/upgrade_svn14796.sql create mode 100644 sql-files/upgrade_svn14797.sql create mode 100644 src/map/duel.c create mode 100644 src/map/duel.h diff --git a/Changelog-Renewal.txt b/Changelog-Renewal.txt index d0fac1b167..35f9a4ef04 100644 --- a/Changelog-Renewal.txt +++ b/Changelog-Renewal.txt @@ -1,5 +1,7 @@ Date Added +2011/05/15 + * Merged changes from trunk [14784:14819/trunk]. [Ai4rei] 2011/05/14 * Added Job Level stat bonuses for baby third classes. [Gepard] - Fixed Genetic High's VIT bonus being given at different level than Genetic's (since r14557). diff --git a/conf/Changelog.txt b/conf/Changelog.txt index a890c12526..85428aab0c 100644 --- a/conf/Changelog.txt +++ b/conf/Changelog.txt @@ -1,5 +1,8 @@ Date Added +2011/05/13 + * Rev. 14812 Added settings 'cashshop_show_points' and 'mail_show_status', both disabled by default, as the messages they control are custom (follow up to r11548 and r12264). [Ai4rei] + - Moved custom cash point update messages to 'msg_athena.conf' (IDs 504~506). 2011/03/15 * Rev. 14744 Fixed option 'monster_ai' referring to setting 'mob_npc_warp' rather than 'mob_warp' (follow up to r8135). [Ai4rei] 2011/03/06 diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf index 76d18ed0f9..797295aea9 100644 --- a/conf/battle/misc.conf +++ b/conf/battle/misc.conf @@ -128,3 +128,14 @@ searchstore_querydelay: 10 // Maximum amount of results a store search query may yield, before // it is canceled. searchstore_maxresults: 30 + +// Whether or not gaining and loosing of cash points is displayed (Note 1). +// Default: no +cashshop_show_points: no + +// Whether or not mail box status is displayed upon login. +// Default: 0 +// 0 = No +// 1 = Yes +// 2 = Yes, when there are unread mails +mail_show_status: 0 diff --git a/conf/maps_athena.conf b/conf/maps_athena.conf index 514a642a75..384802628c 100644 --- a/conf/maps_athena.conf +++ b/conf/maps_athena.conf @@ -679,6 +679,10 @@ map: tha_t12 map: auction_01 map: auction_02 +// ??? +// -- 2005-12-06gdata_k.gpf +alde_tt03 + // --- Garden City Hugel / Kiehl --- // -- 2005-12-20sdata_k.gpf -- map: hugel @@ -989,6 +993,20 @@ map: iz_dun05 // -- 2010-12-01data_x.gpf map: evt_mobroom +// ??? +map: dic_dun03 +//map: mjolnir_04_1 +//map: evt_swar_b +//map: evt_swar_r +//map: evt_swar_s +//map: evt_swar_t + +// Lighthalzen Dungeon F4, Wolfchev's Laboratory +// -- 2011-03-16rdata_x.gpf +map: 1@lhz +map: lhz_dun04 +map: que_lhz + //------------------------- Clone Maps --------------------------- //------------------------- Extra Maps --------------------------- diff --git a/conf/msg_athena.conf b/conf/msg_athena.conf index 973c3b8859..47417632ed 100644 --- a/conf/msg_athena.conf +++ b/conf/msg_athena.conf @@ -423,7 +423,10 @@ 502: Day Mode is activated 503: Night Mode is activated -// 504~506 are not used (previously super novice's guardian angel prayer) +// Cash point change messages +504: Used %d kafra points and %d cash points. %d kafra and %d cash points remaining. +505: Gained %d cash points. Total %d points. +506: Gained %d kafra points. Total %d points. // Trade Spoof Messages 507: This player has been banned for %d minute(s). diff --git a/db/Changelog.txt b/db/Changelog.txt index 3949237db3..156e642529 100644 --- a/db/Changelog.txt +++ b/db/Changelog.txt @@ -9,6 +9,8 @@ 13005 Angelic Wing Dagger: NEED INFO. ======================= +2011/04/16 + * Rev. 14797 Added Archangel Wings (2573) and their respective Box (16998) item based on client-side kRO description. [Ai4rei] 2011/03/19 * Rev. 14748 Fixed Beast Strafing (HT_POWER) SP requirement as provided by Playtester (bugreport:4675). [Gepard] 2011/03/06 diff --git a/db/item_db.txt b/db/item_db.txt index 225b2b1d96..5601c9a529 100644 --- a/db/item_db.txt +++ b/db/item_db.txt @@ -1445,6 +1445,7 @@ //2558,Freya_Soul_Scarf4,Freya Soul Scarf, //2559,Guardian_Manteau,Guardian Manteau, 2560,Para_Team_Manteau,Eden Team Manteau,5,0,,0,,14,,0,0xFFFFFFFF,7,2,4,,12,0,0,{ bonus2 bSubEle,Ele_Neutral,10; },{},{} +2573,Archangel_Wings,Archangel Wings,5,0,,200,,18,,1,0xFFFFFFFF,7,2,4,,0,1,1,{},{},{} // Accessories //=================================================================== 2601,Ring,Ring,5,30000,,100,,0,,0,0xFFFFFFFE,7,2,136,,20,0,0,{ bonus bStr,2; },{},{} @@ -6192,6 +6193,7 @@ 16680,Universal_Catalog_Gold_Box50,Universal Catalog Gold 50 Box,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ getitem 12581,50; },{},{} 16776,Universal_Catalog_Gold_Box10,Universal Catalog Gold 10 Box,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ getitem 12581,10; },{},{} 16777,Universal_Catalog_Gold_Box50,Universal Catalog Gold 50 Box,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ getitem 12581,50; },{},{} +16998,Archangel_Wings_Box,Archangel Wings Box,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ getitem 2573,1; },{},{} //18000,Cannon_Ball //18001,Holy_Cannon_Ball //18002,Dark_Cannon_Ball diff --git a/db/map_cache.dat b/db/map_cache.dat index de5e23957a9ce599a8c968be5c0fb1f08c01b710..6f034c6c7f96552d6bd76c5f9c488be17fb87ce8 100644 GIT binary patch delta 12693 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 delta 3835 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 t;)d1#NHP,; -This command works on the invoking character like 'heal', however, it is not -normally used in NPC scripts and will not work as expected there, but is used -all over in item scripts. - -Unlike 'heal', which just alters hp/sp and doesn't do anything else at all, this -command also shows healing animations for potions and other stuff, checks -whether the potion was made by a famous alchemist and alters the amount healed, -etc, etc. Since which kind of effect is shown depends on what item was used, -using it in an NPC script will not have a desired effect. +This command heals given absolute amounts of HP and/or SP on the invoking +character. Unlike heal, this command is intended for use in item scripts. It +applies potion-related bonuses, such as alchemist ranking, cards and status +changes. When used inside an NPC script, certain bonuses are omitted. There is also a nice example on using this with the 'rand' function, to give you a random amount of healing. @@ -5544,7 +5545,7 @@ currently ignored by the client and appears always green. 5,1.- End of time-related commands // -*announce "",{,{,{,{,{,}}}}}}; +*announce "",{,{,{,{,{,}}}}}; This command will broadcast a message to all or most players, similar to @kami/@kamib GM commands. @@ -6768,18 +6769,17 @@ This will open a book item at the specified page ======================== --------------------------------------- -*instance_create("",,) +*instance_create("",); -Create an instance using the name "" for the Party of . -Instance ID currently will only be ID_ENDLESS (5) or ID_CATACOMBS (6) -Most Instance_* commands are used in conjunction with this command and depend +Create an instance using the name "" for the Party of . +Most instance_* commands are used in conjunction with this command and depend on the ID this command returns. Example: // Store the Party ID of the invoking character. set .@party_id, getcharid(1); // Attempt to create an instance using that party ID. - set .@id, instance_create("Endless Tower", .@party_id, ID_ENDLESS); + set .@id, instance_create("Endless Tower", .@party_id); if (.@id == -1) { // Party ID is in use by another instance. ... } @@ -6788,67 +6788,111 @@ Example: } --------------------------------------- -*instance_destroy() +*instance_destroy {}; -Destroys instance with the ID . +Destroys instance with the ID . If no ID is specified, the instance, +the script is attached to, is used. If the script is not attached to an instance, +the instance of the currently attached player's party is used. If no player is +currently attached, the command fails and causes the script to halt. --------------------------------------- -*instance_attachmap(,"") -*instance_detachmap(,"") +*instance_attachmap("",{,}); -Attach or detach the map "" to the instance with the . +Attaches the map "" to the instance specified with . The +optional parameter specifies, whether a map requires emulation for instancing (1) +or not (0 = default). + +Returns the resulting map name on success or an empty string on failure. --------------------------------------- -*instance_init(); +*instance_detachmap ""{,}; -Initiate the instance of . +Detach the map "" to the instance with the . If no ID is +specified, the instance, the script is attached to, is used. If the script is not +attached to an instance, the instance of the currently attached player's party is +used. If no player is currently attached, the command fails and causes the script +to halt. --------------------------------------- -*instance_announce ,"",{,}; +*instance_init ; -Works like announce, but has the parameter, where 0 = active instance? +Initializes the instance given by . This copies all NPCs from the +source maps to the instanced maps. --------------------------------------- -*instance_attach(); +*instance_announce ,"",{,{,{,{,{,}}}}}; -Attaches a script to the provided ? +Works like announce, but has the parameter. If instance id is 0, the +instance, the script is attached to, is used. If the script is not attached to an +instance, the instance of the currently attached player's party is used. If no +player is currently attached, the command fails and causes the script to halt. --------------------------------------- -*instance_npcname("",) +*instance_attach ; -Retrieve the unique name given to a copy of an NPC for an instance, the given -"" that belongs to instance . Can be used with such commands -as enablenpc and disablenpc, donpcevent, etc. +Attaches the current script to the instance given by . --------------------------------------- -*has_instance("") +*instance_npcname(""{,}); -Check if the player has been queued for the instance. +Retrieves the unique name given to a copy of an NPC given by "" in an +instance specified . If no ID is specified, the instance, the script +is attached to, is used. If the script is not attached to an instance, the +instance of the currently attached player's party is used. If no player is +currently attached, the command fails and causes the script to halt. --------------------------------------- -*instance_id() +*has_instance(""{,}); -Apparently returns the ID the player is currently attached too. +Checks whether or not the given map belongs to specified instance. If no ID is +specified, the instance, the script is attached to, is used. If the script is not +attached to an instance, the instance of the currently attached player's party +is used. If no player is currently attached, the command fails and causes the +script to halt. + +Returns the name of the instanced map on success, otherwise an empty string. --------------------------------------- -*instance_warpall "",,; +*instance_id({}); -Warp all players in the instance to and given coordinates. +Retrieves the instance id, depending on . If type is not given, it defaults +to 0. + +Type: + 0 - Instance ID the script is attached to. + 1 - Instance ID of the currently attached player's party. --------------------------------------- -*instance_set_timeout ,,; +*instance_warpall "",,{,}; -Lifetime of for , while is how long until the -instance times out while inactive. +Warps all players in the instance to at given +coordinates. If no ID is specified, the instance, the script is attached to, +is used. If the script is not attached to an instance, the instance of the +currently attached player's party is used. If no player is currently attached, +the command fails and causes the script to halt. + +--------------------------------------- + +*instance_set_timeout ,{,}; + +Sets the timeout values for an instance given by . If no ID is +specified, the instance, the script is attached to, is used. If the script is +not attached to an instance, the instance of the currently attached player's +party is used. If no player is currently attached, the command fails and causes +the script to halt. + +Parameter specifies the total amount of time the instance will +exist. Parameter specifies how long players have, when they are +outside of the instance, until it is destroyed. --------------------------------------- diff --git a/sql-files/main.sql b/sql-files/main.sql index 239f8dac3d..feafcae3ed 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -83,11 +83,12 @@ CREATE TABLE IF NOT EXISTS `char` ( `hair` tinyint(4) unsigned NOT NULL default '0', `hair_color` smallint(5) unsigned NOT NULL default '0', `clothes_color` smallint(5) unsigned NOT NULL default '0', - `weapon` smallint(6) unsigned NOT NULL default '1', + `weapon` smallint(6) unsigned NOT NULL default '0', `shield` smallint(6) unsigned NOT NULL default '0', `head_top` smallint(6) unsigned NOT NULL default '0', `head_mid` smallint(6) unsigned NOT NULL default '0', `head_bottom` smallint(6) unsigned NOT NULL default '0', + `robe` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0', `last_map` varchar(11) NOT NULL default '', `last_x` smallint(4) unsigned NOT NULL default '53', `last_y` smallint(4) unsigned NOT NULL default '111', diff --git a/sql-files/mob_db.sql b/sql-files/mob_db.sql index 5f75922488..65630e76b6 100644 --- a/sql-files/mob_db.sql +++ b/sql-files/mob_db.sql @@ -18,12 +18,12 @@ CREATE TABLE `mob_db` ( `ATK2` smallint(6) unsigned NOT NULL default '0', `DEF` smallint(6) unsigned NOT NULL default '0', `MDEF` smallint(6) unsigned NOT NULL default '0', - `STR` tinyint(4) unsigned NOT NULL default '0', - `AGI` tinyint(4) unsigned NOT NULL default '0', - `VIT` tinyint(4) unsigned NOT NULL default '0', - `INT` tinyint(4) unsigned NOT NULL default '0', - `DEX` tinyint(4) unsigned NOT NULL default '0', - `LUK` tinyint(4) unsigned NOT NULL default '0', + `STR` smallint(6) unsigned NOT NULL default '0', + `AGI` smallint(6) unsigned NOT NULL default '0', + `VIT` smallint(6) unsigned NOT NULL default '0', + `INT` smallint(6) unsigned NOT NULL default '0', + `DEX` smallint(6) unsigned NOT NULL default '0', + `LUK` smallint(6) unsigned NOT NULL default '0', `Range2` tinyint(4) unsigned NOT NULL default '0', `Range3` tinyint(4) unsigned NOT NULL default '0', `Scale` tinyint(4) unsigned NOT NULL default '0', diff --git a/sql-files/mob_db2.sql b/sql-files/mob_db2.sql index d23483f7e5..188aa4c1f5 100644 --- a/sql-files/mob_db2.sql +++ b/sql-files/mob_db2.sql @@ -18,12 +18,12 @@ CREATE TABLE `mob_db2` ( `ATK2` smallint(6) unsigned NOT NULL default '0', `DEF` smallint(6) unsigned NOT NULL default '0', `MDEF` smallint(6) unsigned NOT NULL default '0', - `STR` tinyint(4) unsigned NOT NULL default '0', - `AGI` tinyint(4) unsigned NOT NULL default '0', - `VIT` tinyint(4) unsigned NOT NULL default '0', - `INT` tinyint(4) unsigned NOT NULL default '0', - `DEX` tinyint(4) unsigned NOT NULL default '0', - `LUK` tinyint(4) unsigned NOT NULL default '0', + `STR` smallint(6) unsigned NOT NULL default '0', + `AGI` smallint(6) unsigned NOT NULL default '0', + `VIT` smallint(6) unsigned NOT NULL default '0', + `INT` smallint(6) unsigned NOT NULL default '0', + `DEX` smallint(6) unsigned NOT NULL default '0', + `LUK` smallint(6) unsigned NOT NULL default '0', `Range2` tinyint(4) unsigned NOT NULL default '0', `Range3` tinyint(4) unsigned NOT NULL default '0', `Scale` tinyint(4) unsigned NOT NULL default '0', diff --git a/sql-files/upgrade_svn14796.sql b/sql-files/upgrade_svn14796.sql new file mode 100644 index 0000000000..21c1bcd550 --- /dev/null +++ b/sql-files/upgrade_svn14796.sql @@ -0,0 +1 @@ +ALTER TABLE `char` MODIFY `weapon` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0'; diff --git a/sql-files/upgrade_svn14797.sql b/sql-files/upgrade_svn14797.sql new file mode 100644 index 0000000000..acf6fb33db --- /dev/null +++ b/sql-files/upgrade_svn14797.sql @@ -0,0 +1 @@ +ALTER TABLE `char` ADD `robe` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0' AFTER `head_bottom`; diff --git a/src/char/char.c b/src/char/char.c index b499faf962..6599a62581 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -525,7 +525,7 @@ int mmo_char_tostr(char *str, struct mmo_charstatus *p, struct global_reg *reg, "%d\t%d,%d\t%s\t%d,%d,%d\t%u,%u,%d" //Up to Zeny field "\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d" //Up to Skill Point "\t%d,%d,%d\t%d,%d,%d,%d" //Up to hom id - "\t%d,%d,%d\t%d,%d,%d,%d,%d" //Up to head bottom + "\t%d,%d,%d\t%d,%d,%d,%d,%d,%d" //Up to robe "\t%d,%d,%d\t%d,%d,%d" //last point + save point ",%d,%d,%d,%d,%d,%lu\t", //Family info + delete date p->char_id, p->account_id, p->slot, p->name, // @@ -537,7 +537,7 @@ int mmo_char_tostr(char *str, struct mmo_charstatus *p, struct global_reg *reg, p->option, p->karma, p->manner, // p->party_id, p->guild_id, p->pet_id, p->hom_id, p->hair, p->hair_color, p->clothes_color, - p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom, + p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom, p->robe, p->last_point.map, p->last_point.x, p->last_point.y, // p->save_point.map, p->save_point.x, p->save_point.y, p->partner_id,p->father,p->mother,p->child,p->fame, // @@ -599,7 +599,26 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg // initilialise character memset(p, '\0', sizeof(struct mmo_charstatus)); -// Char structure of version 146xx (delete date) +// Char structure of version 14797 (robe) + if (sscanf(str, "%d\t%d,%d\t%127[^\t]\t%d,%d,%d\t%u,%u,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d" + "\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d,%d" + "\t%d,%d,%d\t%d,%d,%d,%d,%d,%d,%d,%d,%lu%n", + &tmp_int[0], &tmp_int[1], &tmp_int[2], tmp_str[0], + &tmp_int[3], &tmp_int[4], &tmp_int[5], + &tmp_uint[0], &tmp_uint[1], &tmp_int[8], + &tmp_int[9], &tmp_int[10], &tmp_int[11], &tmp_int[12], + &tmp_int[13], &tmp_int[14], &tmp_int[15], &tmp_int[16], &tmp_int[17], &tmp_int[18], + &tmp_int[19], &tmp_int[20], + &tmp_int[21], &tmp_int[22], &tmp_int[23], // + &tmp_int[24], &tmp_int[25], &tmp_int[26], &tmp_int[44], + &tmp_int[27], &tmp_int[28], &tmp_int[29], + &tmp_int[30], &tmp_int[31], &tmp_int[32], &tmp_int[33], &tmp_int[34], &tmp_int[47], + &tmp_int[45], &tmp_int[35], &tmp_int[36], + &tmp_int[46], &tmp_int[37], &tmp_int[38], &tmp_int[39], + &tmp_int[40], &tmp_int[41], &tmp_int[42], &tmp_int[43], &tmp_ulong[0], &next) != 50) + { + tmp_int[47] = 0; // robe +// Char structure of version 14700 (delete date) if (sscanf(str, "%d\t%d,%d\t%127[^\t]\t%d,%d,%d\t%u,%u,%d\t%d,%d,%d,%d\t%d,%d,%d,%d,%d,%d\t%d,%d" "\t%d,%d,%d\t%d,%d,%d,%d\t%d,%d,%d\t%d,%d,%d,%d,%d" "\t%d,%d,%d\t%d,%d,%d,%d,%d,%d,%d,%d,%lu%n", @@ -742,7 +761,8 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg tmp_int[45] = mapindex_name2id(tmp_str[1]); tmp_int[46] = mapindex_name2id(tmp_str[2]); } // Char structure of version 1500 (homun + mapindex maps) - } // Char structure of version 146xx (delete date) + } // Char structure of version 14700 (delete date) + } // Char structure of version 14797 (robe) safestrncpy(p->name, tmp_str[0], NAME_LENGTH); //Overflow protection [Skotlex] p->char_id = tmp_int[0]; @@ -793,6 +813,7 @@ int mmo_char_fromstr(char *str, struct mmo_charstatus *p, struct global_reg *reg p->last_point.map = tmp_int[45]; p->save_point.map = tmp_int[46]; p->delete_date = tmp_ulong[0]; + p->robe = tmp_int[47]; #ifndef TXT_SQL_CONVERT // Some checks @@ -1772,7 +1793,7 @@ int count_users(void) // Writes char data to the buffer in the format used by the client. // Used in packets 0x6b (chars info) and 0x6d (new char info) // Returns the size -#define MAX_CHAR_BUF 132 //Max size (for WFIFOHEAD calls) +#define MAX_CHAR_BUF 136 //Max size (for WFIFOHEAD calls) int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) { unsigned short offset = 0; @@ -1835,6 +1856,10 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) #if PACKETVER >= 20100803 WBUFL(buf,124) = TOL(p->delete_date); offset += 4; +#endif +#if PACKETVER >= 20110111 + WBUFL(buf,128) = p->robe; + offset += 4; #endif return 106+offset; } @@ -2001,6 +2026,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd) mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2); if (character->waiting_disconnect == INVALID_TIMER) character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0); + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 8; WFIFOSET(fd,3); @@ -2008,6 +2034,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd) } if (character->fd >= 0 && character->fd != fd) { //There's already a connection from this account that hasn't picked a char yet. + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 8; WFIFOSET(fd,3); @@ -2142,6 +2169,7 @@ int parse_fromlogin(int fd) if( max_connect_user && count_users() >= max_connect_user && sd->gmlevel < gm_allow_level ) { // refuse connection (over populated) + WFIFOHEAD(i,3); WFIFOW(i,0) = 0x6c; WFIFOW(i,2) = 0; WFIFOSET(i,3); @@ -2676,6 +2704,7 @@ int parse_frommap(int fd) data = status_search_scdata(aid, cid); if (data->count > 0) { //Deliver status change data. + WFIFOHEAD(fd,14 + data->count*sizeof(struct status_change_data)); WFIFOW(fd,0) = 0x2b1d; WFIFOW(fd,2) = 14 + data->count*sizeof(struct status_change_data); WFIFOL(fd,4) = aid; diff --git a/src/char_sql/char.c b/src/char_sql/char.c index 36de40bf51..5ad5a273b6 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -474,7 +474,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) (p->pet_id != cp->pet_id) || (p->weapon != cp->weapon) || (p->hom_id != cp->hom_id) || (p->shield != cp->shield) || (p->head_top != cp->head_top) || (p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) || - (p->rename != cp->rename) + (p->rename != cp->rename) || (p->robe != cp->robe) ) { //Save status if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `base_level`='%d', `job_level`='%d'," @@ -484,7 +484,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) "`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d'," "`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d'," "`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d'," - "`delete_date`='%lu'" + "`delete_date`='%lu',`robe`='%d'" " WHERE `account_id`='%d' AND `char_id` = '%d'", char_db, p->base_level, p->job_level, p->base_exp, p->job_exp, p->zeny, @@ -495,6 +495,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y, mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename, (unsigned long)p->delete_date, // FIXME: platform-dependent size + p->robe, p->account_id, p->char_id) ) { Sql_ShowDebug(sql_handle); @@ -844,7 +845,8 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) "`char_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`," "`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`," "`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`," - "`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`" + "`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`," + "`robe`" " FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS) || SQL_ERROR == SqlStmt_Execute(stmt) || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &p.char_id, 0, NULL, NULL) @@ -882,6 +884,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p.rename, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p.robe, 0, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); @@ -940,7 +943,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything "`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`," "`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`hair`," "`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`," - "`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`" + "`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`" " FROM `%s` WHERE `char_id`=? LIMIT 1", char_db) || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SqlStmt_Execute(stmt) @@ -994,6 +997,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything || SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT, &p->fame, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_SHORT, &p->rename, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 50, SQLDT_SHORT, &p->robe, 0, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); @@ -1550,7 +1554,7 @@ int count_users(void) // Writes char data to the buffer in the format used by the client. // Used in packets 0x6b (chars info) and 0x6d (new char info) // Returns the size -#define MAX_CHAR_BUF 132 //Max size (for WFIFOHEAD calls) +#define MAX_CHAR_BUF 136 //Max size (for WFIFOHEAD calls) int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) { unsigned short offset = 0; @@ -1613,6 +1617,10 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) #if PACKETVER >= 20100803 WBUFL(buf,124) = TOL(p->delete_date); offset += 4; +#endif +#if PACKETVER >= 20110111 + WBUFL(buf,128) = p->robe; + offset += 4; #endif return 106+offset; } @@ -1736,6 +1744,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd) mapif_disconnectplayer(server[character->server].fd, character->account_id, character->char_id, 2); if (character->waiting_disconnect == INVALID_TIMER) character->waiting_disconnect = add_timer(gettick()+20000, chardb_waiting_disconnect, character->account_id, 0); + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 8; WFIFOSET(fd,3); @@ -1743,6 +1752,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd) } if (character->fd >= 0 && character->fd != fd) { //There's already a connection from this account that hasn't picked a char yet. + WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x81; WFIFOB(fd,2) = 8; WFIFOSET(fd,3); @@ -1877,6 +1887,7 @@ int parse_fromlogin(int fd) if( max_connect_user && count_users() >= max_connect_user && sd->gmlevel < gm_allow_level ) { // refuse connection (over populated) + WFIFOHEAD(i,3); WFIFOW(i,0) = 0x6c; WFIFOW(i,2) = 0; WFIFOSET(i,3); @@ -3522,6 +3533,7 @@ int parse_char(int fd) //can't delete the char //either SQL error or can't delete by some CONFIG conditions //del fail + WFIFOHEAD(fd,3); WFIFOW(fd, 0) = 0x70; WFIFOB(fd, 2) = 0; WFIFOSET(fd, 3); diff --git a/src/common/grfio.c b/src/common/grfio.c index 3c0960f303..e7549ecb4c 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -7,7 +7,6 @@ #include #include "grfio.h" -#include #include "../common/cbasetypes.h" #include "../common/showmsg.h" @@ -216,70 +215,6 @@ static void decode_des_etc(unsigned char* buf, size_t len, int type, int cycle) } } } -/*========================================== - * Grf data decode sub : zip - *------------------------------------------*/ -int decode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen) -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = (Bytef*) dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} - -int encode_zip(unsigned char* dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen) -{ - z_stream stream; - int err; - memset(&stream, 0, sizeof(stream)); - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = (Bytef*) dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = deflateInit(&stream,Z_DEFAULT_COMPRESSION); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} unsigned long grfio_crc32 (const unsigned char* buf, unsigned int len) { @@ -496,9 +431,9 @@ void* grfio_reads(char* fname, int* size) if (entry->cycle >= 0) decode_des_etc(buf, entry->srclen_aligned, entry->cycle == 0, entry->cycle); len = entry->declen; - decode_zip(buf2, &len, buf, entry->srclen); + uncompress(buf2, &len, buf, entry->srclen); if (len != (uLong)entry->declen) { - ShowError("decode_zip size mismatch err: %d != %d\n", (int)len, entry->declen); + ShowError("uncompress size mismatch err: %d != %d\n", (int)len, entry->declen); aFree(buf); aFree(buf2); return NULL; @@ -645,7 +580,7 @@ static int grfio_entryread(char* grfname, int gentry) grf_filelist = (unsigned char *)aMallocA(eSize); // Get a Extend Size fread(rBuf,1,rSize,fp); fclose(fp); - decode_zip(grf_filelist, &eSize, rBuf, rSize); // Decode function + uncompress(grf_filelist, &eSize, rBuf, rSize); // Decode function list_size = eSize; aFree(rBuf); diff --git a/src/common/grfio.h b/src/common/grfio.h index 57439b16d7..d5334ccf3b 100644 --- a/src/common/grfio.h +++ b/src/common/grfio.h @@ -4,6 +4,8 @@ #ifndef _GRFIO_H_ #define _GRFIO_H_ +#include + void grfio_init(char*); // GRFIO Initialize void grfio_final(void); // GRFIO Finalize void* grfio_reads(char*,int*); // GRFIO data file read & size get @@ -14,7 +16,4 @@ char *grfio_find_file(char *fname); int grfio_size(char*); // GRFIO data file size get unsigned long grfio_crc32(const unsigned char *buf, unsigned int len); -int decode_zip(unsigned char *dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen); -int encode_zip(unsigned char *dest, unsigned long* destLen, const unsigned char* source, unsigned long sourceLen); - #endif /* _GRFIO_H_ */ diff --git a/src/common/mapindex.c b/src/common/mapindex.c index a1c86af979..be2913c695 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -128,18 +128,8 @@ unsigned short mapindex_name2id(const char* name) if (strcmp(indexes[i].name,map_name)==0) return i; } -#ifdef MAPINDEX_AUTOADD - if( mapindex_addmap(i,map_name) ) - { - ShowDebug("mapindex_name2id: Auto-added map \"%s\" to position %d\n", map_name, i); - return i; - } - ShowWarning("mapindex_name2id: Failed to auto-add map \"%s\" to position %d!\n", map_name, i); - return 0; -#else ShowDebug("mapindex_name2id: Map \"%s\" not found in index list!\n", map_name); return 0; -#endif } const char* mapindex_id2name(unsigned short id) diff --git a/src/common/mapindex.h b/src/common/mapindex.h index 06131d0a4d..854669ea61 100644 --- a/src/common/mapindex.h +++ b/src/common/mapindex.h @@ -7,9 +7,6 @@ //File in charge of assigning a numberic ID to each map in existance for space saving when passing map info between servers. extern char mapindex_cfgfile[80]; -//whether to enable auto-adding of maps during run. Not so secure as the map indexes will vary! -//#define MAPINDEX_AUTOADD - #define MAX_MAPINDEX 2000 //Some definitions for the mayor city maps. diff --git a/src/common/mmo.h b/src/common/mmo.h index 024008b7b6..0bc30ea47a 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -39,6 +39,8 @@ // 20100721 - 2010-07-21aRagexeRE+ - 0x6b, 0x6d // 20100727 - 2010-07-27aRagexeRE+ - 0x6b, 0x6d // 20100803 - 2010-08-03aRagexeRE+ - 0x6b, 0x6d, 0x827, 0x828, 0x829, 0x82a, 0x82b, 0x82c, 0x842, 0x843 +// 20101124 - 2010-11-24aRagexeRE+ - 0x856, 0x857, 0x858 +// 20110111 - 2011-01-11aRagexeRE+ - 0x6b, 0x6d #ifndef PACKETVER #define PACKETVER 20081126 @@ -329,6 +331,7 @@ struct mmo_charstatus { short weapon; // enum weapon_type short shield; // view-id short head_top,head_mid,head_bottom; + short robe; char name[NAME_LENGTH]; unsigned int base_level,job_level; diff --git a/src/map/Makefile.in b/src/map/Makefile.in index f45f4dd001..7070a0a9d7 100644 --- a/src/map/Makefile.in +++ b/src/map/Makefile.in @@ -18,7 +18,7 @@ MAP_OBJ = map.o chrif.o clif.o pc.o status.o npc.o \ storage.o skill.o atcommand.o battle.o battleground.o \ intif.o trade.o party.o vending.o guild.o pet.o \ log.o mail.o date.o unit.o homunculus.o mercenary.o quest.o instance.o \ - buyingstore.o searchstore.o + buyingstore.o searchstore.o duel.o MAP_TXT_OBJ = $(MAP_OBJ:%=obj_txt/%) \ obj_txt/mapreg_txt.o MAP_SQL_OBJ = $(MAP_OBJ:%=obj_sql/%) \ @@ -28,7 +28,7 @@ MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \ storage.h skill.h atcommand.h battle.h battleground.h \ intif.h trade.h party.h vending.h guild.h pet.h \ log.h mail.h date.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h \ - buyingstore.h searchstore.h + buyingstore.h searchstore.h duel.h HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 3eb0c37acd..7d66d1694d 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -17,6 +17,7 @@ #include "chat.h" #include "clif.h" #include "chrif.h" +#include "duel.h" #include "intif.h" #include "itemdb.h" #include "log.h" @@ -88,7 +89,7 @@ int lowtohigh_compare (const void * a, const void * b) //----------------------------------------------------------- // Return the message string of the specified number by [Yor] //----------------------------------------------------------- -char* msg_txt(int msg_number) +const char* msg_txt(int msg_number) { if (msg_number >= 0 && msg_number < MAX_MSG && msg_table[msg_number] != NULL && msg_table[msg_number][0] != '\0') @@ -5837,7 +5838,7 @@ ACMD_FUNC(skilltree) struct map_session_data *pl_sd = NULL; int skillnum; int meets, j, c=0; - char target[NAME_LENGTH], *tbl; + char target[NAME_LENGTH]; struct skill_tree_entry *ent; nullpo_retr(-1, sd); @@ -5855,9 +5856,7 @@ ACMD_FUNC(skilltree) c = pc_calc_skilltree_normalize_job(pl_sd); c = pc_mapid2jobid(c, pl_sd->status.sex); - tbl = job_name(c); - - sprintf(atcmd_output, "Player is using %s skill tree (%d basic points)", tbl, pc_checkskill(pl_sd, 1)); + sprintf(atcmd_output, "Player is using %s skill tree (%d basic points)", job_name(c), pc_checkskill(pl_sd, 1)); clif_displaymessage(fd, atcmd_output); ARR_FIND( 0, MAX_SKILL_TREE, j, skill_tree[c][j].id == 0 || skill_tree[c][j].id == skillnum ); @@ -7250,7 +7249,7 @@ ACMD_FUNC(makehomun) int homunid; nullpo_retr(-1, sd); - if ( merc_is_hom_active(sd->hd) ) { + if ( sd->status.hom_id ) { clif_displaymessage(fd, msg_txt(450)); return -1; } @@ -8652,9 +8651,9 @@ ACMD_FUNC(font) font_id = atoi(message); if( font_id == 0 ) { - if( sd->state.user_font ) + if( sd->user_font ) { - sd->state.user_font = 0; + sd->user_font = 0; clif_displaymessage(fd, "Returning to normal font."); clif_font(sd); } @@ -8666,9 +8665,9 @@ ACMD_FUNC(font) } else if( font_id < 0 || font_id > 9 ) clif_displaymessage(fd, "Invalid font. Use a Value from 0 to 9."); - else if( font_id != sd->state.user_font ) + else if( font_id != sd->user_font ) { - sd->state.user_font = font_id; + sd->user_font = font_id; clif_font(sd); clif_displaymessage(fd, "Font changed."); } diff --git a/src/map/atcommand.h b/src/map/atcommand.h index 37ce87ca30..5456bc3487 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -41,7 +41,7 @@ int atcommand_killmonster(const int fd, struct map_session_data* sd, const char* #define MAX_MSG 1000 extern char* msg_table[MAX_MSG]; -char* msg_txt(int msg_number); +const char* msg_txt(int msg_number); int msg_config_read(const char* cfgName); void do_final_msg(void); diff --git a/src/map/battle.c b/src/map/battle.c index 40e59039be..11e696a7fd 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -4012,6 +4012,8 @@ static const struct _battle_data { { "searchstore_querydelay", &battle_config.searchstore_querydelay, 10, 0, INT_MAX, }, { "searchstore_maxresults", &battle_config.searchstore_maxresults, 30, 1, INT_MAX, }, { "display_party_name", &battle_config.display_party_name, 0, 0, 1, }, + { "cashshop_show_points", &battle_config.cashshop_show_points, 0, 0, 1, }, + { "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, }, // BattleGround Settings { "bg_update_interval", &battle_config.bg_update_interval, 1000, 100, INT_MAX, }, { "bg_short_attack_damage_rate", &battle_config.bg_short_damage_rate, 80, 0, INT_MAX, }, diff --git a/src/map/battle.h b/src/map/battle.h index b2f33b73b3..58f6223216 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -486,6 +486,8 @@ extern struct Battle_Config int searchstore_querydelay; int searchstore_maxresults; int display_party_name; + int cashshop_show_points; + int mail_show_status; // [BattleGround Settings] int bg_update_interval; diff --git a/src/map/battleground.c b/src/map/battleground.c index 58e3b469cb..13f62a0422 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -52,7 +52,7 @@ int bg_team_delete(int bg_id) continue; bg_send_dot_remove(sd); - sd->state.bg_id = 0; + sd->bg_id = 0; } idb_remove(bg_team_db, bg_id); return 1; @@ -70,7 +70,7 @@ int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y) int bg_send_dot_remove(struct map_session_data *sd) { - if( sd && sd->state.bg_id ) + if( sd && sd->bg_id ) clif_bg_xy_remove(sd); return 0; } @@ -81,12 +81,12 @@ int bg_team_join(int bg_id, struct map_session_data *sd) struct battleground_data *bg = bg_team_search(bg_id); struct map_session_data *pl_sd; - if( bg == NULL || sd == NULL || sd->state.bg_id ) return 0; + if( bg == NULL || sd == NULL || sd->bg_id ) return 0; ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL); if( i == MAX_BG_MEMBERS ) return 0; // No free slots - sd->state.bg_id = bg_id; + sd->bg_id = bg_id; bg->members[i].sd = sd; bg->members[i].x = sd->bl.x; bg->members[i].y = sd->bl.y; @@ -111,12 +111,12 @@ int bg_team_leave(struct map_session_data *sd, int flag) struct battleground_data *bg; char output[128]; - if( sd == NULL || !sd->state.bg_id ) + if( sd == NULL || !sd->bg_id ) return 0; bg_send_dot_remove(sd); - bg_id = sd->state.bg_id; - sd->state.bg_id = 0; + bg_id = sd->bg_id; + sd->bg_id = 0; if( (bg = bg_team_search(bg_id)) == NULL ) return 0; @@ -141,7 +141,7 @@ int bg_team_leave(struct map_session_data *sd, int flag) int bg_member_respawn(struct map_session_data *sd) { // Respawn after killed struct battleground_data *bg; - if( sd == NULL || !pc_isdead(sd) || !sd->state.bg_id || (bg = bg_team_search(sd->state.bg_id)) == NULL ) + if( sd == NULL || !pc_isdead(sd) || !sd->bg_id || (bg = bg_team_search(sd->bg_id)) == NULL ) return 0; if( bg->mapindex == 0 ) return 0; // Respawn not handled by Core @@ -177,26 +177,26 @@ int bg_team_get_id(struct block_list *bl) switch( bl->type ) { case BL_PC: - return ((TBL_PC*)bl)->state.bg_id; + return ((TBL_PC*)bl)->bg_id; case BL_PET: if( ((TBL_PET*)bl)->msd ) - return ((TBL_PET*)bl)->msd->state.bg_id; + return ((TBL_PET*)bl)->msd->bg_id; break; case BL_MOB: { struct map_session_data *msd; struct mob_data *md = (TBL_MOB*)bl; if( md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL ) - return msd->state.bg_id; - return md->state.bg_id; + return msd->bg_id; + return md->bg_id; } case BL_HOM: if( ((TBL_HOM*)bl)->master ) - return ((TBL_HOM*)bl)->master->state.bg_id; + return ((TBL_HOM*)bl)->master->bg_id; break; case BL_MER: if( ((TBL_MER*)bl)->master ) - return ((TBL_MER*)bl)->master->state.bg_id; + return ((TBL_MER*)bl)->master->bg_id; break; case BL_SKILL: return ((TBL_SKILL*)bl)->group->bg_id; @@ -210,7 +210,7 @@ int bg_send_message(struct map_session_data *sd, const char *mes, int len) struct battleground_data *bg; nullpo_ret(sd); - if( sd->state.bg_id == 0 || (bg = bg_team_search(sd->state.bg_id)) == NULL ) + if( sd->bg_id == 0 || (bg = bg_team_search(sd->bg_id)) == NULL ) return 0; clif_bg_message(bg, sd->bl.id, sd->status.name, mes, len); return 0; diff --git a/src/map/battleground.h b/src/map/battleground.h index 946ac2692e..c2b74a534f 100644 --- a/src/map/battleground.h +++ b/src/map/battleground.h @@ -22,8 +22,8 @@ struct battleground_data { // BG Cementery unsigned short mapindex, x, y; // Logout Event - char logout_event[50]; - char die_event[50]; + char logout_event[EVENT_NAME_LENGTH]; + char die_event[EVENT_NAME_LENGTH]; }; void do_init_battleground(void); diff --git a/src/map/chat.h b/src/map/chat.h index be3efb513c..b80832d3df 100644 --- a/src/map/chat.h +++ b/src/map/chat.h @@ -22,7 +22,7 @@ struct chat_data { uint32 maxLvl; // maximum base level allowed to join struct map_session_data* usersd[20]; struct block_list* owner; - char npc_event[50]; + char npc_event[EVENT_NAME_LENGTH]; }; diff --git a/src/map/clif.c b/src/map/clif.c index e4105c170a..eeb9f75321 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -451,7 +451,7 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target if( !(fd=sd->fd) ) continue; - if( type == GUILD_NOBG && sd->state.bg_id ) + if( type == GUILD_NOBG && sd->bg_id ) continue; if( sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS) ) @@ -498,7 +498,7 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target case BG_SAMEMAP_WOS: case BG: case BG_WOS: - if( sd && sd->state.bg_id && (bg = bg_team_search(sd->state.bg_id)) != NULL ) + if( sd && sd->bg_id && (bg = bg_team_search(sd->bg_id)) != NULL ) { for( i = 0; i < MAX_BG_MEMBERS; i++ ) { @@ -797,13 +797,19 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool WBUFW(buf,0) = spawn?0x22b:0x22a; #elif PACKETVER < 20091103 WBUFW(buf,0) = spawn?0x2ed:0x2ee; -#else +#elif PACKETVER < 20101124 WBUFW(buf,0) = spawn?0x7f8:0x7f9; +#else + WBUFW(buf,0) = spawn?0x858:0x857; #endif #if PACKETVER >= 20091103 name = status_get_name(bl); +#if PACKETVER < 20110111 WBUFW(buf,2) = (spawn?62:63)+strlen(name); +#else + WBUFW(buf,2) = (spawn?64:65)+strlen(name); +#endif WBUFB(buf,4) = clif_bl_type(bl); offset+=3; buf = WBUFP(buffer,offset); @@ -876,6 +882,11 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool WBUFB(buf,40) = 0; return packet_len(0x7c); } +#endif +#if PACKETVER >= 20110111 + WBUFW(buf,34) = vd->robe; + offset+= 2; + buf = WBUFP(buffer,offset); #endif WBUFL(buf,34) = status_get_guild_id(bl); WBUFW(buf,38) = status_get_emblem_id(bl); @@ -910,7 +921,7 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool return packet_len(WBUFW(buffer,0)); #endif #if PACKETVER >= 20080102 - WBUFW(buf,53) = sd?sd->state.user_font:0; + WBUFW(buf,53) = sd?sd->user_font:0; #endif #if PACKETVER >= 20091103 strcpy((char*)WBUFP(buf,55), name); @@ -946,13 +957,19 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un WBUFW(buf, 0) = 0x22c; #elif PACKETVER < 20091103 WBUFW(buf, 0) = 0x2ec; -#else +#elif PACKETVER < 20101124 WBUFW(buf, 0) = 0x7f7; +#else + WBUFW(buf, 0) = 0x856; #endif #if PACKETVER >= 20091103 name = status_get_name(bl); +#if PACKETVER < 20110111 WBUFW(buf, 2) = 69+strlen(name); +#else + WBUFW(buf, 2) = 71+strlen(name); +#endif offset+=2; buf = WBUFP(buffer,offset); #endif @@ -989,6 +1006,11 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un WBUFW(buf,32) = vd->hair_color; WBUFW(buf,34) = vd->cloth_color; WBUFW(buf,36) = (sd)? sd->head_dir : 0; +#if PACKETVER >= 20110111 + WBUFW(buf,38) = vd->robe; + offset+= 2; + buf = WBUFP(buffer,offset); +#endif WBUFL(buf,38) = status_get_guild_id(bl); WBUFW(buf,42) = status_get_emblem_id(bl); WBUFW(buf,44) = (sd)? sd->status.manner : 0; @@ -1006,7 +1028,7 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un WBUFB(buf,57) = (sd)? 5 : 0; WBUFW(buf,58) = clif_setlevel(status_get_lv(bl)); #if PACKETVER >= 20080102 - WBUFW(buf,60) = sd?sd->state.user_font:0; + WBUFW(buf,60) = sd?sd->user_font:0; #endif #if PACKETVER >= 20091103 strcpy((char*)WBUFP(buf,62), name); @@ -1144,7 +1166,7 @@ int clif_spawn(struct block_list *bl) clif_specialeffect(bl,423,AREA); else if(sd->state.size==1) clif_specialeffect(bl,421,AREA); - if( sd->state.bg_id && map[sd->bl.m].flag.battleground ) + if( sd->bg_id && map[sd->bl.m].flag.battleground ) clif_sendbgemblem_area(sd); } break; @@ -2057,7 +2079,7 @@ void clif_inventorylist(struct map_session_data *sd) WBUFW(bufe,ne*se+28)=0; //Unknown #endif #if PACKETVER >= 20100629 - if (sd->inventory_data[i]->equip&EQP_HELM) + if (sd->inventory_data[i]->equip&EQP_VISIBLE) WBUFW(bufe,ne*se+30)= sd->inventory_data[i]->look; else WBUFW(bufe,ne*se+30)=0; @@ -2140,7 +2162,7 @@ void clif_equiplist(struct map_session_data *sd) WBUFW(buf,n*cmd+28)=0; //Unknown #endif #if PACKETVER >= 20100629 - if (sd->inventory_data[i]->equip&EQP_HELM) + if (sd->inventory_data[i]->equip&EQP_VISIBLE) WBUFW(buf,n*cmd+30)= sd->inventory_data[i]->look; else WBUFW(buf,n*cmd+30)=0; @@ -2350,7 +2372,7 @@ int clif_guild_xy(struct map_session_data *sd) *------------------------------------------*/ int clif_guild_xy_single(int fd, struct map_session_data *sd) { - if( sd->state.bg_id ) + if( sd->bg_id ) return 0; WFIFOHEAD(fd,packet_len(0x1eb)); @@ -2449,7 +2471,7 @@ int clif_updatestatus(struct map_session_data *sd,int type) clif_hpmeter(sd); if( !battle_config.party_hp_mode && sd->status.party_id ) clif_party_hp(sd); - if( sd->state.bg_id ) + if( sd->bg_id ) clif_bg_hp(sd); break; case SP_SP: @@ -2705,6 +2727,17 @@ void clif_changelook(struct block_list *bl,int type,int val) #endif //Shoes? No packet uses this.... break; + case LOOK_BODY: + case LOOK_FLOOR: + // unknown purpose + break; + case LOOK_ROBE: +#if PACKETVER < 20110111 + return; +#else + vd->robe = val; +#endif + break; } // prevent leaking the presence of GM-hidden objects @@ -2726,8 +2759,7 @@ void clif_changelook(struct block_list *bl,int type,int val) WBUFW(buf,9)=vd->shield; } else { WBUFB(buf,6)=type; - WBUFW(buf,7)=val; - WBUFW(buf,9)=0; + WBUFL(buf,7)=val; } clif_send(buf,packet_len(0x1d7),bl,target); #endif @@ -2952,7 +2984,7 @@ int clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok) #if PACKETVER < 20100629 WFIFOB(fd,6)=ok; #else - if (ok && sd->inventory_data[n]->equip&EQP_HELM) + if (ok && sd->inventory_data[n]->equip&EQP_VISIBLE) WFIFOW(fd,6)=sd->inventory_data[n]->look; else WFIFOW(fd,6)=0; @@ -3649,7 +3681,7 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d clif_spiritball_single(sd->fd, dstsd); if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting. - (sd->state.bg_id && sd->state.bg_id == dstsd->state.bg_id) || //BattleGround + (sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround (battle_config.disp_hpmeter && (gmlvl = pc_isGM(sd)) >= battle_config.disp_hpmeter && gmlvl >= pc_isGM(dstsd)) ) clif_hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp); @@ -3692,7 +3724,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) clif_specialeffect_single(bl,423,sd->fd); else if(tsd->state.size==1) clif_specialeffect_single(bl,421,sd->fd); - if( tsd->state.bg_id && map[tsd->bl.m].flag.battleground ) + if( tsd->bg_id && map[tsd->bl.m].flag.battleground ) clif_sendbgemblem_single(sd->fd,tsd); } break; @@ -4972,17 +5004,12 @@ void clif_MainChatMessage(const char* message) /*========================================== * Send broadcast message with font formatting. * S 01C3 .W .L .W .W .W .W .?B - * S 040C .W .L .W .W .W .W .?B *------------------------------------------*/ int clif_broadcast2(struct block_list* bl, const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target) { unsigned char *buf = (unsigned char*)aMallocA((16 + len)*sizeof(unsigned char)); -#if PACKETVER < 20080820 WBUFW(buf,0) = 0x1c3; -#else - WBUFW(buf,0) = 0x40c; -#endif WBUFW(buf,2) = len + 16; WBUFL(buf,4) = fontColor; WBUFW(buf,8) = fontType; @@ -6986,7 +7013,7 @@ int clif_guild_leave(struct map_session_data *sd,const char *name,const char *me /*========================================== * ギルドメンバ追放通知 *------------------------------------------*/ -int clif_guild_expulsion(struct map_session_data *sd,const char *name,const char *mes,int account_id) +void clif_guild_expulsion(struct map_session_data* sd, const char* name, const char* mes, int account_id) { unsigned char buf[128]; #if PACKETVER < 20100803 @@ -6995,46 +7022,58 @@ int clif_guild_expulsion(struct map_session_data *sd,const char *name,const char const unsigned short cmd = 0x839; #endif - nullpo_ret(sd); + nullpo_retv(sd); WBUFW(buf,0) = cmd; - safestrncpy((char*)WBUFP(buf, 2),name,NAME_LENGTH); - safestrncpy((char*)WBUFP(buf,26),mes,40); + safestrncpy((char*)WBUFP(buf,2), name, NAME_LENGTH); + safestrncpy((char*)WBUFP(buf,26), mes, 40); #if PACKETVER < 20100803 - safestrncpy((char*)WBUFP(buf,66),"",NAME_LENGTH); // account name (not used for security reasons) + memset(WBUFP(buf,66), 0, NAME_LENGTH); // account name (not used for security reasons) #endif - clif_send(buf,packet_len(cmd),&sd->bl,GUILD_NOBG); - return 0; + clif_send(buf, packet_len(cmd), &sd->bl, GUILD_NOBG); } /*========================================== * ギルド追放メンバリスト *------------------------------------------*/ -int clif_guild_expulsionlist(struct map_session_data *sd) +void clif_guild_expulsionlist(struct map_session_data* sd) { - int fd; - int i,c; - struct guild *g; +#if PACKETVER < 20100803 + const int offset = NAME_LENGTH*2+40; +#else + const int offset = NAME_LENGTH+40; +#endif + int fd, i, c = 0; + struct guild* g; + + nullpo_retv(sd); - nullpo_ret(sd); if( (g = guild_search(sd->status.guild_id)) == NULL ) - return 0; + return; fd = sd->fd; - WFIFOHEAD(fd,4 + MAX_GUILDEXPULSION * 88); - WFIFOW(fd,0)=0x163; - for(i=c=0;iexpulsion[i]; - if(e->account_id>0){ - safestrncpy((char*)WFIFOP(fd,4 + c*88),e->name,NAME_LENGTH); - safestrncpy((char*)WFIFOP(fd,4 + c*88+24),"",24); // account name (not used for security reasons) - safestrncpy((char*)WFIFOP(fd,4 + c*88+48),e->mes,40); + + WFIFOHEAD(fd,4 + MAX_GUILDEXPULSION * offset); + WFIFOW(fd,0) = 0x163; + + for( i = 0; i < MAX_GUILDEXPULSION; i++ ) + { + struct guild_expulsion* e = &g->expulsion[i]; + + if( e->account_id > 0 ) + { + memcpy(WFIFOP(fd,4 + c*offset), e->name, NAME_LENGTH); +#if PACKETVER < 20100803 + memset(WFIFOP(fd,4 + c*offset+24), 0, NAME_LENGTH); // account name (not used for security reasons) + memcpy(WFIFOP(fd,4 + c*offset+48), e->mes, 40); +#else + memcpy(WFIFOP(fd,4 + c*offset+24), e->mes, 40); +#endif c++; } } - WFIFOW(fd,2) = 4 + c*88; + WFIFOW(fd,2) = 4 + c*offset; WFIFOSET(fd,WFIFOW(fd,2)); - return 0; } /*========================================== @@ -8024,15 +8063,15 @@ void clif_equipcheckbox(struct map_session_data* sd) WFIFOSET(fd, packet_len(0x2da)); } -/*========================================== - * Sends info about a player's equipped items - * R 002d7 .W .24B .w .w .w .w .w .w .w .1B {equip item}.26B* - * for PACKETVER >= 20100629 - * R 002d7 .W .24B .w .w .w .w .w .w .w .1B {equip item}.28B* - *------------------------------------------*/ +/// Sends info about a player's equipped items (ZC_EQUIPWIN_MICROSCOPE) +/// 02d7 .W .24B .W .W .W .W .W .W .W .B {equip item}.26B* +/// 02d7 .W .24B .W .W .W .W .W .W .W .B {equip item}.28B* (PACKETVER >= 20100629) +/// 0859 .W .24B .W .W .W .W .W .W .W .B {equip item}.28B* (PACKETVER >= 20101124) +/// 0859 .W .24B .W .W .W .W .W .W .W .W .B {equip item}.28B* (PACKETVER >= 20110111) void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd) { - int i, n, fd; + uint8* buf; + int i, n, fd, offset = 0; #if PACKETVER < 20100629 const int s = 26; #else @@ -8043,17 +8082,27 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts fd = sd->fd; WFIFOHEAD(fd, MAX_INVENTORY * s + 43); + buf = WFIFOP(fd,0); - WFIFOW(fd, 0) = 0x2d7; - safestrncpy((char*)WFIFOP(fd, 4), tsd->status.name, NAME_LENGTH); - WFIFOW(fd,28) = tsd->status.class_; - WFIFOW(fd,30) = tsd->vd.hair_style; - WFIFOW(fd,32) = tsd->vd.head_bottom; - WFIFOW(fd,34) = tsd->vd.head_mid; - WFIFOW(fd,36) = tsd->vd.head_top; - WFIFOW(fd,38) = tsd->vd.hair_color; - WFIFOW(fd,40) = tsd->vd.cloth_color; - WFIFOB(fd,42) = tsd->vd.sex; +#if PACKETVER < 20101124 + WBUFW(buf, 0) = 0x2d7; +#else + WBUFW(buf, 0) = 0x859; +#endif + safestrncpy((char*)WBUFP(buf, 4), tsd->status.name, NAME_LENGTH); + WBUFW(buf,28) = tsd->status.class_; + WBUFW(buf,30) = tsd->vd.hair_style; + WBUFW(buf,32) = tsd->vd.head_bottom; + WBUFW(buf,34) = tsd->vd.head_mid; + WBUFW(buf,36) = tsd->vd.head_top; +#if PACKETVER >= 20110111 + WBUFW(buf,38) = tsd->vd.robe; + offset+= 2; + buf = WBUFP(buf,2); +#endif + WBUFW(buf,38) = tsd->vd.hair_color; + WBUFW(buf,40) = tsd->vd.cloth_color; + WBUFB(buf,42) = tsd->vd.sex; for(i=0,n=0; i < MAX_INVENTORY; i++) { @@ -8063,24 +8112,24 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts continue; // Inventory position - WFIFOW(fd, n*s+43) = i + 2; + WBUFW(buf, n*s+43) = i + 2; // Add refine, identify flag, element, etc. - clif_item_sub(WFIFOP(fd,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc_equippoint(tsd, i)); + clif_item_sub(WBUFP(buf,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc_equippoint(tsd, i)); // Add cards - clif_addcards(WFIFOP(fd, n*s+55), &tsd->status.inventory[i]); + clif_addcards(WBUFP(buf, n*s+55), &tsd->status.inventory[i]); // Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes) - WFIFOL(fd, n*s+63) = tsd->status.inventory[i].expire_time; - WFIFOW(fd, n*s+67) = 0; + WBUFL(buf, n*s+63) = tsd->status.inventory[i].expire_time; + WBUFW(buf, n*s+67) = 0; #if PACKETVER >= 20100629 - if (tsd->inventory_data[i]->equip&EQP_HELM) - WFIFOW(fd, n*s+69) = tsd->inventory_data[i]->look; + if (tsd->inventory_data[i]->equip&EQP_VISIBLE) + WBUFW(buf, n*s+69) = tsd->inventory_data[i]->look; else - WFIFOW(fd, n*s+69) = 0; + WBUFW(buf, n*s+69) = 0; #endif n++; } - WFIFOW(fd, 2) = 43 + n*s; // Set length + WFIFOW(fd, 2) = 43+offset+n*s; // Set length WFIFOSET(fd, WFIFOW(fd, 2)); } @@ -8443,13 +8492,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_party_hp(sd); // Show hp after displacement [LuzZza] } - if( sd->state.bg_id ) clif_bg_hp(sd); // BattleGround System - if( sd->state.changemap && map[sd->bl.m].flag.battleground ) - { - clif_map_type(sd, MAPTYPE_BATTLEFIELD); // Battleground Mode - if( map[sd->bl.m].flag.battleground == 2 ) - clif_bg_updatescore_single(sd); - } + if( sd->bg_id ) clif_bg_hp(sd); // BattleGround System if(map[sd->bl.m].flag.pvp) { if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris] @@ -8606,6 +8649,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_status_load(&sd->bl, SI_NIGHT, 0); } + if( map[sd->bl.m].flag.battleground ) + { + clif_map_type(sd, MAPTYPE_BATTLEFIELD); // Battleground Mode + if( map[sd->bl.m].flag.battleground == 2 ) + clif_bg_updatescore_single(sd); + } + if( map[sd->bl.m].flag.allowks && !map_flag_ks(sd->bl.m) ) { char output[128]; @@ -9642,7 +9692,8 @@ void clif_parse_ChatLeave(int fd, struct map_session_data* sd) //0: static void clif_noask_sub(struct map_session_data *src, struct map_session_data *target, int type) { - char *msg, output[256]; + const char* msg; + char output[256]; // Your request has been rejected by autoreject option. msg = msg_txt(392); clif_disp_onlyself(src, msg, strlen(msg)); @@ -10928,7 +10979,7 @@ void clif_parse_GuildCheckMaster(int fd, struct map_session_data *sd) *------------------------------------------*/ void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd) { - if( !sd->status.guild_id && !sd->state.bg_id ) + if( !sd->status.guild_id && !sd->bg_id ) return; switch( RFIFOL(fd,2) ) @@ -11076,7 +11127,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd) clif_displaymessage(fd, msg_txt(228)); return; } - if( sd->state.bg_id ) + if( sd->bg_id ) { clif_displaymessage(fd, "You can't leave battleground guilds."); return; @@ -11091,7 +11142,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd) *------------------------------------------*/ void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd) { - if( map[sd->bl.m].flag.guildlock || sd->state.bg_id ) + if( map[sd->bl.m].flag.guildlock || sd->bg_id ) { // Guild locked. clif_displaymessage(fd, msg_txt(228)); return; @@ -11128,7 +11179,7 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd) sd->cantalk_tick = gettick() + battle_config.min_chat_delay; } - if( sd->state.bg_id ) + if( sd->bg_id ) bg_send_message(sd, text, textlen); else guild_send_message(sd, text, textlen); @@ -13859,7 +13910,7 @@ int clif_sendbgemblem_area(struct map_session_data *sd) WBUFW(buf, 0) = 0x2dd; WBUFL(buf,2) = sd->bl.id; safestrncpy((char*)WBUFP(buf,6), sd->status.name, NAME_LENGTH); // name don't show in screen. - WBUFW(buf,30) = sd->state.bg_id; + WBUFW(buf,30) = sd->bg_id; clif_send(buf,packet_len(0x2dd), &sd->bl, AREA); return 0; } @@ -13871,7 +13922,7 @@ int clif_sendbgemblem_single(int fd, struct map_session_data *sd) WFIFOW(fd,0) = 0x2dd; WFIFOL(fd,2) = sd->bl.id; safestrncpy((char*)WFIFOP(fd,6), sd->status.name, NAME_LENGTH); - WFIFOW(fd,30) = sd->state.bg_id; + WFIFOW(fd,30) = sd->bg_id; WFIFOSET(fd,packet_len(0x2dd)); return 0; } @@ -13886,7 +13937,7 @@ int clif_font(struct map_session_data *sd) nullpo_ret(sd); WBUFW(buf,0) = 0x2ef; WBUFL(buf,2) = sd->bl.id; - WBUFW(buf,6) = sd->state.user_font; + WBUFW(buf,6) = sd->user_font; clif_send(buf, packet_len(0x2ef), &sd->bl, AREA); return 1; } @@ -14977,6 +15028,11 @@ static int packetdb_readdb(void) 3, -1, 8, -1, 86, 2, 6, 6, -1, -1, 4, 10, 10, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 3, 2, 66, 5, 2, 12, 6, 0, 0, + //#0x0840 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; struct { void (*func)(int, struct map_session_data *); diff --git a/src/map/clif.h b/src/map/clif.h index 2d90eb522a..70a7fdce84 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -29,7 +29,7 @@ struct party_booking_ad_info; #include // packet DB #define MAX_PACKET_DB 0x900 -#define MAX_PACKET_VER 25 +#define MAX_PACKET_VER 26 struct s_packet_db { short len; @@ -430,7 +430,7 @@ int clif_guild_memberlogin_notice(struct guild *g,int idx,int flag); int clif_guild_invite(struct map_session_data *sd,struct guild *g); int clif_guild_inviteack(struct map_session_data *sd,int flag); int clif_guild_leave(struct map_session_data *sd,const char *name,const char *mes); -int clif_guild_expulsion(struct map_session_data *sd,const char *name,const char *mes,int account_id); +void clif_guild_expulsion(struct map_session_data* sd, const char* name, const char* mes, int account_id); int clif_guild_positionchanged(struct guild *g,int idx); int clif_guild_memberpositionchanged(struct guild *g,int idx); int clif_guild_emblem(struct map_session_data *sd,struct guild *g); diff --git a/src/map/duel.c b/src/map/duel.c new file mode 100644 index 0000000000..7621b92bed --- /dev/null +++ b/src/map/duel.c @@ -0,0 +1,189 @@ +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#include "../common/cbasetypes.h" + +#include "atcommand.h" // msg_txt +#include "clif.h" +#include "duel.h" +#include "pc.h" + +#include +#include +#include +#include + +struct duel duel_list[MAX_DUEL]; +int duel_count = 0; + +/*========================================== + * Duel organizing functions [LuzZza] + *------------------------------------------*/ +void duel_savetime(struct map_session_data* sd) +{ + time_t timer; + struct tm *t; + + time(&timer); + t = localtime(&timer); + + pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min); + return; +} + +int duel_checktime(struct map_session_data* sd) +{ + int diff; + time_t timer; + struct tm *t; + + time(&timer); + t = localtime(&timer); + + diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME"); + + return !(diff >= 0 && diff < battle_config.duel_time_interval); +} +static int duel_showinfo_sub(struct map_session_data* sd, va_list va) +{ + struct map_session_data *ssd = va_arg(va, struct map_session_data*); + int *p = va_arg(va, int*); + char output[256]; + + if (sd->duel_group != ssd->duel_group) return 0; + + sprintf(output, " %d. %s", ++(*p), sd->status.name); + clif_disp_onlyself(ssd, output, strlen(output)); + return 1; +} + +int duel_showinfo(const unsigned int did, struct map_session_data* sd) +{ + int p=0; + char output[256]; + + if(duel_list[did].max_players_limit > 0) + sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --" + did, duel_count, + duel_list[did].members_count, + duel_list[did].members_count + duel_list[did].invites_count, + duel_list[did].max_players_limit); + else + sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --" + did, duel_count, + duel_list[did].members_count, + duel_list[did].members_count + duel_list[did].invites_count); + + clif_disp_onlyself(sd, output, strlen(output)); + map_foreachpc(duel_showinfo_sub, sd, &p); + return 0; +} + +int duel_create(struct map_session_data* sd, const unsigned int maxpl) +{ + int i=1; + char output[256]; + + while(duel_list[i].members_count > 0 && i < MAX_DUEL) i++; + if(i == MAX_DUEL) return 0; + + duel_count++; + sd->duel_group = i; + duel_list[i].members_count++; + duel_list[i].invites_count = 0; + duel_list[i].max_players_limit = maxpl; + + strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --" + clif_disp_onlyself(sd, output, strlen(output)); + + clif_map_property(sd, MAPPROPERTY_FREEPVPZONE); + //clif_misceffect2(&sd->bl, 159); + return i; +} + +int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd) +{ + char output[256]; + + // " -- Player %s invites %s to duel --" + sprintf(output, msg_txt(373), sd->status.name, target_sd->status.name); + clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS); + + target_sd->duel_invite = did; + duel_list[did].invites_count++; + + // "Blue -- Player %s invites you to PVP duel (@accept/@reject) --" + sprintf(output, msg_txt(374), sd->status.name); + clif_broadcast((struct block_list *)target_sd, output, strlen(output)+1, 0x10, SELF); + return 0; +} + +static int duel_leave_sub(struct map_session_data* sd, va_list va) +{ + int did = va_arg(va, int); + if (sd->duel_invite == did) + sd->duel_invite = 0; + return 0; +} + +int duel_leave(const unsigned int did, struct map_session_data* sd) +{ + char output[256]; + + // " <- Player %s has left duel --" + sprintf(output, msg_txt(375), sd->status.name); + clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS); + + duel_list[did].members_count--; + + if(duel_list[did].members_count == 0) { + map_foreachpc(duel_leave_sub, did); + duel_count--; + } + + sd->duel_group = 0; + duel_savetime(sd); + clif_map_property(sd, MAPPROPERTY_NOTHING); + return 0; +} + +int duel_accept(const unsigned int did, struct map_session_data* sd) +{ + char output[256]; + + duel_list[did].members_count++; + sd->duel_group = sd->duel_invite; + duel_list[did].invites_count--; + sd->duel_invite = 0; + + // " -> Player %s has accepted duel --" + sprintf(output, msg_txt(376), sd->status.name); + clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS); + + clif_map_property(sd, MAPPROPERTY_FREEPVPZONE); + //clif_misceffect2(&sd->bl, 159); + return 0; +} + +int duel_reject(const unsigned int did, struct map_session_data* sd) +{ + char output[256]; + + // " -- Player %s has rejected duel --" + sprintf(output, msg_txt(377), sd->status.name); + clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS); + + duel_list[did].invites_count--; + sd->duel_invite = 0; + return 0; +} + +void do_final_duel(void) +{ +} + +int do_init_duel(void) +{ + memset(&duel_list[0], 0, sizeof(duel_list)); + return 0; +} diff --git a/src/map/duel.h b/src/map/duel.h new file mode 100644 index 0000000000..674d0e12f6 --- /dev/null +++ b/src/map/duel.h @@ -0,0 +1,29 @@ +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#ifndef _DUEL_H_ +#define _DUEL_H_ + +struct duel { + int members_count; + int invites_count; + int max_players_limit; +}; + +#define MAX_DUEL 1024 +extern struct duel duel_list[MAX_DUEL]; +extern int duel_count; + +//Duel functions // [LuzZza] +int duel_create(struct map_session_data* sd, const unsigned int maxpl); +int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd); +int duel_accept(const unsigned int did, struct map_session_data* sd); +int duel_reject(const unsigned int did, struct map_session_data* sd); +int duel_leave(const unsigned int did, struct map_session_data* sd); +int duel_showinfo(const unsigned int did, struct map_session_data* sd); +int duel_checktime(struct map_session_data* sd); + +int do_init_duel(void); +void do_final_duel(void); + +#endif /* _DUEL_H_ */ diff --git a/src/map/guild.c b/src/map/guild.c index e56b346ec2..c80b124efe 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -36,7 +36,7 @@ static DBMap* guild_infoevent_db; // int guild_id -> struct eventlist* static DBMap* guild_castleinfoevent_db; // int castle_id_index -> struct eventlist* struct eventlist { - char name[50]; + char name[EVENT_NAME_LENGTH]; struct eventlist *next; }; @@ -325,7 +325,7 @@ int guild_send_xy_timer_sub(DBKey key,void *data,va_list ap) for(i=0;imax_member;i++){ //struct map_session_data* sd = g->member[i].sd; struct map_session_data* sd = map_charid2sd(g->member[i].char_id); // temporary crashfix - if( sd != NULL && (sd->guild_x != sd->bl.x || sd->guild_y != sd->bl.y) && !sd->state.bg_id ) + if( sd != NULL && (sd->guild_x != sd->bl.x || sd->guild_y != sd->bl.y) && !sd->bg_id ) { clif_guild_xy(sd); sd->guild_x = sd->bl.x; @@ -1545,7 +1545,7 @@ int guild_broken(int guild_id,int flag) struct guild_castle *gc=NULL; struct map_session_data *sd; int i; - char name[50]; + char name[EVENT_NAME_LENGTH]; if(flag!=0 || g==NULL) return 0; @@ -1604,7 +1604,7 @@ int guild_gm_changed(int guild_id, int account_id, int char_id) { struct guild *g; struct guild_member gm; - int pos; + int pos, i; g=guild_search(guild_id); @@ -1638,7 +1638,18 @@ int guild_gm_changed(int guild_id, int account_id, int char_id) g->member[0].sd->state.gmaster_flag = g; //Block his skills for 5 minutes to prevent abuse. guild_block_skill(g->member[0].sd, 300000); - } + } + + // announce the change to all guild members + for( i = 0; i < g->max_member; i++ ) + { + if( g->member[i].sd && g->member[i].sd->fd ) + { + clif_guild_basicinfo(g->member[i].sd); + clif_guild_memberlist(g->member[i].sd); + } + } + return 1; } diff --git a/src/map/instance.c b/src/map/instance.c index 6fa3a2c0a5..e9ff2b4091 100644 --- a/src/map/instance.c +++ b/src/map/instance.c @@ -31,22 +31,21 @@ struct s_instance instance[MAX_INSTANCE]; /*-------------------------------------- * name : instance name * Return value could be - * -4 = already exists | -3 = no free instances | -2 = missing parameter | -1 = invalid type + * -4 = already exists | -3 = no free instances | -2 = party not found | -1 = invalid type * On success return instance_id *--------------------------------------*/ int instance_create(int party_id, const char *name) { int i; - struct party_data *p = NULL; + struct party_data* p; - if( !party_id || !name ) + if( ( p = party_search(party_id) ) == NULL ) { - ShowError("map_instance_create: missing parameter.\n"); + ShowError("instance_create: party %d not found for instance '%s'.\n", party_id, name); return -2; } - p = party_search(party_id); - if( !p || p->instance_id ) + if( p->instance_id ) return -4; // Party already instancing // Searching a Free Instance @@ -54,7 +53,7 @@ int instance_create(int party_id, const char *name) ARR_FIND(1, MAX_INSTANCE, i, instance[i].state == INSTANCE_FREE); if( i == MAX_INSTANCE ) { - ShowError("map_instance_create: no free instances, consider increasing MAX_INSTANCE.\n"); + ShowError("instance_create: no free instances, consider increasing MAX_INSTANCE.\n"); return -3; } diff --git a/src/map/intif.c b/src/map/intif.c index 875baa0367..1b69c0837f 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -1465,7 +1465,7 @@ int intif_parse_Mail_inboxreceived(int fd) if (flag) clif_Mail_refreshinbox(sd); - else + else if( battle_config.mail_show_status && ( battle_config.mail_show_status == 1 || sd->mail.inbox.unread ) ) { char output[128]; sprintf(output, msg_txt(510), sd->mail.inbox.unchecked, sd->mail.inbox.unread + sd->mail.inbox.unchecked); diff --git a/src/map/map.c b/src/map/map.c index 9f9c936080..c086b73c0c 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -17,6 +17,7 @@ #include "path.h" #include "chrif.h" #include "clif.h" +#include "duel.h" #include "intif.h" #include "npc.h" #include "pc.h" @@ -1508,7 +1509,7 @@ void map_addiddb(struct block_list *bl) TBL_MOB* md = (TBL_MOB*)bl; idb_put(mobid_db,bl->id,bl); - if( md->boss ) + if( md->state.boss ) idb_put(bossid_db, bl->id, bl); } @@ -1658,8 +1659,30 @@ struct mob_data * map_id2md(int id) struct npc_data * map_id2nd(int id) {// just a id2bl lookup because there's no npc_db - if (id <= 0) return NULL; - return (struct npc_data*)map_id2bl(id); + struct block_list* bl = map_id2bl(id); + + return BL_CAST(BL_NPC, bl); +} + +struct homun_data* map_id2hd(int id) +{ + struct block_list* bl = map_id2bl(id); + + return BL_CAST(BL_HOM, bl); +} + +struct mercenary_data* map_id2mc(int id) +{ + struct block_list* bl = map_id2bl(id); + + return BL_CAST(BL_MER, bl); +} + +struct chat_data* map_id2cd(int id) +{ + struct block_list* bl = map_id2bl(id); + + return BL_CAST(BL_CHAT, bl); } /// Returns the nick of the target charid or NULL if unknown (requests the nick to the char server). @@ -2704,7 +2727,7 @@ int map_readfromcache(struct map_data *m, char *buffer, char *decode_buffer) } // TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo] - decode_zip(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len); + uncompress(decode_buffer, &size, p+sizeof(struct map_cache_map_info), info->len); CREATE(m->cell, struct mapcell, size); @@ -3438,6 +3461,7 @@ void do_final(void) do_final_status(); do_final_unit(); do_final_battleground(); + do_final_duel(); map_db->destroy(map_db, map_db_final); @@ -3673,6 +3697,7 @@ int do_init(int argc, char *argv[]) do_init_npc(); do_init_unit(); do_init_battleground(); + do_init_duel(); npc_event_do_oninit(); // npcのOnInitイベント?行 diff --git a/src/map/map.h b/src/map/map.h index 8c817387f5..d572cec4c7 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -203,6 +203,8 @@ enum { #define CHATROOM_PASS_SIZE (8 + 1) //Max allowed chat text length #define CHAT_SIZE_MAX (255 + 1) +//24 for npc name + 24 for label + 2 for a "::" and 1 for EOS +#define EVENT_NAME_LENGTH ( NAME_LENGTH * 2 + 3 ) #define DEFAULT_AUTOSAVE_INTERVAL 5*60*1000 @@ -301,18 +303,18 @@ struct block_list { // Expanded to specify all mob-related spawn data by [Skotlex] struct spawn_data { short class_; //Class, used because a mob can change it's class - unsigned boss : 1; unsigned short m,x,y; //Spawn information (map, point, spawn-area around point) signed short xs,ys; unsigned short num; //Number of mobs using this structure unsigned short active; //Number of mobs that are already spawned (for mob_remove_damaged: no) unsigned int delay1,delay2; //Min delay before respawning after spawn/death struct { - unsigned size :2; //Holds if mob has to be tiny/large - unsigned ai :2; //Holds if mob is special ai. - unsigned dynamic :1; //Whether this data is indexed by a map's dynamic mob list + unsigned int size :2; //Holds if mob has to be tiny/large + unsigned int ai :2; //Holds if mob is special ai. + unsigned int dynamic :1; //Whether this data is indexed by a map's dynamic mob list + unsigned int boss : 1; } state; - char name[NAME_LENGTH],eventname[50]; //Name/event + char name[NAME_LENGTH],eventname[EVENT_NAME_LENGTH]; //Name/event }; @@ -398,7 +400,10 @@ enum _look { LOOK_HAIR_COLOR, LOOK_CLOTHES_COLOR, LOOK_SHIELD, - LOOK_SHOES + LOOK_SHOES, + LOOK_BODY, + LOOK_FLOOR, + LOOK_ROBE, }; // used by map_setcell() @@ -625,6 +630,9 @@ struct map_session_data* map_charid2sd(int charid); struct map_session_data * map_id2sd(int id); struct mob_data * map_id2md(int id); struct npc_data * map_id2nd(int id); +struct homun_data* map_id2hd(int id); +struct mercenary_data* map_id2mc(int id); +struct chat_data* map_id2cd(int id); struct block_list * map_id2bl(int id); #define map_id2index(id) map[(id)].index diff --git a/src/map/mob.c b/src/map/mob.c index 1626f49a0a..4c8fa685aa 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -160,7 +160,8 @@ struct view_data * mob_get_viewdata(int class_) *------------------------------------------*/ int mob_parse_dataset(struct spawn_data *data) { - int i; + size_t len; + //FIXME: This implementation is not stable, npc scripts will stop working once MAX_MOB_DB changes value! [Skotlex] if(data->class_ > 2*MAX_MOB_DB){ // large/tiny mobs [Valaris] data->state.size=2; @@ -173,36 +174,33 @@ int mob_parse_dataset(struct spawn_data *data) if ((!mobdb_checkid(data->class_) && !mob_is_clone(data->class_)) || !data->num) return 0; - //better safe than sorry, current md->npc_event has a size of 50 - if ((i=strlen(data->eventname)) >= 50) - return 0; + if( npc_event_isspecial(data->eventname) ) + {//Portable monster big/small implementation. [Skotlex] + int i = atoi(data->eventname); - if (data->eventname[0]) - { - if(i <= 2) - { //Portable monster big/small implementation. [Skotlex] - i = atoi(data->eventname); - if (i) { - if (i&2) - data->state.size=1; - else if (i&4) - data->state.size=2; - if (i&8) - data->state.ai=1; - data->eventname[0] = '\0'; //Clear event as it is not used. - } - } else { - if (data->eventname[i-1] == '"') - data->eventname[i-1] = '\0'; //Remove trailing quote. - if (data->eventname[0] == '"') //Strip leading quotes - memmove(data->eventname, data->eventname+1, i-1); + if( i ) + { + if( i&2 ) + data->state.size = 1; + else if( i&4 ) + data->state.size = 2; + if( i&8 ) + data->state.ai = 1; } + data->eventname[0] = '\0'; //Clear event as it is not used. + } + else if( ( len = strlen(data->eventname) ) > 0 ) + { + if( data->eventname[len-1] == '"' ) + data->eventname[len-1] = '\0'; //Remove trailing quote. + if( data->eventname[0] == '"' ) //Strip leading quotes + memmove(data->eventname, data->eventname+1, len-1); } if(strcmp(data->name,"--en--")==0) - strncpy(data->name,mob_db(data->class_)->name,NAME_LENGTH-1); + safestrncpy(data->name, mob_db(data->class_)->name, sizeof(data->name)); else if(strcmp(data->name,"--ja--")==0) - strncpy(data->name,mob_db(data->class_)->jname,NAME_LENGTH-1); + safestrncpy(data->name, mob_db(data->class_)->jname, sizeof(data->name)); return 1; } @@ -218,7 +216,7 @@ struct mob_data* mob_spawn_dataset(struct spawn_data *data) md->bl.x = data->x; md->bl.y = data->y; md->class_ = data->class_; - md->boss = data->boss; + md->state.boss = data->state.boss; md->db = mob_db(md->class_); memcpy(md->name, data->name, NAME_LENGTH); if (data->state.ai) @@ -667,7 +665,7 @@ int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobnam /*========================================== * Summoning BattleGround [Zephyrus] *------------------------------------------*/ -int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int bg_id) +int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id) { struct mob_data *md = NULL; struct spawn_data data; @@ -704,7 +702,7 @@ int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int md = mob_spawn_dataset(&data); mob_spawn(md); - md->state.bg_id = bg_id; // BG Team ID + md->bg_id = bg_id; // BG Team ID return md->bl.id; } diff --git a/src/map/mob.h b/src/map/mob.h index ce896646cb..605439f125 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -113,42 +113,42 @@ struct mob_data { struct mob_db *db; //For quick data access (saves doing mob_db(md->class_) all the time) [Skotlex] char name[NAME_LENGTH]; struct { - unsigned size : 2; //Small/Big monsters. - unsigned ai : 2; //Special ai for summoned monsters. + unsigned int size : 2; //Small/Big monsters. + unsigned int ai : 2; //Special ai for summoned monsters. //0: Normal mob. //1: Standard summon, attacks mobs. //2: Alchemist Marine Sphere //3: Alchemist Summon Flora } special_state; //Special mob information that does not needs to be zero'ed on mob respawn. struct { + unsigned int aggressive : 1; //Signals whether the mob AI is in aggressive mode or reactive mode. [Skotlex] + unsigned int steal_coin_flag : 1; + unsigned int soul_change_flag : 1; // Celest + unsigned int alchemist: 1; + unsigned int spotted: 1; + unsigned int npc_killmonster: 1; //for new killmonster behavior + unsigned int rebirth: 1; // NPC_Rebirth used + unsigned int boss : 1; enum MobSkillState skillstate; - unsigned aggressive : 1; //Signals whether the mob AI is in aggressive mode or reactive mode. [Skotlex] unsigned char steal_flag; //number of steal tries (to prevent steal exploit on mobs with few items) [Lupus] - unsigned steal_coin_flag : 1; - unsigned soul_change_flag : 1; // Celest - unsigned alchemist: 1; - unsigned spotted: 1; unsigned char attacked_count; //For rude attacked. int provoke_flag; // Celest - unsigned npc_killmonster: 1; //for new killmonster behavior - unsigned rebirth: 1; // NPC_Rebirth used - unsigned int bg_id; // BattleGround System } state; struct guardian_data* guardian_data; struct { int id; unsigned int dmg; - unsigned flag : 2; //0: Normal. 1: Homunc exp. 2: Pet exp + unsigned int flag : 2; //0: Normal. 1: Homunc exp. 2: Pet exp } dmglog[DAMAGELOG_SIZE]; struct spawn_data *spawn; //Spawn data. int spawn_timer; //Required for Convex Mirror struct item *lootitem; short class_; - unsigned boss : 1; unsigned int tdmg; //Stores total damage given to the mob, for exp calculations. [Skotlex] int level; int target_id,attacked_id; int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs) + unsigned int bg_id; // BattleGround System unsigned int next_walktime,last_thinktime,last_linktime,last_pcneartime; short move_fail_count; @@ -160,7 +160,7 @@ struct mob_data { short skillidx; unsigned int skilldelay[MAX_MOBSKILL]; - char npc_event[50]; + char npc_event[EVENT_NAME_LENGTH]; }; @@ -230,7 +230,7 @@ int mob_once_spawn_area(struct map_session_data* sd,int m,int x0,int y0,int x1,i bool mob_ksprotected (struct block_list *src, struct block_list *target); int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian, bool has_index); // Spawning Guardians [Valaris] -int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int bg_id); +int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id); int mob_guardian_guildchange(struct block_list *bl,va_list ap); //Change Guardian's ownership. [Skotlex] int mob_randomwalk(struct mob_data *md,unsigned int tick); diff --git a/src/map/npc.c b/src/map/npc.c index 95331ae5b1..d070b68860 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -105,7 +105,7 @@ struct view_data* npc_get_viewdata(int class_) int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd) { - char name[NAME_LENGTH*2+3]; + char name[EVENT_NAME_LENGTH]; if( nd->touching_id ) return 0; // Attached a player already. Can't trigger on anyone else. @@ -119,7 +119,7 @@ int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd) int npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd) { - char name[NAME_LENGTH*2+3]; + char name[EVENT_NAME_LENGTH]; if( sd->areanpc_id == nd->bl.id ) return 0; @@ -245,7 +245,7 @@ int npc_event_export(char* lname, void* data, va_list ap) if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) { struct event_data *ev; - char buf[NAME_LENGTH*2+3]; + char buf[EVENT_NAME_LENGTH]; char* p = strchr(lname, ':'); // エクスポートされる ev = (struct event_data *) aMalloc(sizeof(struct event_data)); @@ -345,6 +345,14 @@ int npc_event_doall_id(const char* name, int rid) } +/// Checks whether or not the event name is used as transport for +/// special flags. +bool npc_event_isspecial(const char* eventname) +{ + return (bool)( eventname && ISDIGIT(eventname[0]) && !strstr(eventname, "::") ); +} + + /*========================================== * 時計イベント実行 *------------------------------------------*/ @@ -636,7 +644,7 @@ void npc_timerevent_quit(struct map_session_data* sd) // Execute OnTimerQuit if( nd && nd->bl.type == BL_NPC ) { - char buf[NAME_LENGTH*2+3]; + char buf[EVENT_NAME_LENGTH]; struct event_data *ev; snprintf(buf, ARRAYLENGTH(buf), "%s::OnTimerQuit", nd->exname); @@ -813,7 +821,7 @@ int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap) sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys || pc_ishiding(sd) || leavemap ) { - char name[NAME_LENGTH*2+3]; + char name[EVENT_NAME_LENGTH]; nd->touching_id = sd->touching_id = 0; snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name); @@ -894,7 +902,7 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y) int npc_touch_areanpc2(struct mob_data *md) { int i, m = md->bl.m, x = md->bl.x, y = md->bl.y, id; - char eventname[NAME_LENGTH*2+3]; + char eventname[EVENT_NAME_LENGTH]; struct event_data* ev; int xs, ys; @@ -1144,7 +1152,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) //npc_buylist for script-controlled shops. static int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd) { - char npc_ev[NAME_LENGTH*2+3]; + char npc_ev[EVENT_NAME_LENGTH]; int i; int key_nameid = 0; int key_amount = 0; @@ -1379,7 +1387,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) /// npc_selllist for script-controlled shops static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd) { - char npc_ev[NAME_LENGTH*2+3]; + char npc_ev[EVENT_NAME_LENGTH]; int i, idx; int key_nameid = 0; int key_amount = 0; @@ -2211,7 +2219,7 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n')) { struct event_data* ev; - char buf[NAME_LENGTH*2+3]; // 24 for npc name + 24 for label + 2 for a "::" and 1 for EOS + char buf[EVENT_NAME_LENGTH]; snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd->exname, lname); // generate the data and insert it @@ -2399,7 +2407,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n')) { struct event_data* ev; - char buf[NAME_LENGTH*2+3]; // 24 for npc name + 24 for label + 2 for a "::" and 1 for EOS + char buf[EVENT_NAME_LENGTH]; snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd->exname, lname); // generate the data and insert it @@ -2697,7 +2705,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c memset(&mob, 0, sizeof(struct spawn_data)); - mob.boss = !strcmpi(w2,"boss_monster"); + mob.state.boss = !strcmpi(w2,"boss_monster"); // w1=,,,, // w4=,,,, diff --git a/src/map/npc.h b/src/map/npc.h index 6f705a09cc..6e7c7cbeb6 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -134,6 +134,7 @@ int npc_do_ontimer(int npc_id, int option); int npc_event_do(const char* name); int npc_event_doall(const char* name); int npc_event_doall_id(const char* name, int rid); +bool npc_event_isspecial(const char* eventname); int npc_timerevent_start(struct npc_data* nd, int rid); int npc_timerevent_stop(struct npc_data* nd); diff --git a/src/map/pc.c b/src/map/pc.c index 7ee8bec904..f55a77b6a4 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -18,6 +18,7 @@ #include "chrif.h" #include "clif.h" #include "date.h" // is_day_of_*() +#include "duel.h" #include "intif.h" #include "itemdb.h" #include "log.h" @@ -63,9 +64,6 @@ static unsigned short equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARM #define MOTD_LINE_SIZE 128 static char motd_text[MOTD_LINE_SIZE][CHAT_SIZE_MAX]; // Message of the day buffer [Valaris] -struct duel duel_list[MAX_DUEL]; -int duel_count = 0; - //Links related info to the sd->hate_mob[]/sd->feel_map[] entries const struct sg_data sg_info[MAX_PC_FEELHATE] = { { SG_SUN_ANGER, SG_SUN_BLESS, SG_SUN_COMFORT, "PC_FEEL_SUN", "PC_HATE_MOB_SUN", is_day_of_sun }, @@ -3271,13 +3269,37 @@ int pc_payzeny(struct map_session_data *sd,int zeny) void pc_paycash(struct map_session_data *sd, int price, int points) { char output[128]; - int cash = price - points; + int cash; nullpo_retv(sd); - pc_setaccountreg(sd,"#CASHPOINTS",sd->cashPoints - cash); - pc_setaccountreg(sd,"#KAFRAPOINTS",sd->kafraPoints - points); - sprintf(output, "Used %d kafra points and %d cash points. %d kafra and %d cash points remaining.", points, cash, sd->kafraPoints, sd->cashPoints); - clif_disp_onlyself(sd, output, strlen(output)); + if( price < 0 || points < 0 ) + { + ShowError("pc_paycash: Paying negative points (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id); + return; + } + + if( points > price ) + { + ShowWarning("pc_paycash: More kafra points provided than needed (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id); + points = price; + } + + cash = price-points; + + if( sd->cashPoints < cash || sd->kafraPoints < points ) + { + ShowError("pc_paycash: Not enough points (cash=%d, kafra=%d) to cover the price (cash=%d, kafra=%d) (account_id=%d, char_id=%d).\n", sd->cashPoints, sd->kafraPoints, cash, points, sd->status.account_id, sd->status.char_id); + return; + } + + pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash); + pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints-points); + + if( battle_config.cashshop_show_points ) + { + sprintf(output, msg_txt(504), points, cash, sd->kafraPoints, sd->cashPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } } void pc_getcash(struct map_session_data *sd, int cash, int points) @@ -3287,18 +3309,44 @@ void pc_getcash(struct map_session_data *sd, int cash, int points) if( cash > 0 ) { - pc_setaccountreg(sd,"#CASHPOINTS",sd->cashPoints + cash); + if( cash > MAX_ZENY-sd->cashPoints ) + { + ShowWarning("pc_getcash: Cash point overflow (cash=%d, have cash=%d, account_id=%d, char_id=%d).\n", cash, sd->cashPoints, sd->status.account_id, sd->status.char_id); + cash = MAX_ZENY-sd->cashPoints; + } - sprintf(output, "Gained %d cash points. Total %d points", cash, sd->cashPoints); - clif_disp_onlyself(sd, output, strlen(output)); + pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints+cash); + + if( battle_config.cashshop_show_points ) + { + sprintf(output, msg_txt(505), cash, sd->cashPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } + } + else if( cash < 0 ) + { + ShowError("pc_getcash: Obtaining negative cash points (cash=%d, account_id=%d, char_id=%d).\n", cash, sd->status.account_id, sd->status.char_id); } if( points > 0 ) { - pc_setaccountreg(sd,"#KAFRAPOINTS",sd->kafraPoints + points); + if( points > MAX_ZENY-sd->kafraPoints ) + { + ShowWarning("pc_getcash: Kafra point overflow (points=%d, have points=%d, account_id=%d, char_id=%d).\n", points, sd->kafraPoints, sd->status.account_id, sd->status.char_id); + points = MAX_ZENY-sd->kafraPoints; + } - sprintf(output, "Gained %d kafra points. Total %d points", points, sd->kafraPoints); - clif_disp_onlyself(sd, output, strlen(output)); + pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints+points); + + if( battle_config.cashshop_show_points ) + { + sprintf(output, msg_txt(506), points, sd->kafraPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } + } + else if( points < 0 ) + { + ShowError("pc_getcash: Obtaining negative kafra points (points=%d, account_id=%d, char_id=%d).\n", points, sd->status.account_id, sd->status.char_id); } } @@ -4386,6 +4434,7 @@ int pc_checkallowskill(struct map_session_data *sd) SC_SPEARQUICKEN, SC_ADRENALINE, SC_ADRENALINE2, + SC_DANCING, SC_GATLINGFEVER }; const enum sc_type scs_list[] = { @@ -4703,7 +4752,7 @@ int pc_mapid2jobid(unsigned short class_, int sex) /*==================================================== * This function return the name of the job (by [Yor]) *----------------------------------------------------*/ -char* job_name(int class_) +const char* job_name(int class_) { switch (class_) { case JOB_NOVICE: @@ -5809,7 +5858,7 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype) { if( !pc_isdead(sd) ) return; // not applicable - if( sd->state.bg_id && bg_member_respawn(sd) ) + if( sd->bg_id && bg_member_respawn(sd) ) return; // member revived by battleground pc_setstand(sd); @@ -5900,10 +5949,10 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1); pc_setparam(sd, SP_KILLERRID, src?src->id:0); - if( sd->state.bg_id ) + if( sd->bg_id ) { struct battleground_data *bg; - if( (bg = bg_team_search(sd->state.bg_id)) != NULL && bg->die_event[0] ) + if( (bg = bg_team_search(sd->bg_id)) != NULL && bg->die_event[0] ) npc_event(sd, bg->die_event, 0); } npc_script_event(sd,NPCE_DIE); @@ -6147,9 +6196,9 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0); return 1|8; } - else if( sd->state.bg_id ) + else if( sd->bg_id ) { - struct battleground_data *bg = bg_team_search(sd->state.bg_id); + struct battleground_data *bg = bg_team_search(sd->bg_id); if( bg && bg->mapindex > 0 ) { // Respawn by BG add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0); @@ -6627,6 +6676,7 @@ int pc_equiplookall(struct map_session_data *sd) clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); + clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe); return 0; } @@ -6683,6 +6733,9 @@ int pc_changelook(struct map_session_data *sd,int type,int val) break; case LOOK_SHOES: break; + case LOOK_ROBE: + sd->status.robe = val; + break; } clif_changelook(&sd->bl,type,val); return 0; @@ -7413,6 +7466,11 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) } if(pos & EQP_SHOES) clif_changelook(&sd->bl,LOOK_SHOES,0); + if( pos&EQP_GARMENT ) + { + sd->status.robe = id ? id->look : 0; + clif_changelook(&sd->bl, LOOK_ROBE, sd->status.robe); + } pc_checkallowskill(sd); //Check if status changes should be halted. @@ -7483,7 +7541,6 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) sd->status.weapon = sd->weapontype2; pc_calcweapontype(sd); clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); //When unequipping, stop dancing. [Skotlex] } if(sd->status.inventory[n].equip & EQP_HAND_L) { sd->status.shield = sd->weapontype2 = 0; @@ -7504,6 +7561,11 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) } if(sd->status.inventory[n].equip & EQP_SHOES) clif_changelook(&sd->bl,LOOK_SHOES,0); + if( sd->status.inventory[n].equip&EQP_GARMENT ) + { + sd->status.robe = 0; + clif_changelook(&sd->bl, LOOK_ROBE, 0); + } clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1); @@ -7963,168 +8025,6 @@ void pc_setstand(struct map_session_data *sd){ sd->state.dead_sit = sd->vd.dead_sit = 0; } -/*========================================== - * Duel organizing functions [LuzZza] - *------------------------------------------*/ -void duel_savetime(struct map_session_data* sd) -{ - time_t timer; - struct tm *t; - - time(&timer); - t = localtime(&timer); - - pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min); - return; -} - -int duel_checktime(struct map_session_data* sd) -{ - int diff; - time_t timer; - struct tm *t; - - time(&timer); - t = localtime(&timer); - - diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME"); - - return !(diff >= 0 && diff < battle_config.duel_time_interval); -} -static int duel_showinfo_sub(struct map_session_data* sd, va_list va) -{ - struct map_session_data *ssd = va_arg(va, struct map_session_data*); - int *p = va_arg(va, int*); - char output[256]; - - if (sd->duel_group != ssd->duel_group) return 0; - - sprintf(output, " %d. %s", ++(*p), sd->status.name); - clif_disp_onlyself(ssd, output, strlen(output)); - return 1; -} - -int duel_showinfo(const unsigned int did, struct map_session_data* sd) -{ - int p=0; - char output[256]; - - if(duel_list[did].max_players_limit > 0) - sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --" - did, duel_count, - duel_list[did].members_count, - duel_list[did].members_count + duel_list[did].invites_count, - duel_list[did].max_players_limit); - else - sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --" - did, duel_count, - duel_list[did].members_count, - duel_list[did].members_count + duel_list[did].invites_count); - - clif_disp_onlyself(sd, output, strlen(output)); - map_foreachpc(duel_showinfo_sub, sd, &p); - return 0; -} - -int duel_create(struct map_session_data* sd, const unsigned int maxpl) -{ - int i=1; - char output[256]; - - while(duel_list[i].members_count > 0 && i < MAX_DUEL) i++; - if(i == MAX_DUEL) return 0; - - duel_count++; - sd->duel_group = i; - duel_list[i].members_count++; - duel_list[i].invites_count = 0; - duel_list[i].max_players_limit = maxpl; - - strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --" - clif_disp_onlyself(sd, output, strlen(output)); - - clif_map_property(sd, MAPPROPERTY_FREEPVPZONE); - //clif_misceffect2(&sd->bl, 159); - return i; -} - -int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd) -{ - char output[256]; - - // " -- Player %s invites %s to duel --" - sprintf(output, msg_txt(373), sd->status.name, target_sd->status.name); - clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS); - - target_sd->duel_invite = did; - duel_list[did].invites_count++; - - // "Blue -- Player %s invites you to PVP duel (@accept/@reject) --" - sprintf(output, msg_txt(374), sd->status.name); - clif_broadcast((struct block_list *)target_sd, output, strlen(output)+1, 0x10, SELF); - return 0; -} - -static int duel_leave_sub(struct map_session_data* sd, va_list va) -{ - int did = va_arg(va, int); - if (sd->duel_invite == did) - sd->duel_invite = 0; - return 0; -} - -int duel_leave(const unsigned int did, struct map_session_data* sd) -{ - char output[256]; - - // " <- Player %s has left duel --" - sprintf(output, msg_txt(375), sd->status.name); - clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS); - - duel_list[did].members_count--; - - if(duel_list[did].members_count == 0) { - map_foreachpc(duel_leave_sub, did); - duel_count--; - } - - sd->duel_group = 0; - duel_savetime(sd); - clif_map_property(sd, MAPPROPERTY_NOTHING); - return 0; -} - -int duel_accept(const unsigned int did, struct map_session_data* sd) -{ - char output[256]; - - duel_list[did].members_count++; - sd->duel_group = sd->duel_invite; - duel_list[did].invites_count--; - sd->duel_invite = 0; - - // " -> Player %s has accepted duel --" - sprintf(output, msg_txt(376), sd->status.name); - clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS); - - clif_map_property(sd, MAPPROPERTY_FREEPVPZONE); - //clif_misceffect2(&sd->bl, 159); - return 0; -} - -int duel_reject(const unsigned int did, struct map_session_data* sd) -{ - char output[256]; - - // " -- Player %s has rejected duel --" - sprintf(output, msg_txt(377), sd->status.name); - clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS); - - duel_list[did].invites_count--; - sd->duel_invite = 0; - return 0; -} - int pc_split_str(char *str,char **val,int num) { int i; @@ -8486,8 +8386,6 @@ int do_init_pc(void) pc_readdb(); pc_read_motd(); // Read MOTD [Valaris] - memset(&duel_list[0], 0, sizeof(duel_list)); - add_timer_func_list(pc_invincible_timer, "pc_invincible_timer"); add_timer_func_list(pc_eventtimer, "pc_eventtimer"); add_timer_func_list(pc_inventory_rental_end, "pc_inventory_rental_end"); diff --git a/src/map/pc.h b/src/map/pc.h index 7d86706ca8..b6b6fb8515 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -96,63 +96,61 @@ struct map_session_data { //NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in //status_calc_pc, while special_state is recalculated in each call. [Skotlex] struct { - unsigned active : 1; //Marks active player (not active is logging in/out, or changing map servers) - unsigned menu_or_input : 1;// if a script is waiting for feedback from the player - unsigned dead_sit : 2; - unsigned lr_flag : 2; - unsigned connect_new : 1; - unsigned arrow_atk : 1; - unsigned combo : 2; // 1:Asura, 2:Kick [Inkfish] - unsigned gangsterparadise : 1; - unsigned rest : 1; - unsigned storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex] - unsigned snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used. - unsigned abra_flag : 1; // Abracadabra bugfix by Aru - unsigned autocast : 1; // Autospell flag [Inkfish] - unsigned autotrade : 1; //By Fantik - unsigned reg_dirty : 3; //By Skotlex (marks whether registry variables have been saved or not yet) - unsigned showdelay :1; - unsigned showexp :1; - unsigned showzeny :1; - unsigned mainchat :1; //[LuzZza] - unsigned noask :1; // [LuzZza] - unsigned trading :1; //[Skotlex] is 1 only after a trade has started. - unsigned deal_locked :2; //1: Clicked on OK. 2: Clicked on TRADE - unsigned monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo] - unsigned size :2; // for tiny/large types - unsigned night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex] - unsigned blockedmove :1; - unsigned using_fake_npc :1; - unsigned rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex] - unsigned killer : 1; - unsigned killable : 1; - unsigned doridori : 1; - unsigned ignoreAll : 1; - unsigned debug_remove_map : 1; // temporary state to track double remove_map's [FlavioJS] - unsigned buyingstore : 1; - unsigned lesseffect : 1; - unsigned vending : 1; + unsigned int active : 1; //Marks active player (not active is logging in/out, or changing map servers) + unsigned int menu_or_input : 1;// if a script is waiting for feedback from the player + unsigned int dead_sit : 2; + unsigned int lr_flag : 2; + unsigned int connect_new : 1; + unsigned int arrow_atk : 1; + unsigned int combo : 2; // 1:Asura, 2:Kick [Inkfish] + unsigned int gangsterparadise : 1; + unsigned int rest : 1; + unsigned int storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex] + unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used. + unsigned int abra_flag : 1; // Abracadabra bugfix by Aru + unsigned int autocast : 1; // Autospell flag [Inkfish] + unsigned int autotrade : 1; //By Fantik + unsigned int reg_dirty : 3; //By Skotlex (marks whether registry variables have been saved or not yet) + unsigned int showdelay :1; + unsigned int showexp :1; + unsigned int showzeny :1; + unsigned int mainchat :1; //[LuzZza] + unsigned int noask :1; // [LuzZza] + unsigned int trading :1; //[Skotlex] is 1 only after a trade has started. + unsigned int deal_locked :2; //1: Clicked on OK. 2: Clicked on TRADE + unsigned int monster_ignore :1; // for monsters to ignore a character [Valaris] [zzo] + unsigned int size :2; // for tiny/large types + unsigned int night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex] + unsigned int blockedmove :1; + unsigned int using_fake_npc :1; + unsigned int rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex] + unsigned int killer : 1; + unsigned int killable : 1; + unsigned int doridori : 1; + unsigned int ignoreAll : 1; + unsigned int debug_remove_map : 1; // temporary state to track double remove_map's [FlavioJS] + unsigned int buyingstore : 1; + unsigned int lesseffect : 1; + unsigned int vending : 1; + unsigned int noks : 3; // [Zeph Kill Steal Protection] + unsigned int changemap : 1; + short pmap; // Previous map on Map Change unsigned short autoloot; unsigned short autolootid; // [Zephyrus] - unsigned noks : 3; // [Zeph Kill Steal Protection] - bool changemap; - short pmap; // Previous map on Map Change - struct guild *gmaster_flag; - unsigned int bg_id; - unsigned short user_font; unsigned short autobonus; //flag to indicate if an autobonus is activated. [Inkfish] + struct guild *gmaster_flag; } state; struct { unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; - unsigned restart_full_recover : 1; - unsigned no_castcancel : 1; - unsigned no_castcancel2 : 1; - unsigned no_sizefix : 1; - unsigned no_gemstone : 1; - unsigned intravision : 1; // Maya Purple Card effect [DracoRPG] - unsigned perfect_hiding : 1; // [Valaris] - unsigned no_knockback : 1; - unsigned bonus_coma : 1; + unsigned int restart_full_recover : 1; + unsigned int no_castcancel : 1; + unsigned int no_castcancel2 : 1; + unsigned int no_sizefix : 1; + unsigned int no_gemstone : 1; + unsigned int intravision : 1; // Maya Purple Card effect [DracoRPG] + unsigned int perfect_hiding : 1; // [Valaris] + unsigned int no_knockback : 1; + unsigned int bonus_coma : 1; } special_state; int login_id1, login_id2; unsigned short class_; //This is the internal job ID used by the map server to simplify comparisons/queries/etc. [Skotlex] @@ -380,7 +378,7 @@ struct map_session_data { unsigned short pvp_rank, pvp_lastusers; unsigned short pvp_won, pvp_lost; - char eventqueue[MAX_EVENTQUEUE][NAME_LENGTH*2+3]; + char eventqueue[MAX_EVENTQUEUE][EVENT_NAME_LENGTH]; int eventtimer[MAX_EVENTTIMER]; unsigned short eventcount; // [celest] @@ -420,6 +418,13 @@ struct map_session_data { const char* debug_file; int debug_line; const char* debug_func; + + unsigned int bg_id; + unsigned short user_font; + + // temporary debugging of bug #3504 + const char* delunit_prevfile; + int delunit_prevline; }; //Update this max as necessary. 55 is the value needed for Super Baby currently @@ -493,6 +498,13 @@ enum equip_pos { #define EQP_HELM (EQP_HEAD_LOW|EQP_HEAD_MID|EQP_HEAD_TOP) #define EQP_ACC (EQP_ACC_L|EQP_ACC_R) +/// Equip positions that use a visible sprite +#if PACKETVER < 20110111 + #define EQP_VISIBLE EQP_HELM +#else + #define EQP_VISIBLE (EQP_HELM|EQP_GARMENT) +#endif + //Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index //where the arrows are equipped) enum equip_index { @@ -510,16 +522,6 @@ enum equip_index { EQI_MAX }; -struct duel { - int members_count; - int invites_count; - int max_players_limit; -}; - -#define MAX_DUEL 1024 -extern struct duel duel_list[MAX_DUEL]; -extern int duel_count; - #define pc_setdead(sd) ( (sd)->state.dead_sit = (sd)->vd.dead_sit = 1 ) #define pc_setsit(sd) ( (sd)->state.dead_sit = (sd)->vd.dead_sit = 2 ) #define pc_isdead(sd) ( (sd)->state.dead_sit == 1 ) @@ -731,7 +733,7 @@ int pc_candrop(struct map_session_data *sd,struct item *item); int pc_jobid2mapid(unsigned short b_class); // Skotlex int pc_mapid2jobid(unsigned short class_, int sex); // Skotlex -char * job_name(int class_); +const char * job_name(int class_); struct skill_tree_entry { short id; @@ -784,15 +786,6 @@ void pc_inventory_rentals(struct map_session_data *sd); int pc_inventory_rental_clear(struct map_session_data *sd); void pc_inventory_rental_add(struct map_session_data *sd, int seconds); -//Duel functions // [LuzZza] -int duel_create(struct map_session_data* sd, const unsigned int maxpl); -int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd); -int duel_accept(const unsigned int did, struct map_session_data* sd); -int duel_reject(const unsigned int did, struct map_session_data* sd); -int duel_leave(const unsigned int did, struct map_session_data* sd); -int duel_showinfo(const unsigned int did, struct map_session_data* sd); -int duel_checktime(struct map_session_data* sd); - int pc_read_motd(void); // [Valaris] int pc_disguise(struct map_session_data *sd, int class_); diff --git a/src/map/quest.c b/src/map/quest.c index 3e43fcda64..4960d8a938 100644 --- a/src/map/quest.c +++ b/src/map/quest.c @@ -279,17 +279,13 @@ int quest_check(TBL_PC * sd, int quest_id, quest_check_type type) return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0); case HUNTING: { - int j = sd->quest_index[i]; - - if( sd->quest_log[i].count[0] < quest_db[j].count[0] || sd->quest_log[i].count[1] < quest_db[j].count[1] || sd->quest_log[i].count[2] < quest_db[j].count[2] ) - { - if( sd->quest_log[i].time < (unsigned int)time(NULL) ) - return 1; - - return 0; - } - - return 2; + int j; + ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]); + if( j == MAX_QUEST_OBJECTIVES ) + return 2; + if( sd->quest_log[i].time < (unsigned int)time(NULL) ) + return 1; + return 0; } default: ShowError("quest_check_quest: Unknown parameter %d",type); @@ -334,7 +330,7 @@ int quest_read_db(void) continue; else { - ShowError("quest_read_db: insufficient columes in line %s\n", line); + ShowError("quest_read_db: insufficient columns in line %s\n", line); continue; } } diff --git a/src/map/script.c b/src/map/script.c index 4e874b5f02..bf0b4f652c 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -577,9 +577,17 @@ static void disp_error_message2(const char *mes,const char *pos,int report) /// Checks event parameter validity static void check_event(struct script_state *st, const char *evt) { - if( evt != NULL && *evt != '\0' && !stristr(evt,"::On") ){ - ShowError("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n",evt); - script_reportsrc(st); + if( evt && evt[0] && !stristr(evt, "::On") ) + { + if( npc_event_isspecial(evt) ) + { + ; // portable small/large monsters or other attributes + } + else + { + ShowWarning("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n", evt); + script_reportsrc(st); + } } } @@ -4780,7 +4788,7 @@ BUILDIN_FUNC(jobchange) BUILDIN_FUNC(jobname) { int class_=script_getnum(st,2); - script_pushconststr(st,job_name(class_)); + script_pushconststr(st, (char*)job_name(class_)); return 0; } @@ -6316,7 +6324,7 @@ BUILDIN_FUNC(getcharid) case 1: script_pushint(st,sd->status.party_id); break; case 2: script_pushint(st,sd->status.guild_id); break; case 3: script_pushint(st,sd->status.account_id); break; - case 4: script_pushint(st,sd->state.bg_id); break; + case 4: script_pushint(st,sd->bg_id); break; default: ShowError("buildin_getcharid: invalid parameter (%d).\n", num); script_pushint(st,0); @@ -8179,8 +8187,8 @@ BUILDIN_FUNC(cmdothernpc) // Added by RoVeRT { const char* npc = script_getstr(st,2); const char* command = script_getstr(st,3); - char event[51]; - snprintf(event, 51, "%s::OnCommand%s", npc, command); + char event[EVENT_NAME_LENGTH]; + snprintf(event, sizeof(event), "%s::OnCommand%s", npc, command); check_event(st, event); npc_event_do(event); return 0; @@ -12737,6 +12745,13 @@ BUILDIN_FUNC(query_sql) BUILDIN_FUNC(query_logsql) { #ifndef TXT_ONLY + if( !log_config.sql_logs ) + {// logmysql_handle == NULL + ShowWarning("buildin_query_logsql: SQL logs are disabled, query '%s' will not be executed.\n", script_getstr(st,2)); + script_pushint(st,-1); + return 1; + } + return buildin_query_sql_sub(st, logmysql_handle); #else //for TXT version, we always return -1 @@ -14239,7 +14254,7 @@ BUILDIN_FUNC(bg_monster_set_team) if( (mbl = map_id2bl(id)) == NULL || mbl->type != BL_MOB ) return 0; md = (TBL_MOB *)mbl; - md->state.bg_id = bg_id; + md->bg_id = bg_id; mob_stop_attack(md); mob_stop_walking(md, 0); @@ -14252,7 +14267,7 @@ BUILDIN_FUNC(bg_monster_set_team) BUILDIN_FUNC(bg_leave) { struct map_session_data *sd = script_rid2sd(st); - if( sd == NULL || !sd->state.bg_id ) + if( sd == NULL || !sd->bg_id ) return 0; bg_team_leave(sd,0); @@ -14360,11 +14375,11 @@ BUILDIN_FUNC(instance_create) } else if( res < 0 ) { - char *err; + const char *err; switch(res) { case -3: err = "No free instances"; break; - case -2: err = "Missing parameter"; break; + case -2: err = "Invalid party ID"; break; case -1: err = "Invalid type"; break; default: err = "Unknown"; break; } @@ -14658,10 +14673,10 @@ BUILDIN_FUNC(setfont) if( sd == NULL ) return 0; - if( sd->state.user_font != font ) - sd->state.user_font = font; + if( sd->user_font != font ) + sd->user_font = font; else - sd->state.user_font = 0; + sd->user_font = 0; clif_font(sd); return 0; diff --git a/src/map/status.c b/src/map/status.c index e4f3337539..e68ebd2915 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -6429,7 +6429,7 @@ int status_change_clear(struct block_list* bl, int type) /*========================================== * ステータス異常終了 *------------------------------------------*/ -int status_change_end(struct block_list* bl, enum sc_type type, int tid) +int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line) { struct map_session_data *sd; struct status_change *sc; @@ -6588,10 +6588,27 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid) break; case SC_DANCING: { + const char* prevfile = ""; + int prevline = 0; struct map_session_data *dsd; struct status_change_entry *dsc; struct skill_unit_group *group; + if( sd ) + { + if( sd->delunit_prevfile ) + {// initially this is NULL, when a character logs in + prevfile = sd->delunit_prevfile; + prevline = sd->delunit_prevline; + } + else + { + prevfile = ""; + } + sd->delunit_prevfile = file; + sd->delunit_prevline = line; + } + if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4))) {// end status on partner as well dsc = dsd->sc.data[SC_DANCING]; @@ -6608,10 +6625,12 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid) if( group == NULL ) { - ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d). Please report this! (#3504)\n", + ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n", sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid, sd ? sd->status.char_id : 0, - mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y); + mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y, + prevfile, prevline, + file, line); } sce->val2 = 0; diff --git a/src/map/status.h b/src/map/status.h index 718fd2e880..45eaa5c8d0 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1276,7 +1276,8 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti #define sc_start4(bl, type, rate, val1, val2, val3, val4, tick) status_change_start(bl,type,100*(rate),val1,val2,val3,val4,tick,0) int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag); -int status_change_end(struct block_list* bl, enum sc_type type, int tid); +int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line); +#define status_change_end(bl,type,tid) status_change_end_(bl,type,tid,__FILE__,__LINE__) int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr data); int status_change_timer(int tid, unsigned int tick, int id, intptr data); int status_change_timer_sub(struct block_list* bl, va_list ap); diff --git a/src/map/unit.c b/src/map/unit.c index da1ce1c149..3cec43f706 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -17,6 +17,7 @@ #include "mercenary.h" #include "skill.h" #include "clif.h" +#include "duel.h" #include "npc.h" #include "guild.h" #include "status.h" @@ -2067,7 +2068,7 @@ int unit_free(struct block_list *bl, clr_type clrtype) guild_send_memberinfoshort(sd,0); pc_cleareventtimer(sd); pc_inventory_rental_clear(sd); - if( sd->state.bg_id ) bg_team_leave(sd,1); + if( sd->bg_id ) bg_team_leave(sd,1); pc_delspiritball(sd,sd->spiritball,1); if( sd->reg ) diff --git a/src/map/unit.h b/src/map/unit.h index fd5a83208b..e349a74661 100644 --- a/src/map/unit.h +++ b/src/map/unit.h @@ -47,9 +47,10 @@ struct unit_data { struct view_data { unsigned short - class_, + class_, weapon, shield, //Or left-hand weapon. + robe, head_top, head_mid, head_bottom, diff --git a/src/tool/mapcache.c b/src/tool/mapcache.c index f782331cad..deec27c4cc 100644 --- a/src/tool/mapcache.c +++ b/src/tool/mapcache.c @@ -171,7 +171,7 @@ void cache_map(char *name, struct map_data *m) len = (unsigned long)m->xs*(unsigned long)m->ys*2; write_buf = (unsigned char *)aMalloc(len); // Compress the cells and get the compressed length - encode_zip(write_buf, &len, m->cells, m->xs*m->ys); + compress(write_buf, &len, m->cells, m->xs*m->ys); // Fill the map header strncpy(info.name, name, MAP_NAME_LENGTH); diff --git a/tools/mob_db.pl b/tools/mob_db.pl index 38f851b739..a5d2878398 100755 --- a/tools/mob_db.pl +++ b/tools/mob_db.pl @@ -22,12 +22,12 @@ CREATE TABLE `mob_db` ( `ATK2` smallint(6) unsigned NOT NULL default '0', `DEF` smallint(6) unsigned NOT NULL default '0', `MDEF` smallint(6) unsigned NOT NULL default '0', - `STR` tinyint(4) unsigned NOT NULL default '0', - `AGI` tinyint(4) unsigned NOT NULL default '0', - `VIT` tinyint(4) unsigned NOT NULL default '0', - `INT` tinyint(4) unsigned NOT NULL default '0', - `DEX` tinyint(4) unsigned NOT NULL default '0', - `LUK` tinyint(4) unsigned NOT NULL default '0', + `STR` smallint(6) unsigned NOT NULL default '0', + `AGI` smallint(6) unsigned NOT NULL default '0', + `VIT` smallint(6) unsigned NOT NULL default '0', + `INT` smallint(6) unsigned NOT NULL default '0', + `DEX` smallint(6) unsigned NOT NULL default '0', + `LUK` smallint(6) unsigned NOT NULL default '0', `Range2` tinyint(4) unsigned NOT NULL default '0', `Range3` tinyint(4) unsigned NOT NULL default '0', `Scale` tinyint(4) unsigned NOT NULL default '0', diff --git a/vcproj-10/map-server_sql.vcxproj b/vcproj-10/map-server_sql.vcxproj index 2a2726cf27..50ef248449 100644 --- a/vcproj-10/map-server_sql.vcxproj +++ b/vcproj-10/map-server_sql.vcxproj @@ -153,6 +153,7 @@ + @@ -204,6 +205,7 @@ + diff --git a/vcproj-10/map-server_txt.vcxproj b/vcproj-10/map-server_txt.vcxproj index 058fd0707c..69d47c689c 100644 --- a/vcproj-10/map-server_txt.vcxproj +++ b/vcproj-10/map-server_txt.vcxproj @@ -132,6 +132,7 @@ + @@ -183,6 +184,7 @@ + diff --git a/vcproj-6/map-server_sql.dsp b/vcproj-6/map-server_sql.dsp index 63f41a4683..a74c642c4e 100644 --- a/vcproj-6/map-server_sql.dsp +++ b/vcproj-6/map-server_sql.dsp @@ -271,6 +271,14 @@ SOURCE=..\src\map\date.h # End Source File # Begin Source File +SOURCE=..\src\map\duel.c +# End Source File +# Begin Source File + +SOURCE=..\src\map\duel.h +# End Source File +# Begin Source File + SOURCE=..\src\map\guild.c # End Source File # Begin Source File diff --git a/vcproj-6/map-server_txt.dsp b/vcproj-6/map-server_txt.dsp index c7805649d6..f5ea544d20 100644 --- a/vcproj-6/map-server_txt.dsp +++ b/vcproj-6/map-server_txt.dsp @@ -231,6 +231,10 @@ SOURCE=..\src\map\date.c # End Source File # Begin Source File +SOURCE=..\src\map\duel.c +# End Source File +# Begin Source File + SOURCE=..\src\map\guild.c # End Source File # Begin Source File @@ -363,6 +367,10 @@ SOURCE=..\src\map\date.h # End Source File # Begin Source File +SOURCE=..\src\map\duel.h +# End Source File +# Begin Source File + SOURCE=..\src\map\guild.h # End Source File # Begin Source File diff --git a/vcproj-7.1/map-server_sql.vcproj b/vcproj-7.1/map-server_sql.vcproj index 15fb2ade2b..e694418eb4 100644 --- a/vcproj-7.1/map-server_sql.vcproj +++ b/vcproj-7.1/map-server_sql.vcproj @@ -196,6 +196,12 @@ + + + + diff --git a/vcproj-7.1/map-server_txt.vcproj b/vcproj-7.1/map-server_txt.vcproj index 3ab9dbf0d4..f40134a445 100644 --- a/vcproj-7.1/map-server_txt.vcproj +++ b/vcproj-7.1/map-server_txt.vcproj @@ -196,6 +196,12 @@ + + + + diff --git a/vcproj-8/map-server_sql.vcproj b/vcproj-8/map-server_sql.vcproj index d09db63961..d664e47f44 100644 --- a/vcproj-8/map-server_sql.vcproj +++ b/vcproj-8/map-server_sql.vcproj @@ -415,6 +415,14 @@ RelativePath="..\src\map\date.h" > + + + + diff --git a/vcproj-8/map-server_txt.vcproj b/vcproj-8/map-server_txt.vcproj index ddd4302225..1f65a6f281 100644 --- a/vcproj-8/map-server_txt.vcproj +++ b/vcproj-8/map-server_txt.vcproj @@ -266,6 +266,14 @@ RelativePath="..\src\map\date.h" > + + + + diff --git a/vcproj-9/map-server_sql.vcproj b/vcproj-9/map-server_sql.vcproj index 3e080b7e87..7990b26202 100644 --- a/vcproj-9/map-server_sql.vcproj +++ b/vcproj-9/map-server_sql.vcproj @@ -414,6 +414,14 @@ RelativePath="..\src\map\date.h" > + + + + diff --git a/vcproj-9/map-server_txt.vcproj b/vcproj-9/map-server_txt.vcproj index 8edd0f4111..bda9e61d9f 100644 --- a/vcproj-9/map-server_txt.vcproj +++ b/vcproj-9/map-server_txt.vcproj @@ -265,6 +265,14 @@ RelativePath="..\src\map\date.h" > + + + +