Bug Fixes

* Fixed Concentration ending when Frenzy is used. (bugreport:8942)
* Fixed Hells Plant hitting Ghost element enemies. (bugreport:8799)
* Forced guild notice changes to save immediately. (bugreport:8961)
* Fixed Cart Tornado damage formula. (bugreport:9065)
* Adjust Amistr's Castling to now switch to any target type. Still needs skill switching support. (bugreport:1784)
* Removed hard coded 1 second skill duration reduction for Spore Explosion.
* Fixed the party window not displaying the correct map name when in an instance. (bugreport:7949)
* Fixed hatching a pet causing client disconnections. (bugreport:9059) (Hercules 533ff4f)
* Updated Kagerou/Oboro skill cast times. (bugreport:9035)
* Removed deprecated negative nameid value for getitem/getitem2.
* Renamed incuvate to incubate throughout source and SQL.
* Added skill ID to the error display for battle_calc_attack to help resolve issues. (bugreport:8876)
* Cleaned and corrected some Sorcerer Elemental skills. (bugreport:9058)
* Cleaned up some more compile warnings.
This commit is contained in:
aleos89 2014-06-27 15:45:35 -04:00
parent b124498263
commit 62a2813adc
31 changed files with 294 additions and 268 deletions

View File

@ -555,7 +555,7 @@ static int __config_read(config_t *config, FILE *stream, const char *filename,
yyscan_t scanner;
struct scan_context scan_ctx;
struct parse_context parse_ctx;
YY_BUFFER_STATE buffer = NULL;
// YY_BUFFER_STATE buffer = NULL;
int r;
/* Reinitialize the config */
@ -587,7 +587,8 @@ static int __config_read(config_t *config, FILE *stream, const char *filename,
if(stream)
libconfig_yyrestart(stream, scanner);
else /* read from string */
buffer = libconfig_yy_scan_string(str, scanner);
// buffer =
libconfig_yy_scan_string(str, scanner);
libconfig_yyset_lineno(1, scanner);
r = libconfig_yyparse(scanner, &parse_ctx, &scan_ctx);

View File

@ -1702,57 +1702,55 @@
//==== Kagerou & Oboro skills ==============
//-- KO_YAMIKUMO
3001,0,0,0,60000,0,0
3001,0,0,0,200000,0,0
//-- KO_JYUMONJIKIRI
3004,0,2500,0,5000,0,0
3004,0,500,0,3000,0,5000
//-- KO_SETSUDAN
3005,0,2000,0,0,0,0
3005,0,0,0,0,0,3000
//-- KO_BAKURETSU
3006,1000:1500:2000:2500:3000,1000,0,100,0,3000
3006,1000:1400:1800:2200:2600,1000,0,100,0,3000
//-- KO_HAPPOKUNAI
3007,0,1000,0,0,0,0
3007,0,500,0,0,0,0
//-- KO_MUCHANAGE
3008,0,0,0,100,0,10000
3008,1000,0,0,100,0,10000
//-- KO_HUUMARANKA
3009,0,3000,0,500,0,0
3009,1000:1200:1400:1600:1800,1000,0,500,0,3000
//-- KO_MAKIBISHI
3010,0,0,0,12000:14000:16000:18000:20000,10000,0
3010,0,0,0,12000:14000:16000:18000:20000,2500:3000:3500:4000:4500,10000
//-- KO_MEIKYOUSISUI
3011,3000,0,0,10000,0,0
3011,3000,0,0,10000,0,10000
//-- KO_ZANZOU
3012,0,0,0,27000:24000:21000:18000:15000,0,0
3012,0,1000,0,27000:24000:21000:18000:15000,0,30000:27000:24000:21000:18000
//-- KO_KYOUGAKU
3013,1000,0,0,12000:14000:16000:18000:20000,0,0
3013,3000:2500:2000:1500:1000,1000,0,12000:14000:16000:18000:20000,0,10000
//-- KO_JYUSATSU
3014,1000,0,0,8000:10000:12000:14000:16000,0,0
3014,3000:2500:2000:1500:1000,1000,0,8000:10000:12000:14000:16000,0,10000
//-- KO_KAHU_ENTEN
3015,500,0,0,300000,0,0
3015,2000,0,0,300000,0,0
//-- KO_HYOUHU_HUBUKI
3016,500,0,0,300000,0,0
3016,2000,0,0,300000,0,0
//-- KO_KAZEHU_SEIRAN
3017,500,0,0,300000,0,0
3017,2000,0,0,300000,0,0
//-- KO_DOHU_KOUKAI
3018,500,0,0,300000,0,0
//-- KO_KAIHOU
3019,1000,0,0,0,0,0
3018,2000,0,0,300000,0,0
//-- KO_ZENKAI
3020,1000,0,0,10000,10000,0
3020,0,1000,0,10000,10000,0
//-- KO_GENWAKU
3021,500,0,0,5000,0,0
3021,3000:2500:2000:1500:1000,1000,0,30000,0,10000
//-- KO_IZAYOI
3022,0,0,0,30000:45000:60000:75000:90000,0,60000
//-- KG_KAGEHUMI
3023,0,0,0,5000,0,5000
3023,0,0,0,5000:6000:7000:8000:9000,0,0
//-- KG_KYOMU
3024,0,0,0,10000:15000:20000:25000:30000,0,0
3024,0,1000,0,10000:15000:20000:25000:30000,0,20000
//-- KG_KAGEMUSYA
3025,0,0,0,60000:90000:120000:15000:180000,0,0
3025,0,1000,0,60000:90000:120000:150000:180000,0,20000
//-- OB_ZANGETSU
3026,0,0,0,60000:75000:90000:105000:120000,0,0
3026,3000:1500:2000:2500:3000,1000,0,60000:75000:90000:105000:120000,0,30000
//-- OB_OBOROGENSOU
3027,0,0,0,10000:15000:20000:25000:30000,0,0
3027,1000,1000,0,10000:15000:20000:25000:30000,0,15000
//-- OB_AKAITSUKI
3029,0,0,0,10000:15000:20000:25000:30000,0,0
3029,3000:1500:2000:2500:3000,1000,0,10000:15000:20000:25000:30000,0,30000
//==========================================
//===== Eclage Skills ======================

View File

@ -1202,7 +1202,7 @@
2487,9,6,2,0,0,0,1,1,no,0,0,0,none,0,0x0, GN_FIRE_EXPANSION_SMOKE_POWDER,Fire Expansion Smoke Powder
2488,9,6,2,0,0,0,1,1,no,0,0,0,none,0,0x0, GN_FIRE_EXPANSION_TEAR_GAS,Fire Expansion Tear Gas
2489,11,8,1,-1,0x28,0,10,1:2:3:4:5:6:7:8:9:10,no,0,0,0,magic,0,0x0, GN_FIRE_EXPANSION_ACID,Fire Expansion Acid
2490,9,6,2,0,0x3,1,5,1,yes,0,0x80,2:3:4:5:6,none,0,0x0, GN_HELLS_PLANT,Hell's Plant
2490,9,6,2,0,0x3,1,5,1,yes,0,0x80,2:3:4:5:6,misc,0,0x0, GN_HELLS_PLANT,Hell's Plant
2491,0,6,1,0,0x90,0,5,1,no,0,0,0,misc,0,0x0, GN_HELLS_PLANT_ATK,Hell's Plant Attack
2492,0,6,4,0,0x3,5:6:6:7:7,5,1,yes,0,0,0,none,0,0x0, GN_MANDRAGORA,Howling of Mandragora
2493,11,6,16,0,0x1,0,1,1,no,0,0,0,none,0,0x0, GN_SLINGITEM,Sling Item

View File

@ -1690,57 +1690,55 @@
//==== Kagerou & Oboro skills ==============
//-- KO_YAMIKUMO
3001,0,0,0,60000,0,0,-1
3001,0,0,0,200000,0,0,-1
//-- KO_JYUMONJIKIRI
3004,0,2500,0,5000,0,0,-1
3004,0,500,0,3000,0,5000,-1
//-- KO_SETSUDAN
3005,0,2000,0,0,0,0,-1
3005,0,0,0,0,0,3000,-1
//-- KO_BAKURETSU
3006,1000:1500:2000:2500:3000,1000,0,100,0,3000,0
3006,1000:1400:1800:2200:2600,1000,0,100,0,3000,0
//-- KO_HAPPOKUNAI
3007,0,1000,0,0,0,0,-1
3007,0,500,0,0,0,0,-1
//-- KO_MUCHANAGE
3008,0,0,0,100,0,10000,-1
3008,1000,0,0,100,0,10000,-1
//-- KO_HUUMARANKA
3009,0,3000,0,500,0,0,-1
3009,1000:1200:1400:1600:1800,1000,0,500,0,3000,-1
//-- KO_MAKIBISHI
3010,0,0,0,12000:14000:16000:18000:20000,10000,0,-1
3010,0,0,0,12000:14000:16000:18000:20000,2500:3000:3500:4000:4500,10000,-1
//-- KO_MEIKYOUSISUI
3011,3000,0,0,10000,0,0,0
3011,3000,0,0,10000,0,10000,0
//-- KO_ZANZOU
3012,0,0,0,27000:24000:21000:18000:15000,0,0,-1
3012,0,1000,0,27000:24000:21000:18000:15000,0,30000:27000:24000:21000:18000,-1
//-- KO_KYOUGAKU
3013,1000,0,0,12000:14000:16000:18000:20000,0,0,0
3013,3000:2500:2000:1500:1000,1000,0,12000:14000:16000:18000:20000,0,10000,0
//-- KO_JYUSATSU
3014,1000,0,0,8000:10000:12000:14000:16000,0,0,0
3014,3000:2500:2000:1500:1000,1000,0,8000:10000:12000:14000:16000,0,10000,0
//-- KO_KAHU_ENTEN
3015,500,0,0,300000,0,0,0
3015,2000,0,0,300000,0,0,0
//-- KO_HYOUHU_HUBUKI
3016,500,0,0,300000,0,0,0
3016,2000,0,0,300000,0,0,0
//-- KO_KAZEHU_SEIRAN
3017,500,0,0,300000,0,0,0
3017,2000,0,0,300000,0,0,0
//-- KO_DOHU_KOUKAI
3018,500,0,0,300000,0,0,0
//-- KO_KAIHOU
3019,1000,0,0,0,0,0,0
3018,2000,0,0,300000,0,0,0
//-- KO_ZENKAI
3020,1000,0,0,10000,10000,0,0
3020,0,1000,0,10000,10000,0,0
//-- KO_GENWAKU
3021,500,0,0,5000,0,0,0
3021,3000:2500:2000:1500:1000,1000,0,30000,0,10000,0
//-- KO_IZAYOI
3022,0,0,0,30000:45000:60000:75000:90000,0,60000,-1
//-- KG_KAGEHUMI
3023,0,0,0,5000,0,5000,-1
3023,0,0,0,5000:6000:7000:8000:9000,0,0,-1
//-- KG_KYOMU
3024,0,0,0,10000:15000:20000:25000:30000,0,0,-1
3024,0,1000,0,10000:15000:20000:25000:30000,0,20000,-1
//-- KG_KAGEMUSYA
3025,0,0,0,60000:90000:120000:150000:180000,0,0,-1
3025,0,1000,0,60000:90000:120000:150000:180000,0,20000,-1
//-- OB_ZANGETSU
3026,0,0,0,60000:75000:90000:105000:120000,0,0,-1
3026,1000:1500:2000:2500:3000,1000,0,60000:75000:90000:105000:120000,0,30000,2000
//-- OB_OBOROGENSOU
3027,0,0,0,10000:15000:20000:25000:30000,0,0,-1
3027,1000,1000,0,10000:15000:20000:25000:30000,0,15000,-1
//-- OB_AKAITSUKI
3029,0,0,0,10000:15000:20000:25000:30000,0,0,-1
3029,1000:1500:2000:2500:3000,1000,0,10000:15000:20000:25000:30000,0,30000,2000
//==========================================
//===== Eclage Skills ======================

View File

@ -1202,7 +1202,7 @@
2487,9,6,2,0,0,0,1,1,no,0,0,0,none,0,0x0, GN_FIRE_EXPANSION_SMOKE_POWDER,Fire Expansion Smoke Powder
2488,9,6,2,0,0,0,1,1,no,0,0,0,none,0,0x0, GN_FIRE_EXPANSION_TEAR_GAS,Fire Expansion Tear Gas
2489,11,8,1,-1,0x28,0,10,1:2:3:4:5:6:7:8:9:10,no,0,0,0,magic,0,0x0, GN_FIRE_EXPANSION_ACID,Fire Expansion Acid
2490,9,6,2,0,0x3,1,5,1,yes,0,0x80,2:3:4:5:6,none,0,0x0, GN_HELLS_PLANT,Hell's Plant
2490,9,6,2,0,0x3,1,5,1,yes,0,0x80,2:3:4:5:6,misc,0,0x0, GN_HELLS_PLANT,Hell's Plant
2491,0,6,1,0,0x90,0,5,1,no,0,0,0,misc,0,0x0, GN_HELLS_PLANT_ATK,Hell's Plant Attack
2492,0,6,4,0,0x3,5:6:6:7:7,5,1,yes,0,0,0,none,0,0x0, GN_MANDRAGORA,Howling of Mandragora
2493,11,6,16,0,0x1,0,1,1,no,0,0,0,none,0,0x0, GN_SLINGITEM,Sling Item

View File

@ -4236,19 +4236,6 @@ referred to by their database ID number found inside 'db/(pre-)re/item_db.txt'.
getitem 502,10 // The person will receive 10 apples
getitem 617,1 // The person will receive 1 Old Violet Box
Giving an item ID of -1 will give a specified number of random items from the
list of those that fall out of Old Blue Box. Unlike in all other cases, these
will be unidentified, if they turn out to be equipment. This is exactly what's
written in the Old Blue Box's item script.
Other negative IDs also correspond to other random item generating item tables:
Giving an item ID of -2 will produce the effects of Old Violet Box.
Giving an item ID of -3 will produce the effects of Old Card Album.
Giving an item ID of -4 will produce the effects of Gift Box.
Giving an item ID of -5 will produce the effects of Worn Out Scroll, which, in
current SVN, drops only Jellopies anyway.
This transaction is logged if the log script generated transactions option is
enabled.
@ -4271,8 +4258,8 @@ quite a few item scripts. For more examples check just about any official script
This command will give an amount of specified items to the invoking character.
If an optional account ID is specified, and the target character is currently
online, items will be created in their inventory instead. If they are not
online, nothing will happen. It works essentially the same as 'getitem' (it even
works for negative ID numbers the same way) but is a lot more flexible.
online, nothing will happen. It works essentially the same as 'getitem' but is
a lot more flexible.
Those parameters that are different from 'getitem' are:

View File

@ -605,7 +605,7 @@ CREATE TABLE IF NOT EXISTS `pet` (
`intimate` smallint(9) unsigned NOT NULL default '0',
`hungry` smallint(9) unsigned NOT NULL default '0',
`rename_flag` tinyint(4) unsigned NOT NULL default '0',
`incuvate` int(11) unsigned NOT NULL default '0',
`incubate` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`pet_id`)
) ENGINE=MyISAM;

View File

@ -0,0 +1 @@
ALTER TABLE `pet` CHANGE `incuvate` `incubate` int(11) unsigned NOT NULL default '0';

View File

@ -1536,7 +1536,7 @@ int char_delete_char_sql(int char_id){
/* delete char's pet */
//Delete the hatched pet if you have one...
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `incuvate` = '0'", schema_config.pet_db, char_id) )
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d' AND `incubate` = '0'", schema_config.pet_db, char_id) )
Sql_ShowDebug(sql_handle);
//Delete all pets that are stored in eggs (inventory + cart)
@ -2266,7 +2266,7 @@ bool char_checkdb(void){
}
//checking pet_db
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`,`class`,`name`,`account_id`,`char_id`,`level`,"
"`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`"
"`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`"
" from `%s`;", schema_config.pet_db) ){
Sql_ShowDebug(sql_handle);
return false;

View File

@ -1725,6 +1725,7 @@ int mapif_parse_GuildNotice(int fd,int guild_id,const char *mes1,const char *mes
memcpy(g->mes1,mes1,MAX_GUILDMES1);
memcpy(g->mes2,mes2,MAX_GUILDMES2);
g->save_flag |= GS_MES; //Change mes of guild
inter_guild_tosql(g, g->save_flag);
return mapif_guild_notice(g);
}

View File

@ -20,7 +20,6 @@ static int mail_fromsql(int char_id, struct mail_data* md)
{
int i, j;
struct mail_message *msg;
struct item *item;
char *data;
StringBuf buf;
@ -45,6 +44,8 @@ static int mail_fromsql(int char_id, struct mail_data* md)
for (i = 0; i < MAIL_MAX_INBOX && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
{
struct item *item;
msg = &md->msg[i];
Sql_GetData(sql_handle, 0, &data, NULL); msg->id = atoi(data);
Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(msg->send_name, data, NAME_LENGTH);

View File

@ -20,7 +20,7 @@ struct s_pet *pet_pt;
//---------------------------------------------------------
int inter_pet_tosql(int pet_id, struct s_pet* p)
{
//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`)
char esc_name[NAME_LENGTH*2+1];// escaped pet name
Sql_EscapeStringLen(sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));
@ -30,10 +30,10 @@ int inter_pet_tosql(int pet_id, struct s_pet* p)
if( pet_id == -1 )
{// New pet.
if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`) "
"(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`) "
"VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
schema_config.pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate) )
p->equip, p->intimate, p->hungry, p->rename_flag, p->incubate) )
{
Sql_ShowDebug(sql_handle);
return 0;
@ -42,9 +42,9 @@ int inter_pet_tosql(int pet_id, struct s_pet* p)
}
else
{// Update pet.
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incuvate`='%d' WHERE `pet_id`='%d'",
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incubate`='%d' WHERE `pet_id`='%d'",
schema_config.pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id,
p->equip, p->intimate, p->hungry, p->rename_flag, p->incuvate, p->pet_id) )
p->equip, p->intimate, p->hungry, p->rename_flag, p->incubate, p->pet_id) )
{
Sql_ShowDebug(sql_handle);
return 0;
@ -66,9 +66,9 @@ int inter_pet_fromsql(int pet_id, struct s_pet* p)
#endif
memset(p, 0, sizeof(struct s_pet));
//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate`)
//`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`)
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incuvate` FROM `%s` WHERE `pet_id`='%d'", schema_config.pet_db, pet_id) )
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate` FROM `%s` WHERE `pet_id`='%d'", schema_config.pet_db, pet_id) )
{
Sql_ShowDebug(sql_handle);
return 0;
@ -87,7 +87,7 @@ int inter_pet_fromsql(int pet_id, struct s_pet* p)
Sql_GetData(sql_handle, 8, &data, NULL); p->intimate = atoi(data);
Sql_GetData(sql_handle, 9, &data, NULL); p->hungry = atoi(data);
Sql_GetData(sql_handle, 10, &data, NULL); p->rename_flag = atoi(data);
Sql_GetData(sql_handle, 11, &data, NULL); p->incuvate = atoi(data);
Sql_GetData(sql_handle, 11, &data, NULL); p->incubate = atoi(data);
Sql_FreeResult(sql_handle);
@ -181,11 +181,11 @@ int mapif_delete_pet_ack(int fd, int flag){
}
int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id,
short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name)
short pet_equip, short intimate, short hungry, char rename_flag, char incubate, char *pet_name)
{
memset(pet_pt, 0, sizeof(struct s_pet));
safestrncpy(pet_pt->name, pet_name, NAME_LENGTH);
if(incuvate == 1)
if(incubate == 1)
pet_pt->account_id = pet_pt->char_id = 0;
else {
pet_pt->account_id = account_id;
@ -198,7 +198,7 @@ int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short
pet_pt->intimate = intimate;
pet_pt->hungry = hungry;
pet_pt->rename_flag = rename_flag;
pet_pt->incuvate = incuvate;
pet_pt->incubate = incubate;
if(pet_pt->hungry < 0)
pet_pt->hungry = 0;
@ -224,7 +224,7 @@ int mapif_load_pet(int fd, int account_id, int char_id, int pet_id){
inter_pet_fromsql(pet_id, pet_pt);
if(pet_pt!=NULL) {
if(pet_pt->incuvate == 1) {
if(pet_pt->incubate == 1) {
pet_pt->account_id = pet_pt->char_id = 0;
mapif_pet_info(fd, account_id, pet_pt);
}

View File

@ -115,8 +115,6 @@ void aFree_(void *p, const char *file, int line, const char *func)
// ShowMessage("%s:%d: in func %s: aFree %p\n",file,line,func,p);
if (p)
FREE(p, file, line, func);
p = NULL;
}

View File

@ -298,7 +298,7 @@ struct s_pet {
short hungry;//pet hungry
char name[NAME_LENGTH];
char rename_flag;
char incuvate;
char incubate;
};
struct s_homunculus { //[orn]

View File

@ -3917,7 +3917,6 @@ ACMD_FUNC(mapinfo) {
/* Skill damage adjustment info [Cydh] */
#ifdef ADJUST_SKILL_DAMAGE
if (map[m_id].flag.skill_damage) {
int j;
clif_displaymessage(fd,msg_txt(sd,1052)); // Skill Damage Adjustments:
sprintf(atcmd_output," > [Map] %d%%, %d%%, %d%%, %d%% | Caster:%d"
,map[m_id].adjust.damage.pc
@ -3927,6 +3926,8 @@ ACMD_FUNC(mapinfo) {
,map[m_id].adjust.damage.caster);
clif_displaymessage(fd, atcmd_output);
if (map[m_id].skill_damage[0].skill_id) {
int j;
clif_displaymessage(fd," > [Map Skill] Name : Player, Monster, Boss Monster, Other | Caster");
for (j = 0; j < MAX_MAP_SKILL_MODIFIER; j++) {
if (map[m_id].skill_damage[j].skill_id) {

View File

@ -391,8 +391,6 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
}
if( tsc->data[SC_THORNSTRAP])
status_change_end(target, SC_THORNSTRAP, INVALID_TIMER);
if( tsc->data[SC_FIRE_CLOAK_OPTION])
DAMAGE_SUBRATE(tsc->data[SC_FIRE_CLOAK_OPTION]->val2)
if( tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER);
if( tsc->data[SC_EARTH_INSIGNIA]) ratio += 150;
@ -787,7 +785,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
}
}
if(sc->data[SC_ZEPHYR] && (flag&(BF_LONG|BF_SHORT)) == (BF_SHORT|BF_LONG)) {
if( sc->data[SC_ZEPHYR] && !(flag&BF_MAGIC && skill_id) && !(skill_get_inf(skill_id)&(INF_GROUND_SKILL|INF_SELF_SKILL)) ) {
d->dmg_lv = ATK_BLOCK;
return 0;
}
@ -2973,8 +2971,10 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
skillratio += 100;
#else
skillratio += 200;
if( sc && sc->data[SC_TRUESIGHT] )
if (sc && sc->data[SC_TRUESIGHT])
skillratio += 2*sc->data[SC_TRUESIGHT]->val1;
if (sc->data[SC_CONCENTRATION])
skillratio += sc->data[SC_CONCENTRATION]->val2;
#endif
if (sc->data[SC_CRUSHSTRIKE] && (!skill_id || skill_id == KN_AUTOCOUNTER)) {
if (sd) { //ATK [{Weapon Level * (Weapon Upgrade Level + 6) * 100} + (Weapon ATK) + (Weapon Weight)]%
@ -3673,9 +3673,13 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
skillratio = (1000 * skill_lv) + (((sd) ? pc_checkskill(sd, WM_LESSON) : skill_get_max(WM_LESSON)) * status_get_int(src));
break;
case GN_CART_TORNADO: { // ATK [( Skill Level x 50 ) + ( Cart Weight / ( 150 - Caster Base STR ))] + ( Cart Remodeling Skill Level x 50 )] %
skillratio = 50 * skill_lv;
if( sd && sd->cart_weight)
skillratio += sd->cart_weight/10 / max((150-status_get_base_status(src)->str),1) + pc_checkskill(sd, GN_REMODELING_CART) * 50;
int strbonus = status_get_base_status(src)->str; // Only use base STR
if(strbonus > 130)
strbonus = 130;
skillratio = 50 * skill_lv;
if(sd && sd->cart_weight)
skillratio += sd->cart_weight / 10 / (150 - strbonus) + pc_checkskill(sd,GN_REMODELING_CART) * 50;
}
break;
case GN_CARTCANNON:
@ -3723,7 +3727,7 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s
skillratio = 50 * skill_lv + ((sd) ? pc_checkskill(sd, SO_STRIKING) * 50 : skill_get_max(SO_STRIKING));
RE_LVL_DMOD(100);
if( sc && sc->data[SC_BLAST_OPTION] )
skillratio += sd ? sd->status.job_level * 5 : 0;
skillratio += (sd ? sd->status.job_level * 5 : 0);
break;
// Physical Elemantal Spirits Attack Skills
case EL_CIRCLE_OF_FIRE:
@ -5624,47 +5628,50 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
skillratio = 60 * skill_lv;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_HEATER_OPTION] )
skillratio += sd ? sd->status.job_level / 2 : 0;
skillratio += (sd ? sd->status.job_level / 2 : 0);
break;
case SO_ELECTRICWALK:
skillratio = 60 * skill_lv;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_BLAST_OPTION] )
skillratio += sd ? sd->status.job_level / 2 : 0;
skillratio += (sd ? sd->status.job_level / 2 : 0);
break;
case SO_EARTHGRAVE:
skillratio = ( 200 * ((sd) ? pc_checkskill(sd, SA_SEISMICWEAPON) : skill_get_max(SA_SEISMICWEAPON)) + sstatus->int_ * skill_lv );
RE_LVL_DMOD(100);
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
skillratio += sd ? sd->status.job_level * 5 : 0;
skillratio += (sd ? sd->status.job_level * 5 : 0);
break;
case SO_DIAMONDDUST:
skillratio = ( 200 * ((sd) ? pc_checkskill(sd, SA_FROSTWEAPON) : skill_get_max(SA_FROSTWEAPON)) + sstatus->int_ * skill_lv );
RE_LVL_DMOD(100);
if( sc && sc->data[SC_COOLER_OPTION] )
skillratio += sd ? sd->status.job_level * 5 : 0;
skillratio += (sd ? sd->status.job_level * 5 : 0);
break;
case SO_POISON_BUSTER:
skillratio += 900 + 300 * skill_lv;
RE_LVL_DMOD(120);
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
skillratio += sd ? sd->status.job_level * 5 : 0;
skillratio += (sd ? sd->status.job_level * 5 : 0);
break;
case SO_PSYCHIC_WAVE:
skillratio = skill_lv * 70 + (sstatus->int_ * 3);
RE_LVL_DMOD(100);
if (sc && (sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] ||
sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION]))
skillratio += 20;
break;
case SO_VARETYR_SPEAR: //MATK [{( Endow Tornado skill level x 50 ) + ( Caster INT x Varetyr Spear Skill level )} x Caster Base Level / 100 ] %
skillratio = status_get_int(src) * skill_lv + ((sd) ? pc_checkskill(sd, SA_LIGHTNINGLOADER) * 50 : skill_get_max(SA_LIGHTNINGLOADER));
RE_LVL_DMOD(100);
if( sc && sc->data[SC_BLAST_OPTION] )
skillratio += sd ? sd->status.job_level * 5 : 0;
skillratio += (sd ? sd->status.job_level * 5 : 0);
break;
case SO_CLOUD_KILL:
skillratio = skill_lv * 40;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
skillratio += sd ? sd->status.job_level : 0;
skillratio += (sd ? sd->status.job_level : 0);
break;
case GN_DEMONIC_FIRE:
if( skill_lv > 20) // Fire expansion Lv.2
@ -5858,14 +5865,23 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
switch(skill_id) {
case MG_LIGHTNINGBOLT:
case MG_THUNDERSTORM:
if(sc->data[SC_GUST_OPTION])
ad.damage += (6 + sstatus->int_ / 4) + max(sstatus->dex - 10, 0) / 30;
break;
case MG_FIREBOLT:
case MG_FIREWALL:
if(sc->data[SC_PYROTECHNIC_OPTION])
ad.damage += (6 + sstatus->int_ / 4) + max(sstatus->dex - 10, 0) / 30;
break;
case MG_COLDBOLT:
case MG_FROSTDIVER:
if(sc->data[SC_AQUAPLAY_OPTION])
ad.damage += (6 + sstatus->int_ / 4) + max(sstatus->dex - 10, 0) / 30;
break;
case WZ_EARTHSPIKE:
case WZ_HEAVENDRIVE:
if(sc->data[SC_GUST_OPTION] || sc->data[SC_PETROLOGY_OPTION] || sc->data[SC_PYROTECHNIC_OPTION] || sc->data[SC_AQUAPLAY_OPTION])
ad.damage += (6 + sstatus->int_/4) + max(sstatus->dex-10,0)/30;
if(sc->data[SC_PETROLOGY_OPTION])
ad.damage += (6 + sstatus->int_ / 4) + max(sstatus->dex - 10, 0) / 30;
break;
}
}
@ -6340,7 +6356,7 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl
case BF_MAGIC: d = battle_calc_magic_attack(bl,target,skill_id,skill_lv,count); break;
case BF_MISC: d = battle_calc_misc_attack(bl,target,skill_id,skill_lv,count); break;
default:
ShowError("battle_calc_attack: unknown attack type! %d\n",attack_type);
ShowError("battle_calc_attack: unknown attack type! %d (skill_id=%d, skill_lv=%d)\n", attack_type, skill_id, skill_lv);
memset(&d,0,sizeof(d));
break;
}
@ -6801,13 +6817,15 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
else
status_change_end(target, SC_DEVOTION, INVALID_TIMER);
} else if( tsc->data[SC_CIRCLE_OF_FIRE_OPTION] && (wd.flag&BF_SHORT) && target->type == BL_PC ) {
}
if( target->type == BL_PC && (wd.flag&BF_SHORT) && tsc->data[SC_CIRCLE_OF_FIRE_OPTION] ) {
struct elemental_data *ed = ((TBL_PC*)target)->ed;
if( ed ) {
clif_skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, 6);
skill_attack(BF_MAGIC,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
skill_attack(BF_WEAPON,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
}
} else if( tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1 ) {
}
if( tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1 ) {
struct block_list *e_bl = map_id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1);
if( e_bl && !status_isdead(e_bl) ) {
clif_damage(e_bl,e_bl,tick,wd.amotion,wd.dmotion,damage,wd.div_,wd.type,wd.damage2);
@ -6815,7 +6833,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
// Just show damage in target.
clif_damage(src, target, tick, wd.amotion, wd.dmotion, damage, wd.div_, wd.type, wd.damage2 );
map_freeblock_unlock();
return ATK_NONE;
return ATK_BLOCK;
}
}
}
@ -6906,20 +6924,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
}
if( sd && sc && (sc->data[SC_TROPIC_OPTION] || sc->data[SC_CHILLY_AIR_OPTION] || sc->data[SC_WILD_STORM_OPTION] || sc->data[SC_UPHEAVAL_OPTION]) )
{ // Autocast one Bolt depending on status change.
int skill_id = 0;
if( sc->data[SC_TROPIC_OPTION] ) skill_id = sc->data[SC_TROPIC_OPTION]->val3;
else if( sc->data[SC_CHILLY_AIR_OPTION] ) skill_id = sc->data[SC_CHILLY_AIR_OPTION]->val3;
else if( sc->data[SC_WILD_STORM_OPTION] ) skill_id = sc->data[SC_WILD_STORM_OPTION]->val2;
else if( sc->data[SC_UPHEAVAL_OPTION] ) skill_id = sc->data[SC_UPHEAVAL_OPTION]->val2;
sd->state.autocast = 1;
if( skill_id && rand()%100 < (sd->status.job_level / 2) )
skill_castend_damage_id(src, target, skill_id, (int)floor(sd->status.job_level / 10), tick, flag);
sd->state.autocast = 0;
}
if (wd.flag & BF_WEAPON && src != target && damage > 0) {
if (battle_config.left_cardfix_to_right)
battle_drain(sd, target, wd.damage, wd.damage, tstatus->race, tstatus->class_);

View File

@ -42,12 +42,13 @@ struct map_session_data* bg_getavailablesd(struct battleground_data *bg)
int bg_team_delete(int bg_id)
{ // Deletes BG Team from db
int i;
struct map_session_data *sd;
struct battleground_data *bg = bg_team_search(bg_id);
if( bg == NULL ) return 0;
for( i = 0; i < MAX_BG_MEMBERS; i++ )
{
struct map_session_data *sd;
if( (sd = bg->members[i].sd) == NULL )
continue;
@ -79,7 +80,6 @@ int bg_team_join(int bg_id, struct map_session_data *sd)
{ // Player joins team
int i;
struct battleground_data *bg = bg_team_search(bg_id);
struct map_session_data *pl_sd;
if( bg == NULL || sd == NULL || sd->bg_id ) return 0;
@ -96,6 +96,8 @@ int bg_team_join(int bg_id, struct map_session_data *sd)
for( i = 0; i < MAX_BG_MEMBERS; i++ )
{
struct map_session_data *pl_sd;
if( (pl_sd = bg->members[i].sd) != NULL && pl_sd != sd )
clif_hpmeter_single(sd->fd, pl_sd->bl.id, pl_sd->battle_status.hp, pl_sd->battle_status.max_hp);
}

View File

@ -1692,18 +1692,7 @@ void clif_changemap(struct map_session_data *sd, short m, int x, int y)
WFIFOHEAD(fd,packet_len(0x91));
WFIFOW(fd,0) = 0x91;
if(map[m].instance_id) { // Instance map check to send client source map name so we don't crash player
struct instance_data *im = &instance_data[map[m].instance_id];
int i;
if(!im) // This shouldn't happen but if it does give them the map we intended to give
mapindex_getmapname_ext(map[m].name, (char*)WFIFOP(fd,2));
for(i = 0; i < MAX_MAP_PER_INSTANCE; i++) // Loop to find the src map we want
if(im->map[i].m == m) {
mapindex_getmapname_ext(map[im->map[i].src_m].name, (char*)WFIFOP(fd,2));
break;
}
} else
mapindex_getmapname_ext(map[m].name, (char*)WFIFOP(fd,2));
mapindex_getmapname_ext(map_mapid2mapname(m), (char*)WFIFOP(fd,2));
WFIFOW(fd,18) = x;
WFIFOW(fd,20) = y;
WFIFOSET(fd,packet_len(0x91));
@ -4475,7 +4464,7 @@ void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_targe
WBUFW(buf,2) = x;
WBUFW(buf,4) = y;
WBUFW(buf,6) = type;
mapindex_getmapname_ext(map[m].name,(char*)WBUFP(buf,8));
mapindex_getmapname_ext(map_mapid2mapname(m),(char*)WBUFP(buf,8));
if( fd )
{
@ -6724,7 +6713,7 @@ void clif_party_member_info(struct party_data *p, struct map_session_data *sd)
WBUFB(buf,14) = (p->party.member[i].online)?0:1;
memcpy(WBUFP(buf,15), p->party.name, NAME_LENGTH);
memcpy(WBUFP(buf,39), sd->status.name, NAME_LENGTH);
mapindex_getmapname_ext(map[sd->bl.m].name, (char*)WBUFP(buf,63));
mapindex_getmapname_ext(map_mapid2mapname(sd->bl.m), (char*)WBUFP(buf,63));
WBUFB(buf,79) = (p->party.item&1)?1:0;
WBUFB(buf,80) = (p->party.item&2)?1:0;
clif_send(buf,packet_len(0x1e9),&sd->bl,PARTY);
@ -12922,11 +12911,9 @@ void clif_parse_CatchPet(int fd, struct map_session_data *sd){
/// Answer to pet incubator egg selection dialog (CZ_SELECT_PETEGG).
/// 01a7 <index>.W
void clif_parse_SelectEgg(int fd, struct map_session_data *sd){
if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_val != -1) {
//Forged packet, disconnect them [Kevin]
clif_authfail_fd(fd, 0);
if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_val != -1)
return;
}
pet_select_egg(sd,RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2);
clif_menuskill_clear(sd);
}
@ -15917,7 +15904,7 @@ void clif_instance_create(struct map_session_data *sd, const char *name, int num
if(!sd) return;
WBUFW(buf,0) = 0x2cb;
safestrncpy((char *)WBUFP(buf,2), name, 62 );
memcpy( WBUFP(buf,2), name, 62 );
WBUFW(buf,63) = num;
if(flag) // A timer has changed or been added
clif_send(buf,packet_len(0x2cb),&sd->bl,PARTY);
@ -15954,7 +15941,7 @@ void clif_instance_status(struct map_session_data *sd, const char *name, unsigne
if(!sd) return; //party_getavailablesd can return NULL
WBUFW(buf,0) = 0x2cd;
safestrncpy((char *)WBUFP(buf,2), name, 62 );
memcpy( WBUFP(buf,2), name, 62 );
WBUFL(buf,63) = limit1;
WBUFL(buf,67) = limit2;
if(flag) // A timer has changed or been added

View File

@ -549,7 +549,6 @@ int instance_reqinfo(struct map_session_data *sd, short instance_id)
{
struct instance_data *im;
struct instance_db *db;
int i;
nullpo_retr(1, sd);
@ -563,6 +562,8 @@ int instance_reqinfo(struct map_session_data *sd, short instance_id)
// Say it's created if instance is not busy
if(im->state == INSTANCE_IDLE) {
int i;
for(i = 0; i < instance_wait.count; i++) {
if(instance_wait.id[i] == instance_id) {
clif_instance_create(sd, db->name, i+1, 0);

View File

@ -59,7 +59,7 @@ int CheckForCharServer(void)
// pet
int intif_create_pet(int account_id,int char_id,short pet_class,short pet_lv,short pet_egg_id,
short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name)
short pet_equip,short intimate,short hungry,char rename_flag,char incubate,char *pet_name)
{
if (CheckForCharServer())
return 0;
@ -74,7 +74,7 @@ int intif_create_pet(int account_id,int char_id,short pet_class,short pet_lv,sho
WFIFOW(inter_fd,18) = intimate;
WFIFOW(inter_fd,20) = hungry;
WFIFOB(inter_fd,22) = rename_flag;
WFIFOB(inter_fd,23) = incuvate;
WFIFOB(inter_fd,23) = incubate;
memcpy(WFIFOP(inter_fd,24),pet_name,NAME_LENGTH);
WFIFOSET(inter_fd,24+NAME_LENGTH);

View File

@ -66,7 +66,7 @@ void intif_itembound_req(int char_id, int aid, int guild_id);
#endif
int intif_create_pet(int account_id, int char_id, short pet_type, short pet_lv, short pet_egg_id,
short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name);
short pet_equip, short intimate, short hungry, char rename_flag, char incubate, char *pet_name);
int intif_request_petdata(int account_id, int char_id, int pet_id);
int intif_save_petdata(int account_id, struct s_pet *p);
int intif_delete_petdata(int pet_id);

View File

@ -2474,6 +2474,29 @@ void map_removemobs(int16 m)
map[m].mob_delete_timer = add_timer(gettick()+battle_config.mob_remove_delay, map_removemobs_timer, m, 0);
}
/*==========================================
* Check for map_name from map_id
*------------------------------------------*/
const char* map_mapid2mapname(int m)
{
if (map[m].instance_id) { // Instance map check
struct instance_data *im = &instance_data[map[m].instance_id];
if (!im) // This shouldn't happen but if it does give them the map we intended to give
return map[m].name;
else {
int i;
for (i = 0; i < MAX_MAP_PER_INSTANCE; i++) { // Loop to find the src map we want
if (im->map[i].m == m)
return map[im->map[i].src_m].name;
}
}
}
return map[m].name;
}
/*==========================================
* Hookup, get map_id from map_name
*------------------------------------------*/

View File

@ -802,6 +802,7 @@ struct block_list * map_id2bl(int id);
bool map_blid_exists( int id );
#define map_id2index(id) map[(id)].index
const char* map_mapid2mapname(int m);
int16 map_mapindex2mapid(unsigned short mapindex);
int16 map_mapname2mapid(const char* name);
int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port);

View File

@ -1711,7 +1711,7 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
{
char npc_ev[EVENT_NAME_LENGTH];
char card_slot[NAME_LENGTH];
int i, j, idx;
int i, j;
int key_nameid = 0;
int key_amount = 0;
int key_refine = 0;
@ -1736,6 +1736,8 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short*
// save list of to be sold items
for( i = 0; i < n; i++ )
{
int idx;
idx = item_list[i*2]-2;
script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->status.inventory[idx].nameid, &key_nameid);

View File

@ -255,7 +255,6 @@ int party_recv_info(struct party* sp, int char_id)
int removed_count = 0;
int added[MAX_PARTY];// member_id in new data
int added_count = 0;
int i;
int member_id;
nullpo_ret(sp);
@ -263,6 +262,8 @@ int party_recv_info(struct party* sp, int char_id)
p = (struct party_data*)idb_get(party_db, sp->party_id);
if( p != NULL )// diff members
{
int i;
for( member_id = 0; member_id < MAX_PARTY; ++member_id )
{
member = &p->party.member[member_id];
@ -537,8 +538,6 @@ int party_removemember(struct map_session_data* sd, int account_id, char* name)
int party_removemember2(struct map_session_data *sd,int char_id,int party_id)
{
struct party_data *p;
if( sd ) {
if( !sd->status.party_id )
return -3;
@ -546,6 +545,8 @@ int party_removemember2(struct map_session_data *sd,int char_id,int party_id)
return 1;
} else {
int i;
struct party_data *p;
if( !(p = party_search(party_id)) )
return -2;

View File

@ -307,7 +307,7 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
clif_additem(sd,0,0,flag);
map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
pd->pet.incuvate = 1;
pd->pet.incubate = 1;
unit_free(&pd->bl,CLR_OUTSIGHT);
status_calc_pc(sd,SCO_NONE);
@ -331,8 +331,8 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *pet)
}
if (sd->status.pet_id != pet->pet_id) {
if (sd->status.pet_id) {
//Wrong pet?? Set incuvate to no and send it back for saving.
pet->incuvate = 1;
//Wrong pet?? Set incubate to no and send it back for saving.
pet->incubate = 1;
intif_save_petdata(sd->status.account_id,pet);
sd->status.pet_id = 0;
return 1;
@ -397,12 +397,12 @@ int pet_birth_process(struct map_session_data *sd, struct s_pet *pet)
Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->master == sd);
if(sd->status.pet_id && pet->incuvate == 1) {
if(sd->status.pet_id && pet->incubate == 1) {
sd->status.pet_id = 0;
return 1;
}
pet->incuvate = 0;
pet->incubate = 0;
pet->account_id = sd->status.account_id;
pet->char_id = sd->status.char_id;
sd->status.pet_id = pet->pet_id;
@ -440,7 +440,7 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag)
sd->status.pet_id = 0;
return 1;
}
if(p->incuvate == 1) {
if(p->incubate == 1) {
int i;
//Delete egg from inventory. [Skotlex]
for (i = 0; i < MAX_INVENTORY; i++) {
@ -610,7 +610,7 @@ int pet_menu(struct map_session_data *sd,int menunum)
return 1;
//You lost the pet already.
if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incuvate)
if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incubate)
return 1;
egg_id = itemdb_exists(sd->pd->petDB->EggID);
@ -808,32 +808,35 @@ static int pet_randomwalk(struct pet_data *pd,unsigned int tick)
Assert((pd->master == 0) || (pd->master->pd == pd));
if(DIFF_TICK(pd->next_walktime,tick) < 0 && unit_can_move(&pd->bl)) {
const int retrycount=20;
int i,x,y,c,d=12-pd->move_fail_count;
if(d<5) d=5;
for(i=0;i<retrycount;i++){
int r=rnd();
x=pd->bl.x+r%(d*2+1)-d;
y=pd->bl.y+r/(d*2+1)%(d*2+1)-d;
if(map_getcell(pd->bl.m,x,y,CELL_CHKPASS) && unit_walktoxy(&pd->bl,x,y,0)){
pd->move_fail_count=0;
const int retrycount = 20;
int i, c, d = 12-pd->move_fail_count;
if(d < 5)
d = 5;
for(i = 0; i < retrycount; i++) {
int r = rnd(), x, y;
x = pd->bl.x+r%(d*2+1)-d;
y = pd->bl.y+r/(d*2+1)%(d*2+1)-d;
if(map_getcell(pd->bl.m,x,y,CELL_CHKPASS) && unit_walktoxy(&pd->bl,x,y,0)) {
pd->move_fail_count = 0;
break;
}
if(i+1>=retrycount){
if(i + 1 >= retrycount) {
pd->move_fail_count++;
if(pd->move_fail_count>1000){
ShowWarning("PET can't move. hold position %d, class = %d\n",pd->bl.id,pd->pet.class_);
pd->move_fail_count=0;
if(pd->move_fail_count > 1000) {
ShowWarning("Pet can't move. Holding position %d, class = %d\n",pd->bl.id,pd->pet.class_);
pd->move_fail_count = 0;
pd->ud.canmove_tick = tick + 60000;
return 0;
}
}
}
for(i=c=0;i<pd->ud.walkpath.path_len;i++){
for(i = c = 0; i < pd->ud.walkpath.path_len; i++) {
if(pd->ud.walkpath.path[i]&1)
c+=pd->status.speed*14/10;
c += pd->status.speed*14/10;
else
c+=pd->status.speed;
c += pd->status.speed;
}
pd->next_walktime = tick+rnd()%3000+3000+c;
@ -1020,7 +1023,6 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
int i;
struct item_drop_list *dlist;
struct item_drop *ditem;
struct item *it;
if(!pd || !pd->loot || !pd->loot->count)
return 0;
dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
@ -1033,6 +1035,8 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
dlist->item = NULL;
for(i=0;i<pd->loot->count;i++) {
struct item *it;
it = &pd->loot->item[i];
if(sd){
unsigned char flag = 0;

View File

@ -6421,11 +6421,13 @@ BUILDIN_FUNC(checkweight2){
*------------------------------------------*/
BUILDIN_FUNC(getitem)
{
int nameid,amount,get_count,i;
int amount,get_count,i;
unsigned short nameid;
struct item it;
TBL_PC *sd;
struct script_data *data;
unsigned char flag = 0;
const char* command = script_getfuncname(st);
data=script_getdata(st,2);
get_val(st,data);
@ -6439,12 +6441,7 @@ BUILDIN_FUNC(getitem)
nameid=item_data->nameid;
} else if( data_isint(data) ) {// <item id>
nameid=conv_num(st,data);
//Violet Box, Blue Box, etc - random item pick
if( nameid < 0 ) {
nameid = -nameid;
flag = 1;
}
if( nameid <= 0 || !itemdb_exists(nameid) ){
if( !itemdb_exists(nameid) ){
ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid);
return 1; //No item created.
}
@ -6459,12 +6456,9 @@ BUILDIN_FUNC(getitem)
memset(&it,0,sizeof(it));
it.nameid=nameid;
if(!flag)
it.identify=1;
else
it.identify=itemdb_isidentified(nameid);
it.identify=itemdb_isidentified(nameid);
if( !strcmp(script_getfuncname(st),"getitembound") ) {
if( !strcmp(command,"getitembound") ) {
char bound = script_getnum(st,4);
if( bound > BOUND_NONE && bound < BOUND_MAX ) {
it.bound = bound;
@ -6512,7 +6506,8 @@ BUILDIN_FUNC(getitem)
*------------------------------------------*/
BUILDIN_FUNC(getitem2)
{
int nameid, amount, get_count, i;
int amount, get_count, i;
unsigned short nameid;
int iden, ref, attr, c1, c2, c3, c4;
char bound = BOUND_NONE;
struct item_data *item_data;
@ -6520,8 +6515,9 @@ BUILDIN_FUNC(getitem2)
unsigned char flag = 0;
TBL_PC *sd;
struct script_data *data;
const char* command = script_getfuncname(st);
if( !strcmp(script_getfuncname(st),"getitembound2") ) {
if( !strcmp(command,"getitembound2") ) {
bound = script_getnum(st,11);
if( bound > BOUND_NONE && bound < BOUND_MAX ) {
if( script_hasdata(st,12) )
@ -6562,11 +6558,6 @@ BUILDIN_FUNC(getitem2)
c3=(short)script_getnum(st,9);
c4=(short)script_getnum(st,10);
if(nameid < 0) { // Invalid nameid
nameid = -nameid;
flag = 1;
}
if(nameid > 0) {
memset(&item_tmp,0,sizeof(item_tmp));
item_data=itemdb_exists(nameid);
@ -6585,10 +6576,7 @@ BUILDIN_FUNC(getitem2)
}
item_tmp.nameid=nameid;
if(!flag)
item_tmp.identify=iden;
else if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR || item_data->type==IT_SHADOWGEAR )
item_tmp.identify=0;
item_tmp.identify=iden;
item_tmp.refine=ref;
item_tmp.attribute=attr;
item_tmp.card[0]=(short)c1;

View File

@ -1456,7 +1456,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
case SO_DIAMONDDUST:
rate = 5 + 5 * skill_lv;
if( sc && sc->data[SC_COOLER_OPTION] )
rate += sd ? sd->status.job_level / 5 : 0;
rate += (sd ? sd->status.job_level / 5 : 0);
sc_start(src,bl, SC_CRYSTALIZE, rate, skill_lv, skill_get_time2(skill_id, skill_lv));
break;
case SO_VARETYR_SPEAR:
@ -5156,7 +5156,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
else {
clif_skill_nodamage(src, bl, skill_id, 0, 1);
skill_addtimerskill(src, gettick() + skill_get_time(skill_id, skill_lv) - 1000, bl->id, 0, 0, skill_id, skill_lv, 0, 0);
skill_addtimerskill(src, gettick() + skill_get_time(skill_id, skill_lv), bl->id, 0, 0, skill_id, skill_lv, 0, 0);
}
break;
@ -8147,14 +8147,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case HAMI_CASTLE: //[orn]
if(rnd()%100 < 20*skill_lv && src != bl)
{
int x,y;
x = src->x;
y = src->y;
if (hd)
skill_blockhomun_start(hd, skill_id, skill_get_time2(skill_id,skill_lv));
if (rnd()%100 < 20 * skill_lv && src != bl) {
int x = src->x, y = src->y;
if (hd)
skill_blockhomun_start(hd,skill_id,skill_get_time2(skill_id,skill_lv));
if (unit_movepos(src,bl->x,bl->y,0,0)) {
clif_skill_nodamage(src,src,skill_id,skill_lv,1); // Homunc
clif_slide(src, bl->x, bl->y);
@ -8162,16 +8159,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (unit_movepos(bl,x,y,0,0)) {
clif_skill_nodamage(bl,bl,skill_id,skill_lv,1); // Master
clif_slide(bl, x, y);
clif_fixpos(src);
clif_fixpos(bl);
}
//TODO: Shouldn't also players and the like switch targets?
map_foreachinrange(skill_chastle_mob_changetarget,src,
AREA_SIZE, BL_MOB, bl, src);
//TODO: Make casted skill also change its target
map_foreachinrange(skill_changetarget,src,AREA_SIZE,BL_CHAR,bl,src);
}
}
// Failed
else if (hd && hd->master)
} else if (hd && hd->master) // Failed
clif_skill_fail(hd->master, skill_id, USESKILL_FAIL_LEVEL, 0);
else if (sd)
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
@ -12422,12 +12415,12 @@ static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, un
break;
case UNT_FIRE_EXPANSION_SMOKE_POWDER:
if( !sce )
if (!sce && battle_check_target(&sg->unit->bl, bl, sg->target_flag) > 0)
sc_start(ss, bl, type, 100, sg->skill_lv, sg->limit);
break;
case UNT_FIRE_EXPANSION_TEAR_GAS:
if( !sce )
if (!sce && battle_check_target(&sg->unit->bl, bl, sg->target_flag) > 0)
if( sc_start4(ss, bl, type, 100, sg->skill_lv, 0, ss->id,0, sg->limit) )
sc_start(ss, bl, SC_TEARGAS_SOB, 100, sg->skill_lv, sg->limit);
break;
@ -13047,10 +13040,13 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_WARMER:
if( bl->type == BL_PC && !battle_check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON ) {
int hp = tstatus->max_hp * sg->skill_lv / 100;
int hp = 0;
struct status_change *ssc = status_get_sc(ss);
if( ssc && ssc->data[SC_HEATER_OPTION] )
hp *= 3 / 100;
hp = tstatus->max_hp * 3 * sg->skill_lv / 100;
else
hp = tstatus->max_hp * sg->skill_lv / 100;
if( tstatus->hp != tstatus->max_hp )
clif_skill_nodamage(&src->bl, bl, AL_HEAL, hp, 0);
if( tsc && tsc->data[SC_AKAITSUKI] && hp )
@ -15092,7 +15088,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
break;
case SO_PSYCHIC_WAVE:
if( sc && (sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] || sc->data[SC_BLAST_OPTION]) )
req.sp += req.sp * 50 / 100;
req.sp += req.sp / 2; // 1.5x SP cost
break;
}
@ -16273,15 +16269,12 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
/*==========================================
*
*------------------------------------------*/
int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap)
int skill_changetarget(struct block_list *bl, va_list ap)
{
struct mob_data* md;
struct unit_data*ud = unit_bl2ud(bl);
struct block_list *from_bl;
struct block_list *to_bl;
md = (struct mob_data*)bl;
from_bl = va_arg(ap,struct block_list *);
to_bl = va_arg(ap,struct block_list *);
struct mob_data *md = (struct mob_data *)bl;
struct unit_data *ud = unit_bl2ud(bl);
struct block_list *from_bl = va_arg(ap,struct block_list *);
struct block_list *to_bl = va_arg(ap,struct block_list *);
if(ud && ud->target == from_bl->id)
ud->target = to_bl->id;
@ -17753,22 +17746,28 @@ int skill_produce_mix (struct map_session_data *sd, uint16 skill_id, unsigned sh
(sd->status.base_level-100) + pc_checkskill(sd, AM_LEARNINGPOTION) + pc_checkskill(sd, CR_FULLPROTECTION)*(4+rnd()%6); // (Caster?s Base Level - 100) + (Potion Research x 5) + (Full Chemical Protection Skill Level) x (Random number between 4 ~ 10)
switch(nameid){// difficulty factor
case ITEMID_HP_INCREASE_POTION_SMALL: case ITEMID_SP_INCREASE_POTION_SMALL:
case ITEMID_HP_INCREASE_POTION_SMALL:
case ITEMID_SP_INCREASE_POTION_SMALL:
case ITEMID_CONCENTRATED_WHITE_POTION_Z:
difficulty += 10;
break;
case ITEMID_BOMB_MUSHROOM_SPORE: case ITEMID_SP_INCREASE_POTION_MEDIUM:
case ITEMID_BOMB_MUSHROOM_SPORE:
case ITEMID_SP_INCREASE_POTION_MEDIUM:
difficulty += 15;
break;
case ITEMID_BANANA_BOMB: case ITEMID_HP_INCREASE_POTION_MEDIUM:
case ITEMID_SP_INCREASE_POTION_LARGE: case ITEMID_VITATA500:
case ITEMID_BANANA_BOMB:
case ITEMID_HP_INCREASE_POTION_MEDIUM:
case ITEMID_SP_INCREASE_POTION_LARGE:
case ITEMID_VITATA500:
difficulty += 20;
break;
case ITEMID_SEED_OF_HORNY_PLANT: case ITEMID_BLOODSUCK_PLANT_SEED:
case ITEMID_SEED_OF_HORNY_PLANT:
case ITEMID_BLOODSUCK_PLANT_SEED:
case ITEMID_CONCENTRATED_CEROMAIN_SOUP:
difficulty += 30;
break;
case ITEMID_HP_INCREASE_POTION_LARGE: case ITEMID_CURE_FREE:
case ITEMID_HP_INCREASE_POTION_LARGE:
case ITEMID_CURE_FREE:
difficulty += 40;
break;
}

View File

@ -429,7 +429,7 @@ bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md);
bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y);
int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap);
int skill_changetarget(struct block_list *bl,va_list ap);
// Item creation
int skill_can_produce_mix( struct map_session_data *sd, unsigned short nameid, int trigger, int qty);

View File

@ -2017,21 +2017,23 @@ int status_check_visibility(struct block_list *src, struct block_list *target)
if ( src->type == BL_NPC) // NPCs don't care for the rest
return 1;
switch (target->type) { // Check for chase-walk/hiding/cloaking opponents.
case BL_PC: {
struct map_session_data *tsd = (TBL_PC*)target;
if (tsc) {
switch (target->type) { // Check for chase-walk/hiding/cloaking opponents.
case BL_PC: {
struct map_session_data *tsd = (TBL_PC*)target;
if (((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_STEALTHFIELD]) && !(status->mode&MD_BOSS) && (tsd->special_state.perfect_hiding || !(status->mode&MD_DETECTOR)))
if (((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_STEALTHFIELD]) && !(status->mode&MD_BOSS) && (tsd->special_state.perfect_hiding || !(status->mode&MD_DETECTOR)))
return 0;
if (tsc->data[SC_CLOAKINGEXCEED] && !(status->mode&MD_BOSS) && ((tsd && tsd->special_state.perfect_hiding) || (status->mode&MD_DETECTOR)))
return 0;
if (tsc->data[SC__FEINTBOMB] && !(status->mode&(MD_BOSS|MD_DETECTOR)))
return 0;
}
break;
default:
if (((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_STEALTHFIELD]) && !(status->mode&(MD_BOSS|MD_DETECTOR)))
return 0;
if (tsc->data[SC_CLOAKINGEXCEED] && !(status->mode&MD_BOSS) && ((tsd &&tsd->special_state.perfect_hiding) || (status->mode&MD_DETECTOR)))
return 0;
if (tsc && tsc->data[SC__FEINTBOMB] && !(status->mode&(MD_BOSS|MD_DETECTOR)))
return 0;
}
break;
default:
if (tsc && ((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_STEALTHFIELD]) && !(status->mode&(MD_BOSS|MD_DETECTOR)))
return 0;
}
}
return 1;
@ -2645,7 +2647,7 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
if(sc->data[SC_PETROLOGY_OPTION])
bonus += sc->data[SC_PETROLOGY_OPTION]->val2;
if(sc->data[SC_POWER_OF_GAIA])
bonus += sc->data[SC_POWER_OF_GAIA]->val2;
bonus += sc->data[SC_POWER_OF_GAIA]->val3;
if(sc->data[SC_CURSED_SOIL_OPTION])
bonus += sc->data[SC_CURSED_SOIL_OPTION]->val2;
if(sc->data[SC_UPHEAVAL_OPTION])
@ -7919,10 +7921,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
// Before overlapping fail, one must check for status cured.
switch (type) {
case SC_ENDURE:
if (val4)
status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
break;
case SC_BLESSING:
// !TODO: Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
// !but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
@ -9567,6 +9565,22 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
case SC_STONE_SHIELD_OPTION:
val2 = 100; // Elemental modifier.
break;
case SC_TROPIC:
case SC_CHILLY_AIR:
case SC_WILD_STORM:
case SC_UPHEAVAL:
val2 += 10;
case SC_HEATER:
case SC_COOLER:
case SC_BLAST:
case SC_CURSED_SOIL:
val2 += 10;
case SC_PYROTECHNIC:
case SC_AQUAPLAY:
case SC_GUST:
case SC_PETROLOGY:
val2 += 5;
val3 += 9000;
case SC_CIRCLE_OF_FIRE:
case SC_FIRE_CLOAK:
case SC_WATER_DROP:
@ -9575,12 +9589,13 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
case SC_WIND_STEP:
case SC_STONE_SHIELD:
case SC_SOLID_SKIN:
val2 = 10;
tick_time = 2000; // [GodLesZ] tick time
val2 += 5;
val3 += 1000;
tick_time = val3; // [GodLesZ] tick time
break;
case SC_WATER_BARRIER:
val2 = 40; // Increasement. Mdef1 ???
val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
val3 = 30; // Reductions. Atk2, Flee1, Matk1 ????
break;
case SC_ZEPHYR:
val2 = 25; // Flee.
@ -9590,10 +9605,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
break;
case SC_ROCK_CRUSHER:
case SC_ROCK_CRUSHER_ATK:
val2 = 33;
break;
case SC_POWER_OF_GAIA:
val2 = 20; //HP rate bonus
val2 = 33; //Def rate bonus/Speed rate reduction
val3 = 20; //HP rate bonus
break;
case SC_TEARGAS:
val2 = status_get_max_hp(bl) * 5 / 100; // Drain 5% HP
@ -11702,7 +11716,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
case SC_ELECTRICSHOCKER:
if( --(sce->val4) >= 0 ) {
status_charge(bl, 0, 5 * sce->val1 * status->max_sp / 100);
// Keep immobilize status even the SP is already running out.
sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
return 0;
}
@ -11915,6 +11928,18 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
case SC_TROPIC:
case SC_CHILLY_AIR:
case SC_WILD_STORM:
case SC_UPHEAVAL:
case SC_HEATER:
case SC_COOLER:
case SC_BLAST:
case SC_CURSED_SOIL:
case SC_PYROTECHNIC:
case SC_AQUAPLAY:
case SC_GUST:
case SC_PETROLOGY:
case SC_CIRCLE_OF_FIRE:
case SC_FIRE_CLOAK:
case SC_WATER_DROP:
@ -11925,12 +11950,14 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
case SC_SOLID_SKIN:
if( !status_charge(bl,0,sce->val2) ) {
struct block_list *s_bl = battle_get_master(bl);
if (bl->type == BL_ELEM)
elemental_change_mode(BL_CAST(BL_ELEM, bl), MAX_ELESKILLTREE);
if( s_bl )
status_change_end(s_bl,type+1,INVALID_TIMER);
status_change_end(bl,type,INVALID_TIMER);
break;
}
sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
sc_timer_next(sce->val3 + tick, status_change_timer, bl->id, data);
return 0;
case SC_TEARGAS:

View File

@ -246,7 +246,6 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
struct item inventory2[MAX_INVENTORY];
struct item_data *data;
int trade_i, i, n;
short amount;
// check zenys value against hackers (Zeny was already checked on time of adding, but you never know when you lost some zeny since then.
if(sd->deal.zeny > sd->status.zeny || (tsd->status.zeny > MAX_ZENY - sd->deal.zeny))
@ -260,6 +259,8 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
// check free slot in both inventory
for(trade_i = 0; trade_i < 10; trade_i++) {
short amount;
amount = sd->deal.item[trade_i].amount;
if (amount) {
n = sd->deal.item[trade_i].index;