Browse Source

Merge branch 'master' of https://github.com/rathena/rathena

aleos89 8 years ago
parent
commit
550cfcad54

+ 0 - 1
conf/battle/misc.conf

@@ -146,7 +146,6 @@ mon_trans_disable_in_gvg: no
 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
 disp_servervip_msg: no
 
 // Delay to allow user resend new mail (default & minimum is 1000)

+ 15 - 15
db/pre-re/skill_unit_db.txt

@@ -20,7 +20,7 @@
 //      0x00800(UF_DUALMODE)			Spell has effects both at an interval and when you step in/out
 //      0x01000(UF_NOKNOCKBACK)			Cannot be knocked back (only unit that can be damaged)
 //      0x02000(UF_RANGEDSINGLEUNIT)	Layout hack, use layout range propriety but only display center.
-//      0x04000(UF_REM_CRAZYWEED)		Removed if be overlapped by GN_CRAZYWEED
+//      0x04000(UF_CRAZYWEED_IMMUNE)	Immune to GN_CRAZYWEED removal
 //      0x08000(UF_REM_FIRERAIN)		Removed if be overlapped by RL_FIRE_RAIN
 //      0x10000(UF_KNOCKBACK_GROUP) 	Knock back a whole skill group (by default, skill unit is knocked back each unit)
 //      0x20000(UF_HIDDEN_TRAP) 		Hidden trap, see 'traps_setting' skill config to enable this flag
@@ -32,14 +32,14 @@
 //    u1   u2 lay  r intr target  flag
 //
 
- 12,0x7e,    ,  0, 0,  -1,all,   0x4003	//MG_SAFETYWALL
+ 12,0x7e,    ,  0, 0,  -1,all,   0x003	//MG_SAFETYWALL
  18,0x7f,    , -1, 0,  20,enemy, 0x8010	//MG_FIREWALL
  21,0x86,    ,  0, 2:2:2:2:2:2:2:2:2:2:3,1000,enemy, 0x010	//MG_THUNDERSTORM
- 25,0x85,    ,  1, 0,  -1,all,   0x6003	//AL_PNEUMA
+ 25,0x85,    ,  1, 0,  -1,all,   0x2003	//AL_PNEUMA
  27,0x81,0x80,  0, 0,  -1,all,   0x00E	//AL_WARP
  70,0x83,    , -1, 1,1000,all,   0x018	//PR_SANCTUARY
  79,0x84,    , -1, 1,3000,enemy, 0x8018	//PR_MAGNUS
- 80,0x87,0x88,  0, 1,2000,enemy, 0x4006	//WZ_FIREPILLAR
+ 80,0x87,0x88,  0, 1,2000,enemy, 0x006	//WZ_FIREPILLAR
  83,0x86,    ,  0, 3,1000,enemy, 0x010	//WZ_METEOR
  85,0x86,    ,  5:5:5:5:5:5:5:5:5:5:7, 1,1250,enemy,0x018	//WZ_VERMILION
  86,0x86,    ,  0:1:1:2:2:2:2:2:2:2, 0,-1,noone, 0x010	//WZ_WATERBALL
@@ -61,10 +61,10 @@
 220,0xb0,    ,  0, 0,  -1,all,   0x8002	//RG_GRAFFITI
 229,0xb1,    ,  0, 1,1000,enemy, 0x006	//AM_DEMONSTRATION
 254,0x86,    , -1, 0, 300,enemy, 0x010	//CR_GRANDCROSS
-285,0x9a,    ,  3, 0,  -1,all,   0xC010	//SA_VOLCANO
-286,0x9b,    ,  3, 0,  -1,all,   0xC010	//SA_DELUGE
-287,0x9c,    ,  3, 0,  -1,all,   0xC010	//SA_VIOLENTGALE
-288,0x9d,    ,  3:3:4:4:5,0, -1,all,   0xC010	//SA_LANDPROTECTOR
+285,0x9a,    ,  3, 0,  -1,all,   0x8010	//SA_VOLCANO
+286,0x9b,    ,  3, 0,  -1,all,   0x8010	//SA_DELUGE
+287,0x9c,    ,  3, 0,  -1,all,   0x8010	//SA_VIOLENTGALE
+288,0x9d,    ,  3:3:4:4:5,0, -1,all,   0x8010	//SA_LANDPROTECTOR
 306,0x9e,    ,  4, 0,6000,enemy,   0x200	//BD_LULLABY
 307,0x9f,    ,  4, 0,  -1,enemy, 0x220	//BD_RICHMANKIM
 308,0xa0,    ,  4, 0,  -1,enemy, 0x200	//BD_ETERNALCHAOS
@@ -130,10 +130,10 @@
 2274,0xe3,    ,  2, 0,  -1,ally,  0x000	//NC_STEALTHFIELD
 
 2299,0xcc,    ,  0, 1,1000,all,   0x8006 //SC_MANHOLE
