* 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
This commit is contained in:
ai4rei 2011-05-15 05:30:25 +00:00
parent ab5c7c3c16
commit 38725ab312
65 changed files with 1037 additions and 640 deletions

View File

@ -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).

View File

@ -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

View File

@ -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

View File

@ -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 ---------------------------

View File

@ -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).

View File

@ -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

View File

@ -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

Binary file not shown.

View File

@ -810,6 +810,16 @@ mal_dun01
1@cash
iz_dun05
evt_mobroom
alde_tt03
dic_dun03
//mjolnir_04_1
//evt_swar_b
//evt_swar_r
//evt_swar_s
//evt_swar_t
1@lhz
lhz_dun04
que_lhz
// Only add maps under this line if they are not standard maps!

View File

@ -2,7 +2,7 @@
//
//MOB_ID,dummy value (info only),STATE,SKILL_ID,SKILL_LV,rate (10000 = 100%),casttime,delay,cancelable,target,condition type,condition value,val1,val2,val3,val4,val5,emotion,chat
//Example
//1001,Poring@TF_POISON,attack,52,3,100,1500,10000,no,target,always,0,,,,,7
//1001,Poring@TF_POISON,attack,52,3,100,1500,10000,no,target,always,0,,,,,7,
//
//rate refers to the chance of the skill being casted when the condition is fulfilled.
//delay is the time in milliseconds that has to be pass before recasting the same skill.

View File

@ -1585,5 +1585,24 @@ packet_ver: 25
0x0842,6,recall2,2
0x0843,6,remove2,2
//2010-11-24aRagexeRE
packet_ver: 26
0x0436,19,wanttoconnection,2:6:10:14:18
0x035f,5,walktoxy,2
0x0360,6,ticksend,2
0x0361,5,changedir,2:4
0x0362,6,takeitem,2
0x0363,6,dropitem,2:4
0x0364,8,movetokafra,2:4
0x0365,8,movefromkafra,2:4
0x0366,10,useskilltopos,2:4:6:8
0x0367,90,useskilltoposinfo,2:4:6:8:10
0x0368,6,getcharnamerequest,2
0x0369,6,solvecharname,2
0x0856,-1
0x0857,-1
0x0858,-1
0x0859,-1
//Add new packets here
//packet_ver: 26
//packet_ver: 27

View File

@ -4,7 +4,7 @@
//= A reference manual for the eAthena scripting language.
//= Commands are sorted depending on their functionality.
//===== Version ===========================================
//= 3.39.20110322
//= 3.42.20110508
//=========================================================
//= 1.0 - First release, filled will as much info as I could
//= remember or figure out, most likely there are errors,
@ -168,6 +168,12 @@
//= Documented optional parameter 'npc name' of 'waitingroom2bg' command.
//= 3.40.20110404
//= Updated description of 'waitingroom' command to include required zeny/lvl. [Kisuka]
//= 3.41.20110427
//= Updated description of 'itemheal' primarily to remove overhead and lies
//= about client effects. [Ai4rei]
//= 3.42.20110508
//= Updated description of all instance commands to reflect actual behavior.
//= [Ai4rei]
//=========================================================
This document is a reference manual for all the scripting commands and functions
@ -3727,15 +3733,10 @@ character and produces no other output whatsoever.
*itemheal <hp>,<sp>;
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 "<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}}};
*announce "<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}};
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 Name>",<Party ID>,<Instance>)
*instance_create("<instance name>",<party id>);
Create an instance using the name "<Instance Name>" for the Party of <Party ID>.
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 "<instance name>" for the Party of <party id>.
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 ID>)
*instance_destroy {<instance id>};
Destroys instance with the ID <Instance ID>.
Destroys instance with the ID <instance 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 ID>,"<Map Name>")
*instance_detachmap(<Instance ID>,"<Map Name>")
*instance_attachmap("<map name>",<instance id>{,<use base name>});
Attach or detach the map "<Map Name>" to the instance with the <Instance ID>.
Attaches the map "<map name>" to the instance specified with <instance id>. 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 ID>);
*instance_detachmap "<map name>"{,<instance id>};
Initiate the instance of <Instance ID>.
Detach the map "<map name>" to the instance with the <instance 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_announce <Instance ID>,"<text>",<flag>{,<color>};
*instance_init <instance id>;
Works like announce, but has the <Instance ID> parameter, where 0 = active instance?
Initializes the instance given by <instance id>. This copies all NPCs from the
source maps to the instanced maps.
---------------------------------------
*instance_attach(<Instance ID>);
*instance_announce <instance id>,"<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}};
Attaches a script to the provided <Instance ID>?
Works like announce, but has the <instance id> 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("<NPC Name>",<Instance ID>)
*instance_attach <instance id>;
Retrieve the unique name given to a copy of an NPC for an instance, the given
"<NPC Name>" that belongs to instance <Instance ID>. Can be used with such commands
as enablenpc and disablenpc, donpcevent, etc.
Attaches the current script to the instance given by <instance id>.
---------------------------------------
*has_instance("<Map Name>")
*instance_npcname("<npc name>"{,<instance id>});
Check if the player has been queued for the <Map Name> instance.
Retrieves the unique name given to a copy of an NPC given by "<npc name>" in an
instance specified <instance 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_id(<?>)
*has_instance("<map name>"{,<instance id>});
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 "<Map Name>",<x>,<y>;
*instance_id({<type>});
Warp all players in the instance to <map name> and given coordinates.
Retrieves the instance id, depending on <type>. 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 <Time1>,<Time2>,<Instance ID>;
*instance_warpall "<map name>",<x>,<y>{,<instance id>};
Lifetime of <Time1> for <Instance ID>, while <Time2> is how long until the
instance times out while inactive.
Warps all players in the instance <instance id> to <map name> 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 <alive timeout>,<idle timeout>{,<instance id>};
Sets the timeout values for an instance given by <instance 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.
Parameter <alive timeout> specifies the total amount of time the instance will
exist. Parameter <idle timeout> specifies how long players have, when they are
outside of the instance, until it is destroyed.
---------------------------------------

