From 462b2bebdb5ee182adec88010898a237398e42d6 Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Tue, 1 Jul 2014 16:29:19 +0700 Subject: [PATCH] * Bug Fixes: -- Added itemstack check when init autotrader (bugreport:9077) -- 'getitem' issue, gave unidentified item (bugreport:9075), follow up 62a2813 -- Invalid Def & Mdef reduction of SC_ARMORCHANGE & duration (NPC_STONESKIN & NPC_ANTIMAGIC), should be percentage (bugreport:9076) -- Invalid Effect duration & Reflect chance of SC_MAGICMIRROR (NPC_MAGICMIRROR) -- Wrong usage of script_isstring() for script commands: addspiritball, delspiritball, & countspiritball * Misc: -- Moved mail send progress to mail.c mail_send() from clif.c clif_parse_Mail_send() -- Moved hardcoded flood protection when send a mail to 'mail_delay' in misc.conf Signed-off-by: Cydh Ramdh --- conf/battle/misc.conf | 3 + db/pre-re/item_db.txt | 10 ++-- db/pre-re/skill_cast_db.txt | 6 +- db/re/item_db.txt | 6 +- db/re/skill_cast_db.txt | 6 +- sql-files/item_db.sql | 10 ++-- sql-files/item_db_re.sql | 6 +- src/map/battle.c | 1 + src/map/battle.h | 1 + src/map/clif.c | 46 +-------------- src/map/mail.c | 81 ++++++++++++++++++++++--- src/map/mail.h | 3 +- src/map/script.c | 114 +++++++++++++++++++----------------- src/map/status.c | 14 +++-- src/map/vending.c | 2 +- 15 files changed, 173 insertions(+), 136 deletions(-) diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf index 7cf40629ee..b1f4c7a3a1 100644 --- a/conf/battle/misc.conf +++ b/conf/battle/misc.conf @@ -138,3 +138,6 @@ discount_item_point_shop: 0 // Don't display message "login-serv has been asked to %s the player '%.*s'." (Note 1) disp_serverbank_msg: no + +// Delay to allow user resend new mail (default & minimum is 1000) +mail_delay: 1000 diff --git a/db/pre-re/item_db.txt b/db/pre-re/item_db.txt index b4bd592817..964859bbbe 100644 --- a/db/pre-re/item_db.txt +++ b/db/pre-re/item_db.txt @@ -1089,7 +1089,7 @@ 2119,Improved_Arm_Guard,Advanced Arm Guard,4,40000,,150,,4,,0,0x02000000,7,2,32,,50,1,1,{ bonus bMdef,5; },{},{} 2120,Improved_Arm_Guard_,Advanced Arm Guard,4,40000,,150,,4,,1,0x02000000,7,2,32,,50,1,1,{ bonus bMdef,5; },{},{} 2121,Memorize_Book_,Memory Book,4,20,,1000,,3,,1,0x00810204,7,2,32,,0,1,5,{ bonus bInt,1; bonus bMdef,2; },{},{} -2122,Platinum_Shield,Platinum Shield,4,20,,1200,,5,,0,0xFFFFFFFE,2,2,32,,68,1,4,{ bonus bMdef,5; bonus2 bSubSize,Size_Medium,15; bonus2 bSubSize,Size_Large,15; bonus2 bSubRace,RC_Undead,10; bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",2,150,BF_MAGIC,0; },{},{} +2122,Platinum_Shield,Platinum Shield,4,20,,1200,,5,,0,0xFFFFFFFE,2,2,32,,68,1,4,{ bonus bMdef,5; bonus2 bSubSize,Size_Medium,15; bonus2 bSubSize,Size_Large,15; bonus2 bSubRace,RC_Undead,10; bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",7,150,BF_MAGIC,0; },{},{} 2123,Orleans_Server,Orleans's Server,4,20,,1000,,5,,1,0xFFFFFFFE,2,2,32,,55,1,4,{ bonus bMdef,2; bonus bMagicDamageReturn,5; },{},{} 2124,Thorny_Buckler,Thorny Buckler,4,20,,1000,,5,,1,0xFFFFFFFE,2,2,32,,55,1,2,{ bonus bMdef,2; },{},{} 2125,Strong_Shield,Strong Shield,4,20,,2500,,4,,1,0xFFFFFFFE,2,2,32,,75,1,4,{ bonus bNoKnockback,0; bonus2 bSubEle,Ele_Neutral,-20; bonus2 bSubEle,Ele_Fire,-20; bonus2 bSubEle,Ele_Water,-20; bonus2 bSubEle,Ele_Wind,-20; bonus2 bSubEle,Ele_Earth,-20; bonus2 bSubEle,Ele_Dark,-20; bonus2 bSubEle,Ele_Holy,-20; bonus2 bSubEle,Ele_Ghost,-20; },{},{} @@ -1394,8 +1394,8 @@ 2528,Wool_Scarf,Wool Scarf,4,20,,500,,3,,1,0xFFFFFFFE,2,2,4,,55,1,0,{ bonus bMdef,4; },{},{} 2529,Rider_Insignia,Rider Insignia,4,20,,500,,4,,0,0xFFFFFFFE,2,2,4,,55,1,0,{ bonus bAgi,2; },{},{} 2530,Rider_Insignia_,Rider Insignia,4,20,,500,,4,,1,0xFFFFFFFE,2,2,4,,55,1,0,{ bonus bAgi,2; },{},{} -2531,Ulfhedinn,Ulfhedinn,4,20,,700,,3,,1,0x000654E2,2,2,4,,70,1,0,{ bonus3 bAutoSpellWhenHit,"NPC_STONESKIN",1,20; },{},{} -2532,Mithril_Magic_Cape,Mithril Magic Cape,4,20,,400,,3,,1,0x00098B1C,2,2,4,,70,1,0,{ bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",1,200,BF_MAGIC,0; },{},{} +2531,Ulfhedinn,Ulfhedinn,4,20,,700,,3,,1,0x000654E2,2,2,4,,70,1,0,{ bonus3 bAutoSpellWhenHit,"NPC_STONESKIN",6,20; },{},{} +2532,Mithril_Magic_Cape,Mithril Magic Cape,4,20,,400,,3,,1,0x00098B1C,2,2,4,,70,1,0,{ bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",6,200,BF_MAGIC,0; },{},{} //2533,Freyja_Cape,Freyja Cape,4,0,,200,,10,,0,0xFFFFFFFE,7,2,4,,0,0,0,{ bonus2 bSubRace,RC_DemiHuman,15; bonus2 bSubRace,RC_Player,15; },{},{} 2534,Ruffler,Ruffler,4,20,,0,,10,,0,0xFFFFFFFF,7,2,4,,0,0,0,{ bonus2 bSubEle,Ele_Neutral,17; bonus bFlee,17; },{},{} 2535,Cloak_Of_Survival_C,Cloak Of Survival,4,1,,0,,5,,0,0x00810204,7,2,4,,0,0,0,{ bonus bVit,10; bonus bMdef,10; },{},{} @@ -1415,7 +1415,7 @@ 2549,Krieger_Muffler1,Glorious Muffler,4,20,,0,,0,,0,0xFFFFFFFE,7,2,4,,81,1,0,{ bonus bMaxHPRate,5; bonus2 bSubRace,RC_DemiHuman,5; bonus2 bSubRace,RC_Player,5; },{},{} 2550,Fisher's_Muffler,Fisher's Muffler,4,20,,200,,0,,0,0xFFFFFFFF,7,2,4,,0,1,0,{},{},{} 2551,Rider_Insignia_M,Crest of the Rider,4,20,,500,,4,,1,0xFFFFFFFE,2,2,4,,55,1,0,{ bonus bAgi,2; },{},{} -2552,Mithril_Magic_Cape_M,Mithril Magic Manteau,4,20,,400,,3,,1,0x00098B1C,2,2,4,,70,1,0,{ bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",1,200,BF_MAGIC,0; },{},{} +2552,Mithril_Magic_Cape_M,Mithril Magic Manteau,4,20,,400,,3,,1,0x00098B1C,2,2,4,,70,1,0,{ bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",6,200,BF_MAGIC,0; },{},{} 2553,Dragon_Manteau,Dragon Manteau,4,20,,1000,,5,,1,0xFFFFFFFE,2,2,4,,0,1,0,{ bonus bAgi,1; bonus bMdef,5; },{},{} 2554,Piece_Of_Angent_Skin,Nydhorgg's Shadow Garb,4,20,,400,,5,,1,0xFFFFFFFE,2,2,4,,90,1,0,{ bonus2 bSubEle,Ele_Neutral,7; bonus2 bSubEle,Ele_Water,7; bonus2 bSubEle,Ele_Earth,7; bonus2 bSubEle,Ele_Fire,7; bonus2 bSubEle,Ele_Wind,7; bonus2 bSubEle,Ele_Poison,7; bonus2 bSubEle,Ele_Holy,7; bonus2 bSubEle,Ele_Dark,7; bonus2 bSubEle,Ele_Ghost,7; bonus2 bSubEle,Ele_Undead,7; bonus bMaxSP,(BaseLevel/3)+(getrefine()*10); bonus3 bSPDrainRate,10,1,0; bonus bMdef,3; },{},{} // Accessories @@ -2849,7 +2849,7 @@ //5679,Engineer_Cap,Engineer Cap,4,20,,200,,2,,1,0xFFFFFFFF,7,2,256,,10,1,608,{},{},{} //5680,Hawkeyes,Hawkeyes,4,20,,100,,0,,0,0xFFFFFFFF,7,2,512,,10,0,609,{},{},{} 5681,F_Ribbon_Green,Green Ribbon,4,800,,100,,1,,0,0xFFFFFFFF,7,0,256,,0,1,244,{ bonus bMdef,3; },{},{} -5682,Triangle_Rune_Cap,Triangle Rune Cap,4,20,,300,,5,,1,0xFFFFFFFF,7,2,256,,1,1,610,{ bonus bInt,1; },{},{} +5682,Triangle_Rune_Cap,Triangle Rune Cap,4,20,,300,,5,,1,0xFFFFFFFF,7,2,256,,1,1,610,{ bonus bHealPower,2; if (getrefine() > 6) { bonus bMatk,10; bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",8,150,BF_MAGIC,0; } else { bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",7,150,BF_MAGIC,0; } },{},{} 5683,Majestic_Goat_Repl,Baphomet Horns,4,20,,100,,5,,0,0xFFFFFFFF,7,2,256,,1,1,41,{},{},{} 5684,Jewel_Crown_Repl,Ornate Crown,4,20,,100,,5,,0,0xFFFFFFFF,7,2,256,,1,1,88,{},{},{} 5685,Prontera_Army_Cap_Repl,Army Cap,4,20,,100,,5,,0,0xFFFFFFFF,7,2,256,,1,1,48,{},{},{} diff --git a/db/pre-re/skill_cast_db.txt b/db/pre-re/skill_cast_db.txt index 93ed4294c3..80d4fd071c 100644 --- a/db/pre-re/skill_cast_db.txt +++ b/db/pre-re/skill_cast_db.txt @@ -988,15 +988,15 @@ //-- NPC_EVILLAND 670,0,0,0,30000,30000,0 //-- NPC_MAGICMIRROR -671,0,0,0,30000,0,0 +671,0,0,0,30000:30000:30000:30000:30000:2000:2000:2000:2000:2000,0,0 //-- NPC_SLOWCAST 672,0,0,0,0,30000,0 //-- NPC_CRITICALWOUND 673,0,0,0,0,30000,0 //-- NPC_STONESKIN -675,0,0,0,30000,0,0 +675,0,0,0,30000:30000:30000:30000:30000:2000:2000:2000:2000:2000,0,0 //-- NPC_ANTIMAGIC -676,0,0,0,30000,0,0 +676,0,0,0,30000:30000:30000:30000:30000:2000:2000:2000:2000:2000,0,0 //-- NPC_WIDECURSE 677,0,0,0,0,30000,0 //-- NPC_WIDESTUN diff --git a/db/re/item_db.txt b/db/re/item_db.txt index 5c2d7aeee3..130270ebed 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -1610,7 +1610,7 @@ 2529,Rider_Insignia,Rider Insignia,4,20,,500,,13,,0,0xFFFFFFFE,18,2,4,,55,1,0,{ bonus bAgi,2; },{},{} 2530,Rider_Insignia_,Rider Insignia,4,20,,500,,13,,1,0xFFFFFFFE,18,2,4,,55,1,0,{ bonus bAgi,2; },{},{} 2531,Ulfhedinn,Ulfhedinn,4,20,,700,,13,,1,0x000654E2,18,2,4,,70,1,0,{ bonus3 bAutoSpellWhenHit,"NPC_STONESKIN",6,20; },{},{} -2532,Mithril_Magic_Cape,Mithril Magic Cape,4,20,,400,,8,,1,0x00098B1C,18,2,4,,70,1,0,{ bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",1,200,BF_MAGIC,0; },{},{} +2532,Mithril_Magic_Cape,Mithril Magic Cape,4,20,,400,,8,,1,0x00098B1C,18,2,4,,70,1,0,{ bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",6,200,BF_MAGIC,0; },{},{} 2533,Freyja_Cape,Freyja Cape,4,0,,200,,10,,0,0xFFFFFFFE,63,2,4,,0,0,0,{ bonus2 bSubRace,RC_DemiHuman,15; bonus2 bSubRace,RC_Player,15; },{},{} 2534,Ruffler,Ruffler,4,20,,0,,10,,0,0xFFFFFFFF,63,2,4,,0,0,0,{ bonus2 bSubEle,Ele_Neutral,17; bonus bFlee,17; },{},{} 2535,Cloak_Of_Survival_C,Cloak Of Survival,4,1,,0,,5,,0,0x00810204,63,2,4,,0,0,0,{ bonus bVit,10; bonus bMdef,10; },{},{} @@ -1630,7 +1630,7 @@ 2549,Krieger_Muffler1,Glorious Muffler,4,20,,0,,0,,0,0xFFFFFFFE,63,2,4,,80,1,0,{ bonus bMaxHPrate,5; bonus2 bSubRace,RC_DemiHuman,5; bonus2 bSubRace,RC_Player,5; },{},{} 2550,Fisher's_Muffler,Fisher's Muffler,4,20,,200,,0,,0,0xFFFFFFFF,63,2,4,,0,1,0,{},{},{} 2551,Rider_Insignia_M,Crest of the Rider,4,20,,500,,4,,1,0xFFFFFFFE,18,2,4,,55,1,0,{ bonus bAgi,2; },{},{} -2552,Mithril_Magic_Cape_M,Mithril Magic Manteau,4,20,,400,,3,,1,0x00098B1C,18,2,4,,70,1,0,{ bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",1,200,BF_MAGIC,0; },{},{} +2552,Mithril_Magic_Cape_M,Mithril Magic Manteau,4,20,,400,,3,,1,0x00098B1C,18,2,4,,70,1,0,{ bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",6,200,BF_MAGIC,0; },{},{} 2553,Dragon_Manteau,Dragon Manteau,4,20,,1000,,14,,1,0xFFFFFFFE,18,2,4,,0,1,0,{ bonus bAgi,1; bonus bMdef,5; },{},{} 2554,Piece_Of_Angent_Skin,Nydhorgg's Shadow Garb,4,20,,400,,25,,1,0xFFFFFFFE,18,2,4,,90,1,0,{ bonus2 bSubEle,Ele_Neutral,7; bonus2 bSubEle,Ele_Water,7; bonus2 bSubEle,Ele_Earth,7; bonus2 bSubEle,Ele_Fire,7; bonus2 bSubEle,Ele_Wind,7; bonus2 bSubEle,Ele_Poison,7; bonus2 bSubEle,Ele_Holy,7; bonus2 bSubEle,Ele_Dark,7; bonus2 bSubEle,Ele_Ghost,7; bonus2 bSubEle,Ele_Undead,7; bonus bMaxSP,(BaseLevel/3)+(getrefine()*10); bonus3 bSPDrainRate,10,1,0; bonus bMdef,3; },{},{} 2555,Freyja_SScarf7,Freyja Soul Scarf,4,20,,400,,4,,0,0xFFFFFFFF,63,2,4,,20,0,0,{ bonus bFlee,15; bonus2 bSubEle,Ele_Neutral,15; },{},{} @@ -3577,7 +3577,7 @@ 5679,Engineer_Cap,Engineer Cap,4,20,,200,,2,,1,0xFFFFFFFF,63,2,256,,10,1,608,{},{},{} 5680,Hawkeyes,Hawkeyes,4,20,,100,,0,,0,0xFFFFFFFF,63,2,512,,10,0,609,{ bonus bUnbreakableHelm,0; },{},{} 5681,F_Ribbon_Green,Green Ribbon,4,800,,100,,1,,0,0xFFFFFFFF,63,0,256,,0,1,244,{ bonus bMdef,3; },{},{} -5682,Triangle_Rune_Cap,Triangle Rune Cap,4,20,,300,,5,,1,0xFFFFFFFF,63,2,256,,1,1,610,{ bonus bInt,1; },{},{} +5682,Triangle_Rune_Cap,Triangle Rune Cap,4,20,,300,,5,,1,0xFFFFFFFF,63,2,256,,1,1,610,{ bonus bHealPower,2; if (getrefine() > 6) { bonus bMatk,10; bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",8,150,BF_MAGIC,0; } else { bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",7,150,BF_MAGIC,0; } },{},{} 5683,Majestic_Goat_Repl,Baphomet Horns,4,20,,100,,5,,0,0xFFFFFFFF,63,2,256,,1,1,41,{},{},{} 5684,Jewel_Crown_Repl,Ornate Crown,4,20,,100,,5,,0,0xFFFFFFFF,63,2,256,,1,1,88,{},{},{} 5685,Prontera_Army_Cap_Repl,Army Cap,4,20,,100,,5,,0,0xFFFFFFFF,63,2,256,,1,1,48,{},{},{} diff --git a/db/re/skill_cast_db.txt b/db/re/skill_cast_db.txt index 3f86e08ca8..acb398bd7b 100644 --- a/db/re/skill_cast_db.txt +++ b/db/re/skill_cast_db.txt @@ -990,15 +990,15 @@ //-- NPC_EVILLAND 670,0,0,0,30000,30000,0,-1 //-- NPC_MAGICMIRROR -671,0,0,0,30000,0,0,-1 +671,0,0,0,30000:30000:30000:30000:30000:2000:2000:2000:2000:2000,0,0,-1 //-- NPC_SLOWCAST 672,0,0,0,0,30000,0,-1 //-- NPC_CRITICALWOUND 673,0,0,0,0,30000,0,-1 //-- NPC_STONESKIN -675,0,0,0,30000,0,0,-1 +675,0,0,0,30000:30000:30000:30000:30000:2000:2000:2000:2000:2000,0,0,-1 //-- NPC_ANTIMAGIC -676,0,0,0,30000,0,0,-1 +676,0,0,0,30000:30000:30000:30000:30000:2000:2000:2000:2000:2000,0,0,-1 //-- NPC_WIDECURSE 677,0,0,0,0,30000,0,-1 //-- NPC_WIDESTUN diff --git a/sql-files/item_db.sql b/sql-files/item_db.sql index 682c4a2ab5..458fdcde8d 100644 --- a/sql-files/item_db.sql +++ b/sql-files/item_db.sql @@ -1120,7 +1120,7 @@ REPLACE INTO `item_db` VALUES (2118,'Arm_Guard_','Arm Guard',4,10000,NULL,150,NU REPLACE INTO `item_db` VALUES (2119,'Improved_Arm_Guard','Advanced Arm Guard',4,40000,NULL,150,NULL,4,NULL,0,0x02000000,7,2,32,NULL,50,1,1,'bonus bMdef,5;',NULL,NULL); REPLACE INTO `item_db` VALUES (2120,'Improved_Arm_Guard_','Advanced Arm Guard',4,40000,NULL,150,NULL,4,NULL,1,0x02000000,7,2,32,NULL,50,1,1,'bonus bMdef,5;',NULL,NULL); REPLACE INTO `item_db` VALUES (2121,'Memorize_Book_','Memory Book',4,20,NULL,1000,NULL,3,NULL,1,0x00810204,7,2,32,NULL,0,1,5,'bonus bInt,1; bonus bMdef,2;',NULL,NULL); -REPLACE INTO `item_db` VALUES (2122,'Platinum_Shield','Platinum Shield',4,20,NULL,1200,NULL,5,NULL,0,0xFFFFFFFE,2,2,32,NULL,68,1,4,'bonus bMdef,5; bonus2 bSubSize,Size_Medium,15; bonus2 bSubSize,Size_Large,15; bonus2 bSubRace,RC_Undead,10; bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",2,150,BF_MAGIC,0;',NULL,NULL); +REPLACE INTO `item_db` VALUES (2122,'Platinum_Shield','Platinum Shield',4,20,NULL,1200,NULL,5,NULL,0,0xFFFFFFFE,2,2,32,NULL,68,1,4,'bonus bMdef,5; bonus2 bSubSize,Size_Medium,15; bonus2 bSubSize,Size_Large,15; bonus2 bSubRace,RC_Undead,10; bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",7,150,BF_MAGIC,0;',NULL,NULL); REPLACE INTO `item_db` VALUES (2123,'Orleans_Server','Orleans\'s Server',4,20,NULL,1000,NULL,5,NULL,1,0xFFFFFFFE,2,2,32,NULL,55,1,4,'bonus bMdef,2; bonus bMagicDamageReturn,5;',NULL,NULL); REPLACE INTO `item_db` VALUES (2124,'Thorny_Buckler','Thorny Buckler',4,20,NULL,1000,NULL,5,NULL,1,0xFFFFFFFE,2,2,32,NULL,55,1,2,'bonus bMdef,2;',NULL,NULL); REPLACE INTO `item_db` VALUES (2125,'Strong_Shield','Strong Shield',4,20,NULL,2500,NULL,4,NULL,1,0xFFFFFFFE,2,2,32,NULL,75,1,4,'bonus bNoKnockback,0; bonus2 bSubEle,Ele_Neutral,-20; bonus2 bSubEle,Ele_Fire,-20; bonus2 bSubEle,Ele_Water,-20; bonus2 bSubEle,Ele_Wind,-20; bonus2 bSubEle,Ele_Earth,-20; bonus2 bSubEle,Ele_Dark,-20; bonus2 bSubEle,Ele_Holy,-20; bonus2 bSubEle,Ele_Ghost,-20;',NULL,NULL); @@ -1425,8 +1425,8 @@ REPLACE INTO `item_db` VALUES (2527,'Dragon_Breath','Dragon Breath',4,20,NULL,60 REPLACE INTO `item_db` VALUES (2528,'Wool_Scarf','Wool Scarf',4,20,NULL,500,NULL,3,NULL,1,0xFFFFFFFE,2,2,4,NULL,55,1,0,'bonus bMdef,4;',NULL,NULL); REPLACE INTO `item_db` VALUES (2529,'Rider_Insignia','Rider Insignia',4,20,NULL,500,NULL,4,NULL,0,0xFFFFFFFE,2,2,4,NULL,55,1,0,'bonus bAgi,2;',NULL,NULL); REPLACE INTO `item_db` VALUES (2530,'Rider_Insignia_','Rider Insignia',4,20,NULL,500,NULL,4,NULL,1,0xFFFFFFFE,2,2,4,NULL,55,1,0,'bonus bAgi,2;',NULL,NULL); -REPLACE INTO `item_db` VALUES (2531,'Ulfhedinn','Ulfhedinn',4,20,NULL,700,NULL,3,NULL,1,0x000654E2,2,2,4,NULL,70,1,0,'bonus3 bAutoSpellWhenHit,"NPC_STONESKIN",1,20;',NULL,NULL); -REPLACE INTO `item_db` VALUES (2532,'Mithril_Magic_Cape','Mithril Magic Cape',4,20,NULL,400,NULL,3,NULL,1,0x00098B1C,2,2,4,NULL,70,1,0,'bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",1,200,BF_MAGIC,0;',NULL,NULL); +REPLACE INTO `item_db` VALUES (2531,'Ulfhedinn','Ulfhedinn',4,20,NULL,700,NULL,3,NULL,1,0x000654E2,2,2,4,NULL,70,1,0,'bonus3 bAutoSpellWhenHit,"NPC_STONESKIN",6,20;',NULL,NULL); +REPLACE INTO `item_db` VALUES (2532,'Mithril_Magic_Cape','Mithril Magic Cape',4,20,NULL,400,NULL,3,NULL,1,0x00098B1C,2,2,4,NULL,70,1,0,'bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",6,200,BF_MAGIC,0;',NULL,NULL); #REPLACE INTO `item_db` VALUES (2533,'Freyja_Cape','Freyja Cape',4,0,NULL,200,NULL,10,NULL,0,0xFFFFFFFE,7,2,4,NULL,0,0,0,'bonus2 bSubRace,RC_DemiHuman,15; bonus2 bSubRace,RC_Player,15;',NULL,NULL); REPLACE INTO `item_db` VALUES (2534,'Ruffler','Ruffler',4,20,NULL,0,NULL,10,NULL,0,0xFFFFFFFF,7,2,4,NULL,0,0,0,'bonus2 bSubEle,Ele_Neutral,17; bonus bFlee,17;',NULL,NULL); REPLACE INTO `item_db` VALUES (2535,'Cloak_Of_Survival_C','Cloak Of Survival',4,1,NULL,0,NULL,5,NULL,0,0x00810204,7,2,4,NULL,0,0,0,'bonus bVit,10; bonus bMdef,10;',NULL,NULL); @@ -1446,7 +1446,7 @@ REPLACE INTO `item_db` VALUES (2548,'Muffler_C','Neo Muffler',4,0,NULL,0,NULL,5, REPLACE INTO `item_db` VALUES (2549,'Krieger_Muffler1','Glorious Muffler',4,20,NULL,0,NULL,0,NULL,0,0xFFFFFFFE,7,2,4,NULL,81,1,0,'bonus bMaxHPRate,5; bonus2 bSubRace,RC_DemiHuman,5; bonus2 bSubRace,RC_Player,5;',NULL,NULL); REPLACE INTO `item_db` VALUES (2550,'Fisher\'s_Muffler','Fisher\'s Muffler',4,20,NULL,200,NULL,0,NULL,0,0xFFFFFFFF,7,2,4,NULL,0,1,0,NULL,NULL,NULL); REPLACE INTO `item_db` VALUES (2551,'Rider_Insignia_M','Crest of the Rider',4,20,NULL,500,NULL,4,NULL,1,0xFFFFFFFE,2,2,4,NULL,55,1,0,'bonus bAgi,2;',NULL,NULL); -REPLACE INTO `item_db` VALUES (2552,'Mithril_Magic_Cape_M','Mithril Magic Manteau',4,20,NULL,400,NULL,3,NULL,1,0x00098B1C,2,2,4,NULL,70,1,0,'bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",1,200,BF_MAGIC,0;',NULL,NULL); +REPLACE INTO `item_db` VALUES (2552,'Mithril_Magic_Cape_M','Mithril Magic Manteau',4,20,NULL,400,NULL,3,NULL,1,0x00098B1C,2,2,4,NULL,70,1,0,'bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",6,200,BF_MAGIC,0;',NULL,NULL); REPLACE INTO `item_db` VALUES (2553,'Dragon_Manteau','Dragon Manteau',4,20,NULL,1000,NULL,5,NULL,1,0xFFFFFFFE,2,2,4,NULL,0,1,0,'bonus bAgi,1; bonus bMdef,5;',NULL,NULL); REPLACE INTO `item_db` VALUES (2554,'Piece_Of_Angent_Skin','Nydhorgg\'s Shadow Garb',4,20,NULL,400,NULL,5,NULL,1,0xFFFFFFFE,2,2,4,NULL,90,1,0,'bonus2 bSubEle,Ele_Neutral,7; bonus2 bSubEle,Ele_Water,7; bonus2 bSubEle,Ele_Earth,7; bonus2 bSubEle,Ele_Fire,7; bonus2 bSubEle,Ele_Wind,7; bonus2 bSubEle,Ele_Poison,7; bonus2 bSubEle,Ele_Holy,7; bonus2 bSubEle,Ele_Dark,7; bonus2 bSubEle,Ele_Ghost,7; bonus2 bSubEle,Ele_Undead,7; bonus bMaxSP,(BaseLevel/3)+(getrefine()*10); bonus3 bSPDrainRate,10,1,0; bonus bMdef,3;',NULL,NULL); # Accessories @@ -2880,7 +2880,7 @@ REPLACE INTO `item_db` VALUES (5671,'Drooping_Morocc_Minion','Drooping Morocc Mi #REPLACE INTO `item_db` VALUES (5679,'Engineer_Cap','Engineer Cap',4,20,NULL,200,NULL,2,NULL,1,0xFFFFFFFF,7,2,256,NULL,10,1,608,NULL,NULL,NULL); #REPLACE INTO `item_db` VALUES (5680,'Hawkeyes','Hawkeyes',4,20,NULL,100,NULL,0,NULL,0,0xFFFFFFFF,7,2,512,NULL,10,0,609,NULL,NULL,NULL); REPLACE INTO `item_db` VALUES (5681,'F_Ribbon_Green','Green Ribbon',4,800,NULL,100,NULL,1,NULL,0,0xFFFFFFFF,7,0,256,NULL,0,1,244,'bonus bMdef,3;',NULL,NULL); -REPLACE INTO `item_db` VALUES (5682,'Triangle_Rune_Cap','Triangle Rune Cap',4,20,NULL,300,NULL,5,NULL,1,0xFFFFFFFF,7,2,256,NULL,1,1,610,'bonus bInt,1;',NULL,NULL); +REPLACE INTO `item_db` VALUES (5682,'Triangle_Rune_Cap','Triangle Rune Cap',4,20,NULL,300,NULL,5,NULL,1,0xFFFFFFFF,7,2,256,NULL,1,1,610,'bonus bHealPower,2; if (getrefine() > 6) { bonus bMatk,10; bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",8,150,BF_MAGIC,0; } else { bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",7,150,BF_MAGIC,0; }',NULL,NULL); REPLACE INTO `item_db` VALUES (5683,'Majestic_Goat_Repl','Baphomet Horns',4,20,NULL,100,NULL,5,NULL,0,0xFFFFFFFF,7,2,256,NULL,1,1,41,NULL,NULL,NULL); REPLACE INTO `item_db` VALUES (5684,'Jewel_Crown_Repl','Ornate Crown',4,20,NULL,100,NULL,5,NULL,0,0xFFFFFFFF,7,2,256,NULL,1,1,88,NULL,NULL,NULL); REPLACE INTO `item_db` VALUES (5685,'Prontera_Army_Cap_Repl','Army Cap',4,20,NULL,100,NULL,5,NULL,0,0xFFFFFFFF,7,2,256,NULL,1,1,48,NULL,NULL,NULL); diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql index a37425c795..c7342ba697 100644 --- a/sql-files/item_db_re.sql +++ b/sql-files/item_db_re.sql @@ -1641,7 +1641,7 @@ REPLACE INTO `item_db_re` VALUES (2528,'Wool_Scarf','Wool Scarf',4,20,NULL,500,N REPLACE INTO `item_db_re` VALUES (2529,'Rider_Insignia','Rider Insignia',4,20,NULL,500,NULL,13,NULL,0,0xFFFFFFFE,18,2,4,NULL,'55',1,0,'bonus bAgi,2;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2530,'Rider_Insignia_','Rider Insignia',4,20,NULL,500,NULL,13,NULL,1,0xFFFFFFFE,18,2,4,NULL,'55',1,0,'bonus bAgi,2;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2531,'Ulfhedinn','Ulfhedinn',4,20,NULL,700,NULL,13,NULL,1,0x000654E2,18,2,4,NULL,'70',1,0,'bonus3 bAutoSpellWhenHit,"NPC_STONESKIN",6,20;',NULL,NULL); -REPLACE INTO `item_db_re` VALUES (2532,'Mithril_Magic_Cape','Mithril Magic Cape',4,20,NULL,400,NULL,8,NULL,1,0x00098B1C,18,2,4,NULL,'70',1,0,'bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",1,200,BF_MAGIC,0;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (2532,'Mithril_Magic_Cape','Mithril Magic Cape',4,20,NULL,400,NULL,8,NULL,1,0x00098B1C,18,2,4,NULL,'70',1,0,'bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",6,200,BF_MAGIC,0;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2533,'Freyja_Cape','Freyja Cape',4,0,NULL,200,NULL,10,NULL,0,0xFFFFFFFE,63,2,4,NULL,'0',0,0,'bonus2 bSubRace,RC_DemiHuman,15; bonus2 bSubRace,RC_Player,15;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2534,'Ruffler','Ruffler',4,20,NULL,0,NULL,10,NULL,0,0xFFFFFFFF,63,2,4,NULL,'0',0,0,'bonus2 bSubEle,Ele_Neutral,17; bonus bFlee,17;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2535,'Cloak_Of_Survival_C','Cloak Of Survival',4,1,NULL,0,NULL,5,NULL,0,0x00810204,63,2,4,NULL,'0',0,0,'bonus bVit,10; bonus bMdef,10;',NULL,NULL); @@ -1661,7 +1661,7 @@ REPLACE INTO `item_db_re` VALUES (2548,'Muffler_C','Neo Muffler',4,0,NULL,0,NULL REPLACE INTO `item_db_re` VALUES (2549,'Krieger_Muffler1','Glorious Muffler',4,20,NULL,0,NULL,0,NULL,0,0xFFFFFFFE,63,2,4,NULL,'80',1,0,'bonus bMaxHPrate,5; bonus2 bSubRace,RC_DemiHuman,5; bonus2 bSubRace,RC_Player,5;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2550,'Fisher\'s_Muffler','Fisher\'s Muffler',4,20,NULL,200,NULL,0,NULL,0,0xFFFFFFFF,63,2,4,NULL,'0',1,0,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (2551,'Rider_Insignia_M','Crest of the Rider',4,20,NULL,500,NULL,4,NULL,1,0xFFFFFFFE,18,2,4,NULL,'55',1,0,'bonus bAgi,2;',NULL,NULL); -REPLACE INTO `item_db_re` VALUES (2552,'Mithril_Magic_Cape_M','Mithril Magic Manteau',4,20,NULL,400,NULL,3,NULL,1,0x00098B1C,18,2,4,NULL,'70',1,0,'bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",1,200,BF_MAGIC,0;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (2552,'Mithril_Magic_Cape_M','Mithril Magic Manteau',4,20,NULL,400,NULL,3,NULL,1,0x00098B1C,18,2,4,NULL,'70',1,0,'bonus bMdef,3; bonus5 bAutoSpellWhenHit,"NPC_ANTIMAGIC",6,200,BF_MAGIC,0;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2553,'Dragon_Manteau','Dragon Manteau',4,20,NULL,1000,NULL,14,NULL,1,0xFFFFFFFE,18,2,4,NULL,'0',1,0,'bonus bAgi,1; bonus bMdef,5;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2554,'Piece_Of_Angent_Skin','Nydhorgg\'s Shadow Garb',4,20,NULL,400,NULL,25,NULL,1,0xFFFFFFFE,18,2,4,NULL,'90',1,0,'bonus2 bSubEle,Ele_Neutral,7; bonus2 bSubEle,Ele_Water,7; bonus2 bSubEle,Ele_Earth,7; bonus2 bSubEle,Ele_Fire,7; bonus2 bSubEle,Ele_Wind,7; bonus2 bSubEle,Ele_Poison,7; bonus2 bSubEle,Ele_Holy,7; bonus2 bSubEle,Ele_Dark,7; bonus2 bSubEle,Ele_Ghost,7; bonus2 bSubEle,Ele_Undead,7; bonus bMaxSP,(BaseLevel/3)+(getrefine()*10); bonus3 bSPDrainRate,10,1,0; bonus bMdef,3;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2555,'Freyja_SScarf7','Freyja Soul Scarf',4,20,NULL,400,NULL,4,NULL,0,0xFFFFFFFF,63,2,4,NULL,'20',0,0,'bonus bFlee,15; bonus2 bSubEle,Ele_Neutral,15;',NULL,NULL); @@ -3608,7 +3608,7 @@ REPLACE INTO `item_db_re` VALUES (5678,'Notation_Hairband','Notation Hairband',4 REPLACE INTO `item_db_re` VALUES (5679,'Engineer_Cap','Engineer Cap',4,20,NULL,200,NULL,2,NULL,1,0xFFFFFFFF,63,2,256,NULL,'10',1,608,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (5680,'Hawkeyes','Hawkeyes',4,20,NULL,100,NULL,0,NULL,0,0xFFFFFFFF,63,2,512,NULL,'10',0,609,'bonus bUnbreakableHelm,0;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (5681,'F_Ribbon_Green','Green Ribbon',4,800,NULL,100,NULL,1,NULL,0,0xFFFFFFFF,63,0,256,NULL,'0',1,244,'bonus bMdef,3;',NULL,NULL); -REPLACE INTO `item_db_re` VALUES (5682,'Triangle_Rune_Cap','Triangle Rune Cap',4,20,NULL,300,NULL,5,NULL,1,0xFFFFFFFF,63,2,256,NULL,'1',1,610,'bonus bInt,1;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (5682,'Triangle_Rune_Cap','Triangle Rune Cap',4,20,NULL,300,NULL,5,NULL,1,0xFFFFFFFF,63,2,256,NULL,'1',1,610,'bonus bHealPower,2; if (getrefine() > 6) { bonus bMatk,10; bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",8,150,BF_MAGIC,0; } else { bonus5 bAutoSpellWhenHit,"NPC_MAGICMIRROR",7,150,BF_MAGIC,0; }',NULL,NULL); REPLACE INTO `item_db_re` VALUES (5683,'Majestic_Goat_Repl','Baphomet Horns',4,20,NULL,100,NULL,5,NULL,0,0xFFFFFFFF,63,2,256,NULL,'1',1,41,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (5684,'Jewel_Crown_Repl','Ornate Crown',4,20,NULL,100,NULL,5,NULL,0,0xFFFFFFFF,63,2,256,NULL,'1',1,88,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (5685,'Prontera_Army_Cap_Repl','Army Cap',4,20,NULL,100,NULL,5,NULL,0,0xFFFFFFFF,63,2,256,NULL,'1',1,48,NULL,NULL,NULL); diff --git a/src/map/battle.c b/src/map/battle.c index fff08ea227..72565f6281 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7845,6 +7845,7 @@ static const struct _battle_data { { "fame_pharmacy_5", &battle_config.fame_pharmacy_5, 3, 0, INT_MAX, }, { "fame_pharmacy_7", &battle_config.fame_pharmacy_7, 10, 0, INT_MAX, }, { "fame_pharmacy_10", &battle_config.fame_pharmacy_10, 50, 0, INT_MAX, }, + { "mail_delay", &battle_config.mail_delay, 1000, 1000, INT_MAX, }, }; #ifndef STATS_OPT_OUT /** diff --git a/src/map/battle.h b/src/map/battle.h index 4015529e08..3e1176dcd8 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -542,6 +542,7 @@ extern struct Battle_Config int transcendent_status_points; int taekwon_ranker_min_lv; int revive_onwarp; + int mail_delay; // Fame points int fame_taekwon_mission; diff --git a/src/map/clif.c b/src/map/clif.c index 72e7a1c59a..9efc609abc 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -14526,7 +14526,7 @@ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd){ return; flag = mail_setitem(sd, idx, amount); - clif_Mail_setattachment(fd,idx,flag); + clif_Mail_setattachment(fd,idx,!flag); } @@ -14551,59 +14551,17 @@ void clif_parse_Mail_winopen(int fd, struct map_session_data *sd) /// 0248 .W .24B .40B <body len>.B <body>.?B void clif_parse_Mail_send(int fd, struct map_session_data *sd) { - struct mail_message msg; - int body_len; struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)]; if( !chrif_isconnected() ) return; - if( sd->state.trading ) - return; if( RFIFOW(fd,info->pos[0]) < 69 ) { ShowWarning("Invalid Msg Len from account %d.\n", sd->status.account_id); return; } - if( DIFF_TICK(sd->cansendmail_tick, gettick()) > 0 ) { - clif_displaymessage(sd->fd,msg_txt(sd,675)); //"Cannot send mails too fast!!." - clif_Mail_send(fd, true); // fail - return; - } - - body_len = RFIFOB(fd,info->pos[3]); - - if (body_len > MAIL_BODY_LENGTH) - body_len = MAIL_BODY_LENGTH; - - if( !mail_setattachment(sd, &msg) ) { // Invalid Append condition - clif_Mail_send(sd->fd, true); // fail - mail_removeitem(sd,0); - mail_removezeny(sd,0); - return; - } - - msg.id = 0; // id will be assigned by charserver - msg.send_id = sd->status.char_id; - msg.dest_id = 0; // will attempt to resolve name - safestrncpy(msg.send_name, sd->status.name, NAME_LENGTH); - safestrncpy(msg.dest_name, (char*)RFIFOP(fd,info->pos[1]), NAME_LENGTH); - safestrncpy(msg.title, (char*)RFIFOP(fd,info->pos[2]), MAIL_TITLE_LENGTH); - - if (msg.title[0] == '\0') { - return; // Message has no length and somehow client verification was skipped. - } - - if (body_len) - safestrncpy(msg.body, (char*)RFIFOP(fd,info->pos[4]), body_len + 1); - else - memset(msg.body, 0x00, MAIL_BODY_LENGTH); - - msg.timestamp = time(NULL); - if( !intif_Mail_send(sd->status.account_id, &msg) ) - mail_deliveryfail(sd, &msg); - - sd->cansendmail_tick = gettick() + 1000; // 1 Second flood Protection + mail_send(sd, (char*)RFIFOP(fd,info->pos[1]), (char*)RFIFOP(fd,info->pos[2]), (char*)RFIFOP(fd,info->pos[4]), RFIFOB(fd,info->pos[3])); } diff --git a/src/map/mail.c b/src/map/mail.c index 290f6a4c70..48fbd86420 100644 --- a/src/map/mail.c +++ b/src/map/mail.c @@ -3,6 +3,7 @@ #include "../common/nullpo.h" #include "../common/showmsg.h" +#include "../common/strlib.h" #include "mail.h" #include "atcommand.h" @@ -10,6 +11,7 @@ #include "clif.h" #include "pc.h" #include "log.h" +#include "intif.h" #include <time.h> #include <string.h> @@ -55,40 +57,46 @@ int mail_removezeny(struct map_session_data *sd, short flag) return 1; } -unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) { +/** +* Attempt to set item or zeny +* @param sd +* @param idx 0 - Zeny; >= 2 - Inventory item +* @param amount +* @return True if item/zeny can be set, False if failed +*/ +bool mail_setitem(struct map_session_data *sd, short idx, unsigned short amount) { if( pc_istrading(sd) ) - return 1; + return false; if( idx == 0 ) { // Zeny Transfer if( amount < 0 || !pc_can_give_items(sd) ) - return 1; + return false; if( amount > sd->status.zeny ) amount = sd->status.zeny; sd->mail.zeny = amount; // clif_updatestatus(sd, SP_ZENY); - return 0; + return true; } else { // Item Transfer idx -= 2; mail_removeitem(sd, 0); if( idx < 0 || idx >= MAX_INVENTORY ) - return 1; + return false; if( amount < 0 || amount > sd->status.inventory[idx].amount ) - return 1; + return false; if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time || !itemdb_available(sd->status.inventory[idx].nameid) || !itemdb_canmail(&sd->status.inventory[idx],pc_get_group_level(sd)) || (sd->status.inventory[idx].bound && !pc_can_give_bounded_items(sd)) ) - return 1; + return false; sd->mail.index = idx; sd->mail.nameid = sd->status.inventory[idx].nameid; sd->mail.amount = amount; - - return 0; + return true; } } @@ -185,3 +193,58 @@ bool mail_invalid_operation(struct map_session_data *sd) return false; } + +/** +* Attempt to send mail +* @param sd Sender +* @param dest_name Destination name +* @param title Mail title +* @param body_msg Mail message +* @param body_len Message's length +*/ +void mail_send(struct map_session_data *sd, const char *dest_name, const char *title, const char *body_msg, int body_len) { + struct mail_message msg; + + nullpo_retv(sd); + + if( sd->state.trading ) + return; + + if( DIFF_TICK(sd->cansendmail_tick, gettick()) > 0 ) { + clif_displaymessage(sd->fd,msg_txt(sd,675)); //"Cannot send mails too fast!!." + clif_Mail_send(sd->fd, true); // fail + return; + } + + if( body_len > MAIL_BODY_LENGTH ) + body_len = MAIL_BODY_LENGTH; + + if( !mail_setattachment(sd, &msg) ) { // Invalid Append condition + clif_Mail_send(sd->fd, true); // fail + mail_removeitem(sd,0); + mail_removezeny(sd,0); + return; + } + + msg.id = 0; // id will be assigned by charserver + msg.send_id = sd->status.char_id; + msg.dest_id = 0; // will attempt to resolve name + safestrncpy(msg.send_name, sd->status.name, NAME_LENGTH); + safestrncpy(msg.dest_name, (char*)dest_name, NAME_LENGTH); + safestrncpy(msg.title, (char*)title, MAIL_TITLE_LENGTH); + + if (msg.title[0] == '\0') { + return; // Message has no length and somehow client verification was skipped. + } + + if (body_len) + safestrncpy(msg.body, (char*)body_msg, body_len + 1); + else + memset(msg.body, 0x00, MAIL_BODY_LENGTH); + + msg.timestamp = time(NULL); + if( !intif_Mail_send(sd->status.account_id, &msg) ) + mail_deliveryfail(sd, &msg); + + sd->cansendmail_tick = gettick() + battle_config.mail_delay; // Flood Protection +} diff --git a/src/map/mail.h b/src/map/mail.h index cab582e558..cd7b79c6da 100644 --- a/src/map/mail.h +++ b/src/map/mail.h @@ -9,11 +9,12 @@ void mail_clear(struct map_session_data *sd); int mail_removeitem(struct map_session_data *sd, short flag); int mail_removezeny(struct map_session_data *sd, short flag); -unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount); +bool mail_setitem(struct map_session_data *sd, short idx, unsigned short amount); bool mail_setattachment(struct map_session_data *sd, struct mail_message *msg); void mail_getattachment(struct map_session_data* sd, int zeny, struct item* item); int mail_openmail(struct map_session_data *sd); void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg); bool mail_invalid_operation(struct map_session_data *sd); +void mail_send(struct map_session_data *sd, const char *dest_name, const char *title, const char *body_msg, int body_len); #endif /* _MAIL_H_ */ diff --git a/src/map/script.c b/src/map/script.c index 9fe30245e7..90c4d5908b 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6421,7 +6421,7 @@ BUILDIN_FUNC(checkweight2){ *------------------------------------------*/ BUILDIN_FUNC(getitem) { - int amount,get_count,i; + int amount, get_count, i; unsigned short nameid; struct item it; TBL_PC *sd; @@ -6432,49 +6432,49 @@ BUILDIN_FUNC(getitem) data=script_getdata(st,2); get_val(st,data); if( data_isstring(data) ) {// "<item name>" - const char *name=conv_str(st,data); + const char *name = conv_str(st,data); struct item_data *item_data = itemdb_searchname(name); if( item_data == NULL ){ ShowError("buildin_getitem: Nonexistant item %s requested.\n", name); - return 1; //No item created. + return SCRIPT_CMD_FAILURE; //No item created. } - nameid=item_data->nameid; + nameid = item_data->nameid; } else if( data_isint(data) ) {// <item id> - nameid=conv_num(st,data); + nameid = conv_num(st,data); if( !itemdb_exists(nameid) ){ ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid); - return 1; //No item created. + return SCRIPT_CMD_FAILURE; //No item created. } } else { ShowError("buildin_getitem: invalid data type for argument #1 (%d).", data->type); - return 1; + return SCRIPT_CMD_FAILURE; } // <amount> - if( (amount=script_getnum(st,3)) <= 0) - return 0; //return if amount <=0, skip the useles iteration + if( (amount = script_getnum(st,3)) <= 0) + return SCRIPT_CMD_SUCCESS; //return if amount <=0, skip the useles iteration memset(&it,0,sizeof(it)); - it.nameid=nameid; - it.identify=itemdb_isidentified(nameid); + it.nameid = nameid; + it.identify = 1; if( !strcmp(command,"getitembound") ) { char bound = script_getnum(st,4); if( bound > BOUND_NONE && bound < BOUND_MAX ) { it.bound = bound; if( script_hasdata(st,5) ) - sd=map_id2sd(script_getnum(st,5)); + sd = map_id2sd(script_getnum(st,5)); else - sd=script_rid2sd(st); // Attached player + sd = script_rid2sd(st); // Attached player } else { //Not a correct bound type ShowError("script_getitembound: Not a correct bound type! Type=%d\n",bound); return SCRIPT_CMD_FAILURE; } } else if( script_hasdata(st,4) ) - sd=map_id2sd(script_getnum(st,4)); // <Account ID> + sd = map_id2sd(script_getnum(st,4)); // <Account ID> else - sd=script_rid2sd(st); // Attached player + sd = script_rid2sd(st); // Attached player if( sd == NULL ) // no target return SCRIPT_CMD_SUCCESS; @@ -6510,7 +6510,7 @@ BUILDIN_FUNC(getitem2) unsigned short nameid; int iden, ref, attr, c1, c2, c3, c4; char bound = BOUND_NONE; - struct item_data *item_data; + struct item_data *item_data = NULL; struct item item_tmp; unsigned char flag = 0; TBL_PC *sd; @@ -6521,49 +6521,50 @@ BUILDIN_FUNC(getitem2) bound = script_getnum(st,11); if( bound > BOUND_NONE && bound < BOUND_MAX ) { if( script_hasdata(st,12) ) - sd=map_id2sd(script_getnum(st,12)); + sd = map_id2sd(script_getnum(st,12)); else - sd=script_rid2sd(st); // Attached player + sd = script_rid2sd(st); // Attached player } else { ShowError("script_getitembound2: Not a correct bound type! Type=%d\n",bound); return SCRIPT_CMD_FAILURE; } } else if( script_hasdata(st,11) ) - sd=map_id2sd(script_getnum(st,11)); // <Account ID> + sd = map_id2sd(script_getnum(st,11)); // <Account ID> else - sd=script_rid2sd(st); // Attached player + sd = script_rid2sd(st); // Attached player if( sd == NULL ) // no target return SCRIPT_CMD_SUCCESS; - data=script_getdata(st,2); + data = script_getdata(st,2); get_val(st,data); if( data_isstring(data) ) { - const char *name=conv_str(st,data); - struct item_data *item_data_tmp = itemdb_searchname(name); - if( item_data_tmp ) - nameid=item_data_tmp->nameid; - else - nameid=UNKNOWN_ITEM_ID; - } else - nameid=conv_num(st,data); + const char *name = conv_str(st,data); + if( (item_data = itemdb_searchname(name)) == NULL ){ + ShowError("buildin_getitem2: Nonexistant item %s requested.\n", name); + return SCRIPT_CMD_FAILURE; //No item created. + } + } else { + nameid = conv_num(st,data); + if( !(item_data == itemdb_exists(nameid)) ){ + ShowError("buildin_getitem2: Nonexistant item %d requested.\n", nameid); + return SCRIPT_CMD_FAILURE; //No item created. + } + } - amount=script_getnum(st,3); - iden=script_getnum(st,4); - ref=script_getnum(st,5); - attr=script_getnum(st,6); - c1=(short)script_getnum(st,7); - c2=(short)script_getnum(st,8); - c3=(short)script_getnum(st,9); - c4=(short)script_getnum(st,10); + amount = script_getnum(st,3); + iden = script_getnum(st,4); + ref = script_getnum(st,5); + attr = script_getnum(st,6); + c1 = (short)script_getnum(st,7); + c2 = (short)script_getnum(st,8); + c3 = (short)script_getnum(st,9); + c4 = (short)script_getnum(st,10); - if(nameid > 0) { + if(item_data) { memset(&item_tmp,0,sizeof(item_tmp)); - item_data=itemdb_exists(nameid); - if (item_data == NULL) - return -1; - if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR || item_data->type==IT_SHADOWGEAR ) { + if(item_data->type == IT_WEAPON || item_data->type == IT_ARMOR || item_data->type == IT_SHADOWGEAR ) { if(ref > MAX_REFINE) ref = MAX_REFINE; } else if(item_data->type==IT_PETEGG) { @@ -6575,15 +6576,15 @@ BUILDIN_FUNC(getitem2) ref = attr = 0; } - item_tmp.nameid=nameid; - item_tmp.identify=iden; - item_tmp.refine=ref; - item_tmp.attribute=attr; - item_tmp.card[0]=(short)c1; - item_tmp.card[1]=(short)c2; - item_tmp.card[2]=(short)c3; - item_tmp.card[3]=(short)c4; - item_tmp.bound=bound; + item_tmp.nameid = nameid; + item_tmp.identify = iden; + item_tmp.refine = ref; + item_tmp.attribute = attr; + item_tmp.card[0] = (short)c1; + item_tmp.card[1] = (short)c2; + item_tmp.card[2] = (short)c3; + item_tmp.card[3] = (short)c4; + item_tmp.bound = bound; //Check if it's stackable. if (!itemdb_isstackable(nameid)) @@ -18797,7 +18798,7 @@ BUILDIN_FUNC(disable_command) { } /** Get the information of the members of a guild by type. - * getguildmember <guild_id>{,<type>}; + * getguildmember <guild_id>{,<type>}; * @param guild_id: ID of guild * @param type: Type of option (optional) */ @@ -18834,6 +18835,7 @@ BUILDIN_FUNC(getguildmember) } /** Adds spirit ball to player for 'duration' in milisecond +* addspiritball <count>,<duration>{,<char_id>}; * @param count How many spirit ball will be added * @param duration How long spiritball is active until it disappears * @param char_id Target player (Optional) @@ -18848,7 +18850,7 @@ BUILDIN_FUNC(addspiritball) { return SCRIPT_CMD_SUCCESS; if (script_hasdata(st,4)) { - if (script_isstring(st,4)) + if (!script_isstring(st,4)) sd = map_charid2sd(script_getnum(st,4)); else sd = map_nick2sd(script_getstr(st,4)); @@ -18864,6 +18866,7 @@ BUILDIN_FUNC(addspiritball) { } /** Deletes the spirit ball(s) from player +* delspiritball <count>{,<char_id>}; * @param count How many spirit ball will be deleted * @param char_id Target player (Optional) * @author [Cydh] @@ -18876,7 +18879,7 @@ BUILDIN_FUNC(delspiritball) { count = 1; if (script_hasdata(st,3)) { - if (script_isstring(st,3)) + if (!script_isstring(st,3)) sd = map_charid2sd(script_getnum(st,3)); else sd = map_nick2sd(script_getstr(st,3)); @@ -18891,6 +18894,7 @@ BUILDIN_FUNC(delspiritball) { } /** Counts the spirit ball that player has +* countspiritball {,<char_id>}; * @param char_id Target player (Optional) * @author [Cydh] */ @@ -18898,7 +18902,7 @@ BUILDIN_FUNC(countspiritball) { struct map_session_data *sd; if (script_hasdata(st,2)) { - if (script_isstring(st,2)) + if (!script_isstring(st,2)) sd = map_charid2sd(script_getnum(st,2)); else sd = map_nick2sd(script_getstr(st,2)); diff --git a/src/map/status.c b/src/map/status.c index a4fadbf883..3f0c684bd3 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -5598,7 +5598,7 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc, return 1; if(sc->data[SC_ARMORCHANGE]) - def += sc->data[SC_ARMORCHANGE]->val2; + def += (def * sc->data[SC_ARMORCHANGE]->val2) / 100; if(sc->data[SC_DRUMBATTLE]) def += sc->data[SC_DRUMBATTLE]->val3; #ifndef RENEWAL @@ -5763,7 +5763,7 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, return 1; if(sc->data[SC_ARMORCHANGE]) - mdef += sc->data[SC_ARMORCHANGE]->val3; + mdef += (mdef * sc->data[SC_ARMORCHANGE]->val3) / 100; if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3) mdef += 50; if(sc->data[SC_ENDURE]) // It has been confirmed that Eddga card grants 1 MDEF, not 0, not 10, but 1. @@ -9061,6 +9061,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val2 = 20*val1; // Heal effectiveness decrease break; case SC_MAGICMIRROR: + // Level 1 ~ 5 & 6 ~ 10 has different duration + // Level 6 ~ 10 use effect of level 1 ~ 5 + val1 %= 5; case SC_SLOWCAST: val2 = 20*val1; // Magic reflection/cast rate break; @@ -9073,8 +9076,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val2 = 20; val3 =-20; } - val2*=val1; // 20% per level - val3*=val1; + // Level 1 ~ 5 & 6 ~ 10 has different duration + // Level 6 ~ 10 use effect of level 1 ~ 5 + val1 %= 5; + val2 *= val1; // 20% per level + val3 *= val1; break; case SC_EXPBOOST: case SC_JEXPBOOST: diff --git a/src/map/vending.c b/src/map/vending.c index d127422364..a613df6f41 100755 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -508,7 +508,7 @@ void vending_reopen( struct map_session_data* sd ){ } *index = entry->index + 2; - *amount = entry->amount; + *amount = itemdb_isstackable(sd->status.cart[entry->index].id) ? entry->amount : 1; *value = entry->price; p += 8;