-2300,0xcd,    ,  0, 0,1000,all,   0xC006 //SC_DIMENSIONDOOR
-2301,0xce,    ,  2, 0,1000,all,   0xE00E //SC_CHAOSPANIC
-2302,0xcf,    ,  2, 0,  -1,all,   0xE002 //SC_MAELSTROM
-2303,0xd0,    ,  3, 0,  -1,all,   0xE058 //SC_BLOODYLUST
+2300,0xcd,    ,  0, 0,1000,all,   0x8006 //SC_DIMENSIONDOOR
+2301,0xce,    ,  2, 0,1000,all,   0xA00E //SC_CHAOSPANIC
+2302,0xcf,    ,  2, 0,  -1,all,   0xA002 //SC_MAELSTROM
+2303,0xd0,    ,  3, 0,  -1,all,   0xA058 //SC_BLOODYLUST
 2304,0xd1,    ,  0, 2, 500,enemy, 0x018  //SC_FEINTBOMB
 
 2319,0xec,    ,  0, 3,5000,all,   0x000	//LG_BANDING
@@ -155,13 +155,13 @@
 2467,0xf3,    ,  0, 1,1000,all,   0x010	//SO_WIND_INSIGNIA
 2468,0xf4,    ,  0, 1,1000,all,   0x010	//SO_EARTH_INSIGNIA
 
-2479,0xe5,    ,  0, 1,1000,enemy, 0xC006	//GN_THORNS_TRAP
-2482,0xe6,0x7f, -1, 1, 300,enemy, 0xC000	//GN_WALLOFTHORN
+2479,0xe5,    ,  0, 1,1000,enemy, 0x8006	//GN_THORNS_TRAP
+2482,0xe6,0x7f, -1, 1, 300,enemy, 0x8000	//GN_WALLOFTHORN
 2484,0x86,    ,  0, 1, 100,enemy, 0x080	//GN_CRAZYWEED_ATK
 2485,0xe7,    ,  0, 2,2000,enemy, 0x8098	//GN_DEMONIC_FIRE
 2487,0xe8,    ,  2, 0,  -1,all,   0x2000	//GN_FIRE_EXPANSION_SMOKE_POWDER
 2488,0xe9,    ,  2, 0,  -1,all,   0x2000	//GN_FIRE_EXPANSION_TEAR_GAS
-2490,0xea,    ,  0, 1,1000,enemy, 0xC002	//GN_HELLS_PLANT
+2490,0xea,    ,  0, 1,1000,enemy, 0x8002	//GN_HELLS_PLANT
 
 2555,0x104,   ,  0, 1:2:2:3:3,500,enemy,0x6	//RL_B_TRAP
 2567,0x105,   , -1, 0,1000,enemy, 0x98	//RL_FIRE_RAIN

+ 1 - 1
db/re/item_db.txt

@@ -3905,7 +3905,7 @@
 5785,Green_Bunny_Hairband,Green Bunny Hairband,4,20,,200,,0,,0,0xFFFFFFFF,63,2,256,,1,1,664,{ bonus bStr,2; bonus bInt,1; bonus bDex,1; },{},{}
 5786,Ancient_Elven_Ear,Ancient Elven Ear,4,10,,200,,1,,0,0xFFFFFFFF,63,2,512,,1,0,665,{ bonus bLuk,1; bonus bMaxHP,100; bonus bMaxSP,30; },{},{}
 5787,Tha_Maero_Mask,Tha Maero Mask,4,20,,100,,0,,0,0xFFFFFFFF,63,2,513,,30,0,666,{ bonus bMdef,2; },{},{}
-5788,3D_Glasses,3D Glasses,4,20,,100,,1,,0,0xFFFFFFFF,63,2,512,,1,0,661,{ .@eac = eaclass()&EAJ_BASEMASK; if((.@eac==EAJ_SWORDMAN) || (.@eac==EAJ_MERCHANT) || (.@eac==EAJ_ARCHER) || (.@eac==EAJ_GUNSLINGER)) bonus bAtkRate,3; if((Class==Job_Soul_Linker) || (.@eac==EAJ_MAGE) || (.@eac==EAJ_NINJA)) bonus bMatkRate,3; if(.@eac==EAJ_THIEF) bonus bFleeRate,3; if((.@eac==EAJ_NOVICE) || (.@eac==EAJ_TAEKWON) || (Class==Job_Star_Gladiator) || (Class=Job_Star_Gladiator2)) bonus bMaxHPrate,3; bonus bMaxSPrate,3; },{},{}
+5788,3D_Glasses,3D Glasses,4,20,,100,,1,,0,0xFFFFFFFF,63,2,512,,1,0,661,{ .@eac = eaclass()&EAJ_BASEMASK; if((.@eac==EAJ_SWORDMAN) || (.@eac==EAJ_MERCHANT) || (.@eac==EAJ_ARCHER) || (.@eac==EAJ_GUNSLINGER)) bonus bAtkRate,3; if((Class==Job_Soul_Linker) || (.@eac==EAJ_MAGE) || (.@eac==EAJ_NINJA)) bonus bMatkRate,3; if(.@eac==EAJ_THIEF) bonus bFleeRate,3; if((.@eac==EAJ_NOVICE) || (.@eac==EAJ_TAEKWON) || (Class==Job_Star_Gladiator) || (Class==Job_Star_Gladiator2)) bonus bMaxHPrate,3; bonus bMaxSPrate,3; },{},{}
 5789,Thanatos_Mal_Mask,Thanatos Mal Mask,4,20,,100,,3,,0,0xFFFFFFFF,63,2,513,,30,0,667,{ bonus bVit,1; },{},{}
 5790,Holy_Mom_Love,TM,4,20,,500,,0,,1,0xFFFFFFFF,63,2,768,,45,1,610,{ bonus2 bSubRace,RC_Demon,-5; bonus2 bSubRace,RC_Undead,-5; bonus3 bAutoSpell,"MG_COLDBOLT",1,20; },{},{}
 5791,Tenkaippin_Ramen,Tenkaippin Ramen,4,20,,500,,1,,0,0xFFFFFFFF,63,2,256,,30,0,668,{ bonus bInt,-1; bonus bDex,4; },{},{}