View File

@ -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',

View File

@ -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',

View File

@ -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',

View File

@ -0,0 +1 @@
ALTER TABLE `char` MODIFY `weapon` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0';

View File

@ -0,0 +1 @@
ALTER TABLE `char` ADD `robe` SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0' AFTER `head_bottom`;

View File

@ -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;

View File

@ -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);

View File

@ -7,7 +7,6 @@
#include <sys/stat.h>
#include "grfio.h"
#include <zlib.h>
#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);

View File

@ -4,6 +4,8 @@
#ifndef _GRFIO_H_
#define _GRFIO_H_
#include <zlib.h>
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_ */

View File

@ -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)

View File

@ -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.

View File

@ -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;

View File

@ -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)

View File

@ -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.");
}

View File

@ -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);

View File

@ -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, },

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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];
};

View File

@ -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 <len>.W <fontColor>.L <fontType>.W <fontSize>.W <fontAlign>.W <fontY>.W <message>.?B
* S 040C <len>.W <fontColor>.L <fontType>.W <fontSize>.W <fontAlign>.W <fontY>.W <message>.?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;i<MAX_GUILDEXPULSION;i++){
struct guild_expulsion *e=&g->expulsion[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 <length>.W <name>.24B <class>.w <hairstyle>.w <up-viewid>.w <mid-viewid>.w <low-viewid>.w <haircolor>.w <cloth-dye>.w <gender>.1B {equip item}.26B*
* for PACKETVER >= 20100629
* R 002d7 <length>.W <name>.24B <class>.w <hairstyle>.w <bottom-viewid>.w <mid-viewid>.w <up-viewid>.w <haircolor>.w <cloth-dye>.w <gender>.1B {equip item}.28B*
*------------------------------------------*/
/// Sends info about a player's equipped items (ZC_EQUIPWIN_MICROSCOPE)
/// 02d7 <packet len>.W <name>.24B <class>.W <hairstyle>.W <up-viewid>.W <mid-viewid>.W <low-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.26B*
/// 02d7 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (PACKETVER >= 20100629)
/// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (PACKETVER >= 20101124)
/// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <robe>.W <haircolor>.W <cloth-dye>.W <gender>.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 *);

View File

@ -29,7 +29,7 @@ struct party_booking_ad_info;
#include <stdarg.h>
// 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);

189
src/map/duel.c Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
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;
}

29
src/map/duel.h Normal file
View File

@ -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_ */

View File

@ -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;i<g->max_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);
@ -1639,6 +1639,17 @@ int guild_gm_changed(int guild_id, int account_id, int char_id)
//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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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ƒCƒxƒ“ƒg?<3F>s

View File

@ -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

View File

@ -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 )
{
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;
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);
}
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;
}

View File

@ -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);

View File

@ -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=<map name>,<x>,<y>,<xs>,<ys>
// w4=<mob id>,<amount>,<delay1>,<delay2>,<event>

View File

@ -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);

View File