+ 15 - 15
db/re/skill_unit_db.txt

@@ -20,7 +20,7 @@
 //      0x00800(UF_DUALMODE)			Spell has effects both at an interval and when you step in/out
 //      0x01000(UF_NOKNOCKBACK)			Cannot be knocked back (only unit that can be damaged)
 //      0x02000(UF_RANGEDSINGLEUNIT)	Layout hack, use layout range propriety but only display center.
-//      0x04000(UF_REM_CRAZYWEED)		Removed if be overlapped by GN_CRAZYWEED
+//      0x04000(UF_CRAZYWEED_IMMUNE)	Immune to GN_CRAZYWEED removal
 //      0x08000(UF_REM_FIRERAIN)		Removed if be overlapped by RL_FIRE_RAIN
 //      0x10000(UF_KNOCKBACK_GROUP) 	Knock back a whole skill group (by default, skill unit is knocked back each unit)
 //      0x20000(UF_HIDDEN_TRAP) 		Hidden trap, see 'traps_setting' skill config to enable this flag
@@ -32,14 +32,14 @@
 //    u1   u2 lay  r intr target  flag
 //
 
- 12,0x7e,    ,  0, 0,  -1,all,   0x4003	//MG_SAFETYWALL
+ 12,0x7e,    ,  0, 0,  -1,all,   0x003	//MG_SAFETYWALL
  18,0x7f,    , -1, 0,  20,enemy, 0x8010	//MG_FIREWALL
  21,0x86,    ,  0, 2:2:2:2:2:2:2:2:2:2:3,1000,enemy, 0x010	//MG_THUNDERSTORM
- 25,0x85,    ,  1, 0,  -1,all,   0x6003	//AL_PNEUMA
+ 25,0x85,    ,  1, 0,  -1,all,   0x2003	//AL_PNEUMA
  27,0x81,0x80,  0, 0,  -1,all,   0x00E	//AL_WARP
  70,0x83,    , -1, 1,1000,all,   0x018	//PR_SANCTUARY
  79,0x84,    , -1, 1,3000,enemy, 0x8018	//PR_MAGNUS
- 80,0x87,0x88,  0, 1,2000,enemy, 0x4006	//WZ_FIREPILLAR
+ 80,0x87,0x88,  0, 1,2000,enemy, 0x006	//WZ_FIREPILLAR
  83,0x86,    ,  0, 3,1000,enemy, 0x010	//WZ_METEOR
  85,0x86,    ,  5:5:5:5:5:5:5:5:5:5:7, 1,1250,enemy,0x018	//WZ_VERMILION
  86,0x86,    ,  0:1:1:2:2:2:2:2:2:2, 0,-1,noone, 0x010	//WZ_WATERBALL
@@ -61,10 +61,10 @@
 220,0xb0,    ,  0, 0,  -1,all,   0x8002	//RG_GRAFFITI
 229,0xb1,    ,  0, 1, 500,enemy, 0x006	//AM_DEMONSTRATION
 254,0x86,    , -1, 0, 300,enemy, 0x010	//CR_GRANDCROSS
-285,0x9a,    ,  3, 0,  -1,all,   0xC010	//SA_VOLCANO
-286,0x9b,    ,  3, 0,  -1,all,   0xC010	//SA_DELUGE
-287,0x9c,    ,  3, 0,  -1,all,   0xC010	//SA_VIOLENTGALE
-288,0x9d,    ,  3:3:4:4:5,0, -1,all,   0xC010	//SA_LANDPROTECTOR
+285,0x9a,    ,  3, 0,  -1,all,   0xA010	//SA_VOLCANO
+286,0x9b,    ,  3, 0,  -1,all,   0xA010	//SA_DELUGE
+287,0x9c,    ,  3, 0,  -1,all,   0xA010	//SA_VIOLENTGALE
+288,0x9d,    ,  3:3:4:4:5,0, -1,all,   0xA010	//SA_LANDPROTECTOR
 306,0x9e,    ,  4, 0,6000,enemy,   0x200	//BD_LULLABY
 307,0x9f,    ,  4, 0,  -1,enemy, 0x220	//BD_RICHMANKIM
 308,0xa0,    ,  4, 0,  -1,enemy, 0x8200	//BD_ETERNALCHAOS
@@ -131,10 +131,10 @@
 2274,0xe3,    ,  2, 0,  -1,ally,  0x000	//NC_STEALTHFIELD
 
 2299,0xcc,    ,  0, 1,1000,all,   0x8006 //SC_MANHOLE
-2300,0xcd,    ,  0, 0,1000,all,   0xC006 //SC_DIMENSIONDOOR
-2301,0xce,    ,  2, 0,1000,all,   0xE00E //SC_CHAOSPANIC
-2302,0xcf,    ,  2, 0,  -1,all,   0xE002 //SC_MAELSTROM
-2303,0xd0,    ,  3, 0,  -1,all,   0xE058 //SC_BLOODYLUST
+2300,0xcd,    ,  0, 0,1000,all,   0x8006 //SC_DIMENSIONDOOR
+2301,0xce,    ,  2, 0,1000,all,   0xA00E //SC_CHAOSPANIC
+2302,0xcf,    ,  2, 0,  -1,all,   0xA002 //SC_MAELSTROM
+2303,0xd0,    ,  3, 0,  -1,all,   0xA058 //SC_BLOODYLUST
 2304,0xd1,    ,  0, 2, 500,enemy, 0x018  //SC_FEINTBOMB
 
 2319,0xec,    ,  0, 3,5000,all,   0x000	//LG_BANDING
@@ -156,13 +156,13 @@
 2467,0xf3,    ,  0, 1,1000,all,   0x010	//SO_WIND_INSIGNIA
 2468,0xf4,    ,  0, 1,1000,all,   0x010	//SO_EARTH_INSIGNIA
 
-2479,0xe5,    ,  0, 1,1000,enemy, 0xC006	//GN_THORNS_TRAP
-2482,0xe6,0x7f, -1, 1, 300,enemy, 0xC000	//GN_WALLOFTHORN
+2479,0xe5,    ,  0, 1,1000,enemy, 0x8006	//GN_THORNS_TRAP
+2482,0xe6,0x7f, -1, 1, 300,enemy, 0x8000	//GN_WALLOFTHORN
 2484,0x86,    ,  0, 1, 100,enemy, 0x080	//GN_CRAZYWEED_ATK
 2485,0xe7,    ,  0, 2,2000,enemy, 0x8098	//GN_DEMONIC_FIRE
 2487,0xe8,    ,  2, 0,  -1,all,   0x2000	//GN_FIRE_EXPANSION_SMOKE_POWDER
 2488,0xe9,    ,  2, 0,  -1,all,   0x2000	//GN_FIRE_EXPANSION_TEAR_GAS
-2490,0xea,    ,  0, 1,1000,enemy, 0xC002	//GN_HELLS_PLANT
+2490,0xea,    ,  0, 1,1000,enemy, 0x8002	//GN_HELLS_PLANT
 
 2555,0x104,   ,  0, 1:2:2:3:3,500,enemy,0x6	//RL_B_TRAP
 2567,0x105,   , -1, 0,1000,enemy, 0x98	//RL_FIRE_RAIN

+ 2 - 1
doc/item_bonus.txt

@@ -331,7 +331,8 @@ bonus2 bWeaponComaRace,r,n; 		Adds a n/100% chance to cause Coma when attacking
 | 5. AutoSpell Bonuses |
 ========================
 NOTES:
-  - For all AutoSpell bonuses, target must be within the spell's range to go off.
+  - For all AutoSpell bonuses, target does not have be within the spell's range to go off.
+  -- Enable conf/battle/battle.conf::autospell_check_range to force a range check.
   - By default, AutoSpell skills are casted on target unless it is a self or support skill (inf = 4/16).
 
 bonus3 bAutoSpell,sk,y,n;       	Adds a n/10% chance to cast skill sk of level y when attacking

+ 1 - 1
sql-files/item_db_re.sql