@ -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);
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,19 +3309,45 @@ 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);
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);
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");

View File

@ -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_);

View File

@ -279,18 +279,14 @@ 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] )
{
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;
}
return 2;
}
default:
ShowError("quest_check_quest: Unknown parameter %d",type);
break;
@ -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;
}
}

View File

@ -577,10 +577,18 @@ 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);
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;

View File

@ -6429,7 +6429,7 @@ int status_change_clear(struct block_list* bl, int type)
/*==========================================
* ƒXƒe<EFBFBD>[ƒ^ƒXˆÙ<EFBFBD>í<EFBFBD>I¹
*------------------------------------------*/
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 = "<unknown>";
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 = "<none>";
}
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;

View File

@ -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);

View File

@ -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 )

View File

@ -50,6 +50,7 @@ struct view_data {
class_,
weapon,
shield, //Or left-hand weapon.
robe,
head_top,
head_mid,
head_bottom,

View File

@ -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);

View File

@ -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',

View File

@ -153,6 +153,7 @@
<ClInclude Include="..\src\map\chrif.h" />
<ClInclude Include="..\src\map\clif.h" />
<ClInclude Include="..\src\map\date.h" />
<ClInclude Include="..\src\map\duel.h" />
<ClInclude Include="..\src\map\guild.h" />
<ClInclude Include="..\src\map\intif.h" />
<ClInclude Include="..\src\map\itemdb.h" />
@ -204,6 +205,7 @@
<ClCompile Include="..\src\map\chrif.c" />
<ClCompile Include="..\src\map\clif.c" />
<ClCompile Include="..\src\map\date.c" />
<ClCompile Include="..\src\map\duel.c" />
<ClCompile Include="..\src\map\guild.c" />
<ClCompile Include="..\src\map\intif.c" />
<ClCompile Include="..\src\map\itemdb.c" />

View File

@ -132,6 +132,7 @@
<ClCompile Include="..\src\map\chrif.c" />
<ClCompile Include="..\src\map\clif.c" />
<ClCompile Include="..\src\map\date.c" />
<ClCompile Include="..\src\map\duel.c" />
<ClCompile Include="..\src\map\guild.c" />
<ClCompile Include="..\src\map\homunculus.c" />
<ClCompile Include="..\src\map\instance.c" />
@ -183,6 +184,7 @@
<ClInclude Include="..\src\map\chrif.h" />
<ClInclude Include="..\src\map\clif.h" />
<ClInclude Include="..\src\map\date.h" />
<ClInclude Include="..\src\map\duel.h" />
<ClInclude Include="..\src\map\guild.h" />
<ClInclude Include="..\src\map\homunculus.h" />
<ClInclude Include="..\src\map\instance.h" />

View File

@ -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

View File

@ -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

View File

@ -196,6 +196,12 @@
<File
RelativePath="..\src\map\date.h">
</File>
<File
RelativePath="..\src\map\duel.c">
</File>
<File
RelativePath="..\src\map\duel.h">
</File>
<File
RelativePath="..\src\map\guild.c">
</File>

View File

@ -196,6 +196,12 @@
<File
RelativePath="..\src\map\date.h">
</File>
<File
RelativePath="..\src\map\duel.c">
</File>
<File
RelativePath="..\src\map\duel.h">
</File>
<File
RelativePath="..\src\map\guild.c">
</File>

View File

@ -415,6 +415,14 @@
RelativePath="..\src\map\date.h"
>
</File>
<File
RelativePath="..\src\map\duel.c"
>
</File>
<File
RelativePath="..\src\map\duel.h"
>
</File>
<File
RelativePath="..\src\map\guild.c"
>

View File

@ -266,6 +266,14 @@
RelativePath="..\src\map\date.h"
>
</File>
<File
RelativePath="..\src\map\duel.c"
>
</File>
<File
RelativePath="..\src\map\duel.h"
>
</File>
<File
RelativePath="..\src\map\guild.c"
>

View File

@ -414,6 +414,14 @@
RelativePath="..\src\map\date.h"
>
</File>
<File
RelativePath="..\src\map\duel.c"
>
</File>
<File
RelativePath="..\src\map\duel.h"
>
</File>
<File
RelativePath="..\src\map\guild.c"
>

View File

@ -265,6 +265,14 @@
RelativePath="..\src\map\date.h"
>
</File>
<File
RelativePath="..\src\map\duel.c"
>
</File>
<File
RelativePath="..\src\map\duel.h"
>
</File>
<File
RelativePath="..\src\map\guild.c"
>