@@ -3937,7 +3937,7 @@ REPLACE INTO `item_db_re` VALUES (5784,'PinkBunny_Hairband','PinkBunny Hairband'
 REPLACE INTO `item_db_re` VALUES (5785,'Green_Bunny_Hairband','Green Bunny Hairband',4,20,NULL,200,NULL,0,NULL,0,0xFFFFFFFF,63,2,256,NULL,'1',1,664,'bonus bStr,2; bonus bInt,1; bonus bDex,1;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (5786,'Ancient_Elven_Ear','Ancient Elven Ear',4,10,NULL,200,NULL,1,NULL,0,0xFFFFFFFF,63,2,512,NULL,'1',0,665,'bonus bLuk,1; bonus bMaxHP,100; bonus bMaxSP,30;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (5787,'Tha_Maero_Mask','Tha Maero Mask',4,20,NULL,100,NULL,0,NULL,0,0xFFFFFFFF,63,2,513,NULL,'30',0,666,'bonus bMdef,2;',NULL,NULL);
-REPLACE INTO `item_db_re` VALUES (5788,'3D_Glasses','3D Glasses',4,20,NULL,100,NULL,1,NULL,0,0xFFFFFFFF,63,2,512,NULL,'1',0,661,'.@eac = eaclass()&EAJ_BASEMASK; if((.@eac==EAJ_SWORDMAN) || (.@eac==EAJ_MERCHANT) || (.@eac==EAJ_ARCHER) || (.@eac==EAJ_GUNSLINGER)) bonus bAtkRate,3; if((Class==Job_Soul_Linker) || (.@eac==EAJ_MAGE) || (.@eac==EAJ_NINJA)) bonus bMatkRate,3; if(.@eac==EAJ_THIEF) bonus bFleeRate,3; if((.@eac==EAJ_NOVICE) || (.@eac==EAJ_TAEKWON) || (Class==Job_Star_Gladiator) || (Class=Job_Star_Gladiator2)) bonus bMaxHPrate,3; bonus bMaxSPrate,3;',NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (5788,'3D_Glasses','3D Glasses',4,20,NULL,100,NULL,1,NULL,0,0xFFFFFFFF,63,2,512,NULL,'1',0,661,'.@eac = eaclass()&EAJ_BASEMASK; if((.@eac==EAJ_SWORDMAN) || (.@eac==EAJ_MERCHANT) || (.@eac==EAJ_ARCHER) || (.@eac==EAJ_GUNSLINGER)) bonus bAtkRate,3; if((Class==Job_Soul_Linker) || (.@eac==EAJ_MAGE) || (.@eac==EAJ_NINJA)) bonus bMatkRate,3; if(.@eac==EAJ_THIEF) bonus bFleeRate,3; if((.@eac==EAJ_NOVICE) || (.@eac==EAJ_TAEKWON) || (Class==Job_Star_Gladiator) || (Class==Job_Star_Gladiator2)) bonus bMaxHPrate,3; bonus bMaxSPrate,3;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (5789,'Thanatos_Mal_Mask','Thanatos Mal Mask',4,20,NULL,100,NULL,3,NULL,0,0xFFFFFFFF,63,2,513,NULL,'30',0,667,'bonus bVit,1;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (5790,'Holy_Mom_Love','TM',4,20,NULL,500,NULL,0,NULL,1,0xFFFFFFFF,63,2,768,NULL,'45',1,610,'bonus2 bSubRace,RC_Demon,-5; bonus2 bSubRace,RC_Undead,-5; bonus3 bAutoSpell,"MG_COLDBOLT",1,20;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (5791,'Tenkaippin_Ramen','Tenkaippin Ramen',4,20,NULL,500,NULL,1,NULL,0,0xFFFFFFFF,63,2,256,NULL,'30',0,668,'bonus bInt,-1; bonus bDex,4;',NULL,NULL);

+ 0 - 1
src/map/battle.c

@@ -8293,7 +8293,6 @@ static const struct _battle_data {
 	{ "feature.autotrade_head_direction",	&battle_config.feature_autotrade_head_direction,0,		-1,		2,				},
 	{ "feature.autotrade_sit",				&battle_config.feature_autotrade_sit,			1,		-1,		1,				},
 	{ "feature.autotrade_open_delay",		&battle_config.feature_autotrade_open_delay,	5000,	1000,	INT_MAX,		},
-	{ "disp_serverbank_msg",				&battle_config.disp_serverbank_msg,				0,		0,		1,				},
 	{ "disp_servervip_msg",					&battle_config.disp_servervip_msg,				0,		0,		1,				},
 	{ "warg_can_falcon",                    &battle_config.warg_can_falcon,                 0,      0,      1,              },
 	{ "path_blown_halt",                    &battle_config.path_blown_halt,                 1,      0,      1,              },

+ 0 - 1
src/map/battle.h

@@ -565,7 +565,6 @@ extern struct Battle_Config
 	int fame_pharmacy_7;
 	int fame_pharmacy_10;
 
-	int disp_serverbank_msg;
 	int disp_servervip_msg;
 	int warg_can_falcon;
 	int path_blown_halt;

+ 35 - 10
src/map/instance.c

@@ -816,17 +816,18 @@ static bool instance_db_free_sub(struct instance_db *db);
 static bool instance_readdb_sub(char* str[], int columns, int current)
 {
 	uint8 i;
-	int id = atoi(str[0]);
+	char *ptr;
+	int id = strtol(str[0], &ptr, 10);
 	struct instance_db *db;
 	bool isNew = false;
 
-	if (!id || id >  USHRT_MAX) {
-		ShowError("instance_readdb_sub: Cannot add instance with ID '%d'. Valid ID is 1 ~ %d.\n", id, USHRT_MAX);
+	if (!id || id >  USHRT_MAX || *ptr) {
+		ShowError("instance_readdb_sub: Cannot add instance with ID '%d'. Valid IDs are 1 ~ %d, skipping...\n", id, USHRT_MAX);
 		return false;
 	}
 
 	if (mapindex_name2id(str[4]) == 0) {
-		ShowError("instance_readdb_sub: Invalid map '%s' as entrance map.\n", str[4]);
+		ShowError("instance_readdb_sub: Invalid map '%s' as entrance map, skipping...\n", str[4]);
 		return false;
 	}
 
@@ -836,8 +837,7 @@ static bool instance_readdb_sub(char* str[], int columns, int current)
 		db->name = StringBuf_Malloc();
 		db->enter.mapname = StringBuf_Malloc();
 		isNew = true;
-	}
-	else {
+	} else {
 		StringBuf_Clear(db->name);
 		StringBuf_Clear(db->enter.mapname);
 		if (db->maplist_count) {
@@ -849,11 +849,36 @@ static bool instance_readdb_sub(char* str[], int columns, int current)
 	}
 
 	StringBuf_AppendStr(db->name, str[1]);
-	db->limit = atoi(str[2]);
-	db->timeout = atoi(str[3]);
+
+	db->limit = strtol(str[2], &ptr, 10);
+	if (*ptr) {
+		ShowError("instance_readdb_sub: TimeLimit must be an integer value for instance '%d', skipping...\n", id);
+		instance_db_free_sub(db);
+		return false;
+	}
+
+	db->timeout = strtol(str[3], &ptr, 10);
+	if (*ptr) {
+		ShowError("instance_readdb_sub: IdleTimeOut must be an integer value for instance '%d', skipping...\n", id);
+		instance_db_free_sub(db);
+		return false;
+	}
+
 	StringBuf_AppendStr(db->enter.mapname, str[4]);
-	db->enter.x = atoi(str[5]);
-	db->enter.y = atoi(str[6]);
+
+	db->enter.x = (short)strtol(str[5], &ptr, 10);
+	if (*ptr) {
+		ShowError("instance_readdb_sub: EnterX must be an integer value for instance '%d', skipping...\n", id);
+		instance_db_free_sub(db);
+		return false;
+	}
+
+	db->enter.y = (short)strtol(str[6], &ptr, 10);
+	if (*ptr) {
+		ShowError("instance_readdb_sub: EnterY must be an integer value for instance '%d', skipping...\n", id);
+		instance_db_free_sub(db);
+		return false;
+	}
 
 	//Instance maps
 	for (i = 7; i < columns; i++) {

+ 3 - 1
src/map/mob.c

@@ -1344,7 +1344,9 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
 		if (ud) {
 			struct block_list *tbl=NULL;
 			if (ud->target && ud->state.attack_continue)
-				tbl=map_id2bl(ud->target);
+				tbl = map_id2bl(ud->target);
+			else if (ud->target_to && ud->state.attack_continue)
+				tbl = map_id2bl(ud->target_to);
 			else if (ud->skilltarget) {
 				tbl = map_id2bl(ud->skilltarget);
 				//Required check as skilltarget is not always an enemy. [Skotlex]

+ 65 - 51
src/map/npc.c

@@ -1366,6 +1366,63 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
 	return 0;
 }
 
+/** Payment Process for NPCTYPE_CASHSHOP, NPCTYPE_ITEMSHOP, and NPCTYPE_POINTSHOP
+ * @param nd NPC Shop data
+ * @param price Price must be paid
+ * @param points Total points that player has
+ * @param sd Player data
+ * @return e_CASHSHOP_ACK
+ **/
+static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int price, int points, struct map_session_data *sd) {
+	int cost[2] = { 0, 0 };
+
+	npc_shop_currency_type(sd, nd, cost, false);
+
+	switch(nd->subtype) {
+		case NPCTYPE_CASHSHOP:
+			if (cost[1] < points || cost[0] < (price - points))
+				return ERROR_TYPE_MONEY;
+			pc_paycash(sd, price, points, LOG_TYPE_NPC);
+			break;
+		case NPCTYPE_ITEMSHOP:
+			{
+				struct item_data *id = itemdb_exists(nd->u.shop.itemshop_nameid);
+
+				if (cost[0] < (price - points)) {
+					char output[CHAT_SIZE_MAX];
+
+					memset(output, '\0', sizeof(output));
+
+					sprintf(output, msg_txt(sd, 712), (id) ? id->jname : "NULL", (id) ? id->nameid : 0); // You do not have enough %s (%hu).
+					clif_colormes(sd->fd, color_table[COLOR_RED], output);
+					return ERROR_TYPE_PURCHASE_FAIL;
+				}
+				if (id)
+					pc_delitem(sd, pc_search_inventory(sd, nd->u.shop.itemshop_nameid), price - points, 0, 0, LOG_TYPE_NPC);
+				else
+					ShowWarning("Failed to delete item %hu from itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y);
+			}
+			break;
+		case NPCTYPE_POINTSHOP:
+			{
+				char output[CHAT_SIZE_MAX];
+
+				memset(output, '\0', sizeof(output));
+
+				if (cost[0] < (price - points)) {
+					sprintf(output, msg_txt(sd, 713), nd->u.shop.pointshop_str); // You do not have enough '%s'.
+					clif_colormes(sd->fd, color_table[COLOR_RED], output);
+					return ERROR_TYPE_PURCHASE_FAIL;
+				}
+				pc_setreg2(sd, nd->u.shop.pointshop_str, cost[0] - (price - points));
+				sprintf(output, msg_txt(sd, 716), nd->u.shop.pointshop_str, cost[0] - (price - points)); // Your '%s' is now: %d
+				clif_disp_onlyself(sd, output, strlen(output) + 1);
+			}
+			break;
+	}
+	return ERROR_TYPE_NONE;
+}
+
 /**
  * Cash Shop Buy List for clients 2010-11-16 and newer
  * @param sd: Player data
@@ -1376,9 +1433,10 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
  */
 int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list)
 {
-	int i, j, amount, new_, w, vt, cost[2] = { 0, 0 };
+	int i, j, amount, new_, w, vt;
 	unsigned short nameid;
 	struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
+	enum e_CASHSHOP_ACK res;
 
 	if( !nd || ( nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP ) )
 		return ERROR_TYPE_NPC;
@@ -1429,51 +1487,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
 		return ERROR_TYPE_INVENTORY_WEIGHT;
 	if( points > vt ) points = vt;
 
-	// Payment Process ----------------------------------------------------
-	npc_shop_currency_type(sd, nd, cost, false);
-
-	switch(nd->subtype) {
-		case NPCTYPE_CASHSHOP:
-			if (cost[1] < points || cost[0] < (vt - points))
-				return ERROR_TYPE_MONEY;
-			pc_paycash(sd, vt, points, LOG_TYPE_NPC);
-			break;
-		case NPCTYPE_ITEMSHOP:
-		{
-			struct item_data *id = itemdb_exists(nd->u.shop.itemshop_nameid);
-
-			if (cost[0] < (vt - points)) {
-				char output[CHAT_SIZE_MAX];
-
-				memset(output, '\0', sizeof(output));
-
-				sprintf(output, msg_txt(sd, 712), (id) ? id->jname : "NULL", (id) ? id->nameid : 0); // You do not have enough %s (%hu).
-				clif_colormes(sd->fd, color_table[COLOR_RED], output);
-				return ERROR_TYPE_PURCHASE_FAIL;
-			}
-			if (id)
-				pc_delitem(sd, pc_search_inventory(sd, nd->u.shop.itemshop_nameid), vt - points, 0, 0, LOG_TYPE_NPC);
-			else
-				ShowWarning("Failed to delete item %hu from itemshop NPC '%s' (%s, %d, %d)!\n", nd->u.shop.itemshop_nameid, nd->exname, map[nd->bl.m].name, nd->bl.x, nd->bl.y);
-		}
-			break;
-		case NPCTYPE_POINTSHOP:
-		{
-			char output[CHAT_SIZE_MAX];
-
-			memset(output, '\0', sizeof(output));
-
-			if (cost[0] < (vt - points)) {
-				sprintf(output, msg_txt(sd, 713), nd->u.shop.pointshop_str); // You do not have enough '%s'.
-				clif_colormes(sd->fd, color_table[COLOR_RED], output);
-				return ERROR_TYPE_PURCHASE_FAIL;
-			}
-			pc_setreg2(sd, nd->u.shop.pointshop_str, cost[0] - (vt - points));
-			sprintf(output, msg_txt(sd, 716), nd->u.shop.pointshop_str, cost[0] - (vt - points)); // Your '%s' is now: %d
-			clif_disp_onlyself(sd, output, strlen(output) + 1);
-		}
-			break;
-	}
+	if ((res = npc_cashshop_process_payment(nd, vt, points, sd)) != ERROR_TYPE_NONE)
+		return res;
 
 	// Delivery Process ----------------------------------------------------
 	for( i = 0; i < count; i++ ) {
@@ -1573,6 +1588,7 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo
 	struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
 	struct item_data *item;
 	int i, price, w;
+	enum e_CASHSHOP_ACK res;
 
 	if( amount <= 0 )
 		return ERROR_TYPE_ITEM_ID;
@@ -1580,7 +1596,7 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo
 	if( points < 0 )
 		return ERROR_TYPE_MONEY;
 
-	if( !nd || nd->subtype != NPCTYPE_CASHSHOP )
+	if( !nd || (nd->subtype != NPCTYPE_CASHSHOP && nd->subtype != NPCTYPE_ITEMSHOP && nd->subtype != NPCTYPE_POINTSHOP) )
 		return ERROR_TYPE_NPC;
 
 	if( sd->state.trading )
@@ -1630,10 +1646,8 @@ int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amo
 	if( points > price )
 		points = price;
 
-	if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) )
-		return ERROR_TYPE_MONEY;
-
-	pc_paycash(sd, price, points, LOG_TYPE_NPC);
+	if ((res = npc_cashshop_process_payment(nd, price, points, sd)) != ERROR_TYPE_NONE)
+		return res;
 
 	if( !pet_create_egg(sd, nameid) ) {
 		struct item item_tmp;

+ 4 - 3
src/map/pc.c

@@ -512,7 +512,7 @@ void pc_inventory_rental_clear(struct map_session_data *sd)
 void pc_inventory_rentals(struct map_session_data *sd)
 {
 	int i, c = 0;
-	unsigned int expire_tick, next_tick = UINT_MAX;
+	unsigned int next_tick = UINT_MAX;
 
 	for( i = 0; i < MAX_INVENTORY; i++ ) { // Check for Rentals on Inventory
 		if( sd->status.inventory[i].nameid == 0 )
@@ -525,8 +525,9 @@ void pc_inventory_rentals(struct map_session_data *sd)
 			clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
 			pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
 		} else {
-			expire_tick = (unsigned int)(sd->status.inventory[i].expire_time - time(NULL)) * 1000;
-			clif_rental_time(sd->fd, sd->status.inventory[i].nameid, (int)(expire_tick / 1000));
+			unsigned int expire_tick = (unsigned int)(sd->status.inventory[i].expire_time - time(NULL));
+
+			clif_rental_time(sd->fd, sd->status.inventory[i].nameid, (int)expire_tick);
 			next_tick = umin(expire_tick, next_tick);
 			c++;
 		}

+ 11 - 19
src/map/skill.c

@@ -2043,7 +2043,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
 				}
 			}
 			if (battle_config.autospell_check_range &&
-				!battle_check_range(src, tbl, skill_get_range2(src, skill, autospl_skill_lv, true)))
+				!battle_check_range(bl, tbl, skill_get_range2(src, skill, autospl_skill_lv, true)))
 				continue;
 
 			if (skill == AS_SONICBLOW)
@@ -2172,7 +2172,7 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1
 			}
 		}
 		if (battle_config.autospell_check_range &&
-			!battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill, skill_lv, true)))
+			!battle_check_range(bl, tbl, skill_get_range2(&sd->bl, skill, skill_lv, true)))
 			continue;
 
 		sd->state.autocast = 1;
@@ -2383,7 +2383,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
 				}
 			}
 
-			if (!battle_check_range(src, tbl, skill_get_range2(src, autospl_skill_id, autospl_skill_lv, true)) && battle_config.autospell_check_range)
+			if (!battle_check_range(bl, tbl, skill_get_range2(src, autospl_skill_id, autospl_skill_lv, true)) && battle_config.autospell_check_range)
 				continue;
 
 			dstsd->state.autocast = 1;
@@ -13365,7 +13365,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 	struct block_list *ss;
 	TBL_PC* tsd;
 	struct status_data *tstatus;
-	struct status_change *tsc;
+	struct status_change *sc, *tsc;
 	struct skill_unit_group_tickset *ts;
 	enum sc_type type;
 	uint16 skill_id;
@@ -13382,10 +13382,14 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 
 	tsd = BL_CAST(BL_PC, bl);
 	tsc = status_get_sc(bl);
+	sc = status_get_sc(ss);
 	tstatus = status_get_status_data(bl);
 	type = status_skill2sc(sg->skill_id);
 	skill_id = sg->skill_id;
 
+	if (sc && sc->data[SC_VOICEOFSIREN] && sc->data[SC_VOICEOFSIREN]->val2 == bl->id && (skill_get_inf2(skill_id)&INF2_TRAP))
+		return 0; // Traps cannot be activated by the Maestro or Wanderer that enticed the trapper with this skill.
+
 	if (tsc && tsc->data[SC_HOVERING] && skill_get_inf3(skill_id)&INF3_NO_EFF_HOVERING)
 		return 0; // Under Hovering characters are immune to trap and ground target skills.
 
@@ -13480,13 +13484,6 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 						skill_area_temp[3] = 0;
 					skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
 					break;
-				case GN_CRAZYWEED_ATK:
-					if( bl->type == BL_SKILL ) {
-						struct skill_unit *su = (struct skill_unit *)bl;
-						if( su && !(skill_get_inf2(su->group->skill_id)&INF2_TRAP) )
-							break;
-					}
-					//Fall through
 				default:
 					skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
 			}
@@ -17130,6 +17127,9 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
 				return 1;
 			}
 			break;
+		case GN_CRAZYWEED_ATK:
+			if (skill_get_unit_flag(unit->group->skill_id)&UF_CRAZYWEED_IMMUNE)
+				break;
 		case HW_GANBANTEIN:
 		case LG_EARTHDRIVE:
 			// Officially songs/dances are removed
@@ -17189,14 +17189,6 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
 				return 1;
 			}
 			break;
-		case GN_CRAZYWEED_ATK:
-			if (unit->group->skill_id == WZ_FIREPILLAR && unit->group->unit_id != UNT_FIREPILLAR_ACTIVE)
-				break;
-			if (skill_get_unit_flag(unit->group->skill_id)&UF_REM_CRAZYWEED) {
-				skill_delunit(unit);
-				return 1;
-			}
-			break;
 		case RL_FIRE_RAIN:
 			if (skill_get_unit_flag(unit->group->skill_id)&UF_REM_FIRERAIN) {
 				skill_delunit(unit);

+ 1 - 1
src/map/skill.h

@@ -322,7 +322,7 @@ enum e_skill_unit_flag {
 	UF_DUALMODE         = 0x00800,	// Spells should trigger both ontimer and onplace/onout/onleft effects.
 	UF_NOKNOCKBACK      = 0x01000,	// Skill unit cannot be knocked back
 	UF_RANGEDSINGLEUNIT = 0x02000,	// hack for ranged layout, only display center
-	UF_REM_CRAZYWEED    = 0x04000,	// removed by Crazyweed
+	UF_CRAZYWEED_IMMUNE = 0x04000,	// Immune to Crazy Weed removal
 	UF_REM_FIRERAIN     = 0x08000,	// removed by Fire Rain
 	UF_KNOCKBACK_GROUP  = 0x10000,	// knockback skill unit with its group instead of single unit
 	UF_HIDDEN_TRAP      = 0x20000,	// Hidden trap [Cydh]

+ 4 - 3
src/map/status.c

@@ -2034,6 +2034,9 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
 			return false;
 		}
 
+		if (flag == 1 && sc->data[SC_CURSEDCIRCLE_TARGET] && skill_id == MO_ABSORBSPIRITS) // Absorb Spirits fails to go through
+			return false;
+
 		if (skill_id != RK_REFRESH && sc->opt1 && !(sc->opt1 == OPT1_CRYSTALIZE && src->type == BL_MOB) && sc->opt1 != OPT1_BURNING && skill_id != SR_GENTLETOUCH_CURE) { // Stuned/Frozen/etc
 			if (flag != 1) // Can't cast, casted stuff can't damage.
 				return false;
@@ -8691,15 +8694,13 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 	case SC_MOONLITSERENADE:
 	case SC_RUSHWINDMILL:
 	case SC_ECHOSONG:
-	case SC_HARMONIZE:
-	case SC_FRIGG_SONG: // Group A doesn't overlap
+	case SC_HARMONIZE: // Group A doesn't overlap
 		if (type != SC_SWINGDANCE) status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
 		if (type != SC_SYMPHONYOFLOVER) status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
 		if (type != SC_MOONLITSERENADE) status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
 		if (type != SC_RUSHWINDMILL) status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
 		if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
 		if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
-		if (type != SC_FRIGG_SONG) status_change_end(bl, SC_FRIGG_SONG, INVALID_TIMER);
 		break;
 	case SC_VOICEOFSIREN:
 	case SC_DEEPSLEEP: