Browse Source

Gospel, Tarot, Curse, Poison, Hallucination, Hell Power, NPC skills
* Official Gospel chances, effects and duration (fixes #1812)
-- Chance of Gospel to trigger increased from 10%*skill_lv to 50%+5%*skill_lv
-- Gospel's Heal effect now heals 1000-9999 HP instead of 1-9999 HP
-- Blessing and Increase Agi effects now last for 4 minutes instead of 60 seconds
-- Increase Defense now only lasts 10 seconds instead of 60 seconds
-- Gospel's damage is now twice likely to trigger with one of two different effects
-- Fixed Gospel's damage not showing the Holy Cross effect
-- Gospel's first damage effect deals 3000-7999 damage which is reduced by DEF (percentual in pre-re)
-- Gospel's second damage effect deals 1500-5499 damage which cannot be reduced by DEF
-- Curse, Blind and Poison effect now last 30 minutes instead of 60 seconds
-- Provoke lasts infinite, but is removed when changing maps or logging out
-- Fixed Provoke's icon from disappearing whenever a status changes
-- DEF, ATK, Flee and Speed super debuffs now only last 20 seconds instead of 60 seconds
* Official status change base duration for curse (fixes #1811)
-- Curse base duration is 30 seconds in pre-re and 20 seconds in renewal
-- Napalm Vulcan, Tarot Card of Fate, NPC_HELLJUDGEMENT, NPC_WIDECURSE use this duration
-- NPC_CURSEATTACK has a fixed 30 seconds duration
* Official status change base duration for poison (fixes #1811)
-- Poison base duration is 60 seconds in pre-re and 20 seconds in renewal
-- Duration is no longer halved for monsters in pre-re
-- Envenom, Venom Dust, Venom Splasher, Tarot Card of Fate, NPC_POISON, NPC_ACIDBREATH use this duration
* NPC_STOP now has a duration of 15 seconds instead of 10 seconds
* NPC_HELLPOWER and NPC_WIDEHELLDIGNITY now have a duration of 180 seconds instead of 300 seconds
* Tarot Card of Fate uses base duration for Curse, Poison, Stone, Freeze and Stun
-- For Confusion and Stop the duration remains fixed to 30 seconds
* All NPC status skills now have a 20%*skill_lv chance to trigger instead of 50%+10%*skill_lv
-- NPC_HALLUCINATION and NPC_HELLPOWER now only affect you to 20% instead of 100%/60%
* Damage shown by Hallucination is now completely random instead of being multiplied by 6
* The animation is now shown when trying to resurrect someone affected by Hell Power

Special thanks to @mrjnumber1 and Luke for providing various information on these.

Playtester 8 years ago
parent
commit
74d577ce52
8 changed files with 126 additions and 81 deletions
  1. 7 7
      db/pre-re/skill_cast_db.txt
  2. 11 11
      db/re/skill_cast_db.txt
  3. 13 1
      src/map/battle.c
  4. 28 4
      src/map/clif.c
  5. 2 0
      src/map/map.c
  6. 60 54
      src/map/skill.c
  7. 3 4
      src/map/status.c
  8. 2 0
      src/map/unit.c

+ 7 - 7
db/pre-re/skill_cast_db.txt

@@ -96,7 +96,7 @@
 //-- TF_HIDING
 //-- TF_HIDING
 51,0,0,0,30000:60000:90000:120000:150000:180000:210000:240000:270000:300000,0,0
 51,0,0,0,30000:60000:90000:120000:150000:180000:210000:240000:270000:300000,0,0
 //-- TF_POISON
 //-- TF_POISON
-52,0,0,0,0,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,0
+52,0,0,0,0,60000,0
 //==========================================
 //==========================================
 
 
 
 
@@ -235,9 +235,9 @@
 //-- AS_POISONREACT
 //-- AS_POISONREACT
 139,0,0,0,20000:25000:30000:35000:40000:45000:50000:55000:60000:65000,0,0
 139,0,0,0,20000:25000:30000:35000:40000:45000:50000:55000:60000:65000,0,0
 //-- AS_VENOMDUST
 //-- AS_VENOMDUST
-140,0,0,0,5000:10000:15000:20000:25000:30000:35000:40000:45000:50000,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,0
+140,0,0,0,5000:10000:15000:20000:25000:30000:35000:40000:45000:50000,60000,0
 //-- AS_SPLASHER
 //-- AS_SPLASHER
-141,1000,0,0,5000:5500:6000:6500:7000:7500:8000:8500:9000:9500,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,0
+141,1000,0,0,5000:5500:6000:6500:7000:7500:8000:8500:9000:9500,60000,0
 
 
 //==========================================
 //==========================================
 
 
@@ -517,7 +517,7 @@
 //-- NPC_GRANDDARKNESS
 //-- NPC_GRANDDARKNESS
 339,0,0,900,900,30000,0
 339,0,0,900,900,30000,0
 //-- NPC_STOP
 //-- NPC_STOP
-342,0,0,0,10000,0,0
+342,0,0,0,15000,0,0
 //-- NPC_CHANGEUNDEAD
 //-- NPC_CHANGEUNDEAD
 348,0,0,0,30000,0,0
 348,0,0,0,30000,0,0
 //-- NPC_POWERUP
 //-- NPC_POWERUP
@@ -645,7 +645,7 @@
 //-- LK_JOINTBEAT
 //-- LK_JOINTBEAT
 399,0,800:800:800:800:800:1000:1000:1000:1000:1000,0,0,30000,0
 399,0,800:800:800:800:800:1000:1000:1000:1000:1000,0,0,30000,0
 //-- HW_NAPALMVULCAN
 //-- HW_NAPALMVULCAN
-400,1000,1000,0,0,45000,0
+400,1000,1000,0,0,30000,0
 //-- CH_SOULCOLLECT
 //-- CH_SOULCOLLECT
 401,2000,0,0,600000,0,0
 401,2000,0,0,600000,0,0
 //-- PF_MINDBREAKER
 //-- PF_MINDBREAKER
@@ -999,9 +999,9 @@
 
 
 //===== New Monster Skills (12.1) ==========
 //===== New Monster Skills (12.1) ==========
 //-- NPC_HELLPOWER
 //-- NPC_HELLPOWER
-683,0,0,0,0,300000,0
+683,0,0,0,0,180000,0
 //-- NPC_WIDEHELLDIGNITY
 //-- NPC_WIDEHELLDIGNITY
-684,0,0,0,0,300000,0
+684,0,0,0,0,180000,0
 //-- NPC_INVINCIBLE
 //-- NPC_INVINCIBLE
 685,0,0,0,-1,0,0
 685,0,0,0,-1,0,0
 //-- NPC_INVINCIBLEOFF
 //-- NPC_INVINCIBLEOFF

+ 11 - 11
db/re/skill_cast_db.txt

@@ -97,7 +97,7 @@
 //-- TF_HIDING
 //-- TF_HIDING
 51,0,0,0,30000:60000:90000:120000:150000:180000:210000:240000:270000:300000,0,0,0
 51,0,0,0,30000:60000:90000:120000:150000:180000:210000:240000:270000:300000,0,0,0
 //-- TF_POISON
 //-- TF_POISON
-52,0,0,0,0,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,0,0
+52,0,0,0,0,20000,0,0
 //==========================================
 //==========================================
 
 
 
 
@@ -234,9 +234,9 @@
 //-- AS_POISONREACT
 //-- AS_POISONREACT
 139,0,0,0,20000:25000:30000:35000:40000:45000:50000:55000:60000:65000,0,0,0
 139,0,0,0,20000:25000:30000:35000:40000:45000:50000:55000:60000:65000,0,0,0
 //-- AS_VENOMDUST
 //-- AS_VENOMDUST
-140,0,0,0,5000:10000:15000:20000:25000:30000:35000:40000:45000:50000,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,0,0
+140,0,0,0,5000:10000:15000:20000:25000:30000:35000:40000:45000:50000,20000,0,0
 //-- AS_SPLASHER
 //-- AS_SPLASHER
-141,500,0,0,5000:5500:6000:6500:7000:7500:8000:8500:9000:9500,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,7500:8000:8500:9000:9500:10000:10500:11000:11500:12000,500
+141,500,0,0,5000:5500:6000:6500:7000:7500:8000:8500:9000:9500,20000,7500:8000:8500:9000:9500:10000:10500:11000:11500:12000,500
 //==========================================
 //==========================================
 
 
 
 
@@ -292,7 +292,7 @@
 173,0,0,0,3500,0,0,0
 173,0,0,0,3500,0,0,0
 
 
 //-- NPC_POISON
 //-- NPC_POISON
-176,0,0,0,0,60000,0,0
+176,0,0,0,0,20000,0,0
 //-- NPC_BLINDATTACK
 //-- NPC_BLINDATTACK
 177,0,0,0,0,20000,0,0
 177,0,0,0,0,20000,0,0
 //-- NPC_SILENCEATTACK
 //-- NPC_SILENCEATTACK
@@ -512,7 +512,7 @@
 //-- NPC_GRANDDARKNESS
 //-- NPC_GRANDDARKNESS
 339,0,0,900,900,20000,0,0
 339,0,0,900,900,20000,0,0
 //-- NPC_STOP
 //-- NPC_STOP
-342,0,0,0,10000,0,0,0
+342,0,0,0,15000,0,0,0
 //-- NPC_CHANGEUNDEAD
 //-- NPC_CHANGEUNDEAD
 348,0,0,0,30000,0,0,0
 348,0,0,0,30000,0,0,0
 //-- NPC_POWERUP
 //-- NPC_POWERUP
@@ -638,7 +638,7 @@
 399,0,800:800:800:800:1000,0,0,30000,0,0
 399,0,800:800:800:800:1000,0,0,30000,0,0
 
 
 //-- HW_NAPALMVULCAN
 //-- HW_NAPALMVULCAN
-400,800,1000,0,0,45000,0,200
+400,800,1000,0,0,20000,0,200
 
 
 //-- CH_SOULCOLLECT
 //-- CH_SOULCOLLECT
 401,0,0,0,600000,0,0,2000
 401,0,0,0,600000,0,0,2000
@@ -973,13 +973,13 @@
 //-- NPC_ICEBREATH
 //-- NPC_ICEBREATH
 655,0,0,0,0,30000,0,-1
 655,0,0,0,0,30000,0,-1
 //-- NPC_ACIDBREATH
 //-- NPC_ACIDBREATH
-657,0,0,0,0,60000,0,-1
+657,0,0,0,0,20000,0,-1
 //-- NPC_DRAGONFEAR (Upkeep2 times are duration of: Stun(lv1), Silence(lv2), Confusion(lv3) and Bleeding(lv4))
 //-- NPC_DRAGONFEAR (Upkeep2 times are duration of: Stun(lv1), Silence(lv2), Confusion(lv3) and Bleeding(lv4))
 659,0,0,0,0,5000:30000:30000:120000,0,-1
 659,0,0,0,0,5000:30000:30000:120000,0,-1
 //-- NPC_BLEEDING
 //-- NPC_BLEEDING
 660,0,0,0,0,120000,0,-1
 660,0,0,0,0,120000,0,-1
 //-- NPC_HELLJUDGEMENT
 //-- NPC_HELLJUDGEMENT
-662,0,0,0,0,30000,0,-1
+662,0,0,0,0,20000,0,-1
 //-- NPC_WIDESILENCE
 //-- NPC_WIDESILENCE
 663,0,0,0,0,20000,0,-1
 663,0,0,0,0,20000,0,-1
 //-- NPC_WIDEFREEZE
 //-- NPC_WIDEFREEZE
@@ -1007,16 +1007,16 @@
 //-- NPC_ANTIMAGIC
 //-- NPC_ANTIMAGIC
 676,0,0,0,30000:30000:30000:30000:30000:2000:2000:2000:2000:2000,0,0,-1
 676,0,0,0,30000:30000:30000:30000:30000:2000:2000:2000:2000:2000,0,0,-1
 //-- NPC_WIDECURSE
 //-- NPC_WIDECURSE
-677,0,0,0,0,30000,0,-1
+677,0,0,0,0,20000,0,-1
 //-- NPC_WIDESTUN
 //-- NPC_WIDESTUN
 678,0,0,0,0,5000,0,-1
 678,0,0,0,0,5000,0,-1
 //==========================================
 //==========================================
 
 
 //===== New Monster Skills (12.1) ==========
 //===== New Monster Skills (12.1) ==========
 //-- NPC_HELLPOWER
 //-- NPC_HELLPOWER
-683,0,0,0,0,300000,0,-1
+683,0,0,0,0,180000,0,-1
 //-- NPC_WIDEHELLDIGNITY
 //-- NPC_WIDEHELLDIGNITY
-684,0,0,0,0,300000,0,-1
+684,0,0,0,0,180000,0,-1
 //-- NPC_INVINCIBLE
 //-- NPC_INVINCIBLE
 685,0,0,0,-1,0,0,-1
 685,0,0,0,-1,0,0,-1
 //-- NPC_INVINCIBLEOFF
 //-- NPC_INVINCIBLEOFF

+ 13 - 1
src/map/battle.c

@@ -6465,7 +6465,19 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 			md.damage = 500 + 300 * skill_lv;
 			md.damage = 500 + 300 * skill_lv;
 			break;
 			break;
 		case PA_GOSPEL:
 		case PA_GOSPEL:
-			md.damage = 1 + rnd()%9999;
+			if (mflag > 0)
+				md.damage = (rnd() % 4000) + 1500;
+			else {
+				md.damage = (rnd() % 5000) + 3000;
+#ifdef RENEWAL
+				md.damage -= (int64)status_get_def(target);
+#else
+				md.damage -= (md.damage * (int64)status_get_def(target)) / 100;
+#endif
+				md.damage -= tstatus->def2;
+				if (md.damage < 0)
+					md.damage = 0;
+			}
 			break;
 			break;
 		case CR_ACIDDEMONSTRATION:
 		case CR_ACIDDEMONSTRATION:
 #ifdef RENEWAL
 #ifdef RENEWAL

+ 28 - 4
src/map/clif.c

@@ -3891,6 +3891,11 @@ void clif_changeoption(struct block_list* bl)
 	} else
 	} else
 		clif_send(buf,packet_len(0x119),bl,AREA);
 		clif_send(buf,packet_len(0x119),bl,AREA);
 #endif
 #endif
+
+	//Whenever we send "changeoption" to the client, the provoke icon is lost
+	//There is probably an option for the provoke icon, but as we don't know it, we have to do this for now
+	if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->timer == INVALID_TIMER)
+		clif_status_change(bl, StatusIconChangeTable[SC_PROVOKE], 1, -1, 0, 0, 0);
 }
 }
 
 
 
 
@@ -4656,6 +4661,25 @@ static int clif_calc_walkdelay(struct block_list *bl,int delay, char type, int64
 	return (delay > 0) ? delay:1; //Return 1 to specify there should be no noticeable delay, but you should stop walking.
 	return (delay > 0) ? delay:1; //Return 1 to specify there should be no noticeable delay, but you should stop walking.
 }
 }
 
 
+/*========================================== [Playtester]
+* Returns hallucination damage the client displays
+*------------------------------------------*/
+static int clif_hallucination_damage()
+{
+	int digit = rnd() % 5 + 1;
+	switch (digit)
+	{
+	case 1:
+		return (rnd() % 10);
+	case 2:
+		return (rnd() % 100);
+	case 3:
+		return (rnd() % 1000);
+	case 4:
+		return (rnd() % 10000);
+	}
+	return (rnd() % 32767);
+}
 
 
 /// Sends a 'damage' packet (src performs action on dst)
 /// Sends a 'damage' packet (src performs action on dst)
 /// 008a <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.W <div>.W <type>.B <damage2>.W (ZC_NOTIFY_ACT)
 /// 008a <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.W <div>.W <type>.B <damage2>.W (ZC_NOTIFY_ACT)
@@ -4699,8 +4723,8 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
 	sc = status_get_sc(dst);
 	sc = status_get_sc(dst);
 	if(sc && sc->count) {
 	if(sc && sc->count) {
 		if(sc->data[SC_HALLUCINATION]) {
 		if(sc->data[SC_HALLUCINATION]) {
-			if(damage) damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
-			if(damage2) damage2 = damage2*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+			if(damage) damage = clif_hallucination_damage();
+			if(damage2) damage2 = clif_hallucination_damage();
 		}
 		}
 	}
 	}
 
 
@@ -5440,7 +5464,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
 
 
 	if( ( sc = status_get_sc(dst) ) && sc->count ) {
 	if( ( sc = status_get_sc(dst) ) && sc->count ) {
 		if(sc->data[SC_HALLUCINATION] && damage)
 		if(sc->data[SC_HALLUCINATION] && damage)
-			damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+			damage = clif_hallucination_damage();
 	}
 	}
 
 
 #if PACKETVER < 3
 #if PACKETVER < 3
@@ -5537,7 +5561,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in
 
 
 	if(sc && sc->count) {
 	if(sc && sc->count) {
 		if(sc->data[SC_HALLUCINATION] && damage)
 		if(sc->data[SC_HALLUCINATION] && damage)
-			damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+			damage = clif_hallucination_damage();
 	}
 	}
 
 
 	WBUFW(buf,0)=0x115;
 	WBUFW(buf,0)=0x115;

+ 2 - 0
src/map/map.c

@@ -2008,6 +2008,8 @@ int map_quit(struct map_session_data *sd) {
 		status_change_end(&sd->bl, SC_CHASEWALK2, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_CHASEWALK2, INVALID_TIMER);
 		if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
 		if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
 			status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure.
 			status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure.
+		if(sd->sc.data[SC_PROVOKE] && sd->sc.data[SC_PROVOKE]->timer == INVALID_TIMER)
+			status_change_end(&sd->bl, SC_PROVOKE, INVALID_TIMER); //Infinite provoke ends on logout
 		status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
 		status_change_end(&sd->bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);

+ 60 - 54
src/map/skill.c

@@ -1296,7 +1296,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
 		break;
 		break;
 
 
 	case NPC_PETRIFYATTACK:
 	case NPC_PETRIFYATTACK:
-		sc_start4(src,bl,status_skill2sc(skill_id),50+10*skill_lv,
+		sc_start4(src,bl,status_skill2sc(skill_id),(20*skill_lv),
 			skill_lv,0,0,skill_get_time(skill_id,skill_lv),
 			skill_lv,0,0,skill_get_time(skill_id,skill_lv),
 			skill_get_time2(skill_id,skill_lv));
 			skill_get_time2(skill_id,skill_lv));
 		break;
 		break;
@@ -1306,16 +1306,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
 	case NPC_POISON:
 	case NPC_POISON:
 	case NPC_SILENCEATTACK:
 	case NPC_SILENCEATTACK:
 	case NPC_STUNATTACK:
 	case NPC_STUNATTACK:
+	case NPC_BLEEDING:
 	case NPC_HELLPOWER:
 	case NPC_HELLPOWER:
-		sc_start(src,bl,status_skill2sc(skill_id),50+10*skill_lv,skill_lv,skill_get_time2(skill_id,skill_lv));
+		sc_start(src,bl,status_skill2sc(skill_id),(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
 		break;
 		break;
 	case NPC_ACIDBREATH:
 	case NPC_ACIDBREATH:
 	case NPC_ICEBREATH:
 	case NPC_ICEBREATH:
 		sc_start(src,bl,status_skill2sc(skill_id),70,skill_lv,skill_get_time2(skill_id,skill_lv));
 		sc_start(src,bl,status_skill2sc(skill_id),70,skill_lv,skill_get_time2(skill_id,skill_lv));
 		break;
 		break;
-	case NPC_BLEEDING:
-		sc_start2(src,bl,SC_BLEEDING,(20*skill_lv),skill_lv,src->id,skill_get_time2(skill_id,skill_lv));
-		break;
 	case NPC_MENTALBREAKER:
 	case NPC_MENTALBREAKER:
 		{	//Based on observations by Tharis, Mental Breaker should do SP damage
 		{	//Based on observations by Tharis, Mental Breaker should do SP damage
 			//equal to Matk*skLevel.
 			//equal to Matk*skLevel.
@@ -3254,7 +3252,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 	//Display damage.
 	//Display damage.
 	switch( skill_id ) {
 	switch( skill_id ) {
 		case PA_GOSPEL: //Should look like Holy Cross [Skotlex]
 		case PA_GOSPEL: //Should look like Holy Cross [Skotlex]
-			dmg.dmotion = clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, DMG_SPLASH);
+			dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, DMG_SPLASH);
 			break;
 			break;
 		//Skills that need be passed as a normal attack for the client to display correctly.
 		//Skills that need be passed as a normal attack for the client to display correctly.
 		case HVAN_EXPLOSION:
 		case HVAN_EXPLOSION:
@@ -4383,14 +4381,15 @@ static int skill_tarotcard(struct block_list* src, struct block_list *target, ui
 	{
 	{
 		enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE };
 		enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE };
 		uint8 rand_eff = rnd() % 3;
 		uint8 rand_eff = rnd() % 3;
-		sc_start2(src, target, sc[rand_eff], 100, skill_lv, (rand_eff == 2 ? src->id : 0), skill_get_time2(skill_id, skill_lv));
+		int time = ((rand_eff == 0) ? skill_get_time2(skill_id, skill_lv) : skill_get_time2(status_sc2skill(sc[rand_eff]), 1));
+		sc_start(src, target, sc[rand_eff], 100, skill_lv, time);
 		break;
 		break;
 	}
 	}
 	case 9: // DEATH - curse, coma and poison
 	case 9: // DEATH - curse, coma and poison
 	{
 	{
 		status_change_start(src, target, SC_COMA, 10000, skill_lv, 0, src->id, 0, 0, SCSTART_NONE);
 		status_change_start(src, target, SC_COMA, 10000, skill_lv, 0, src->id, 0, 0, SCSTART_NONE);
-		sc_start(src, target, SC_CURSE, 100, skill_lv, skill_get_time2(skill_id, skill_lv));
-		sc_start2(src, target, SC_POISON, 100, skill_lv, src->id, skill_get_time2(skill_id, skill_lv));
+		sc_start(src, target, SC_CURSE, 100, skill_lv, skill_get_time2(status_sc2skill(SC_CURSE), 1));
+		sc_start2(src, target, SC_POISON, 100, skill_lv, src->id, skill_get_time2(status_sc2skill(SC_POISON), 1));
 		break;
 		break;
 	}
 	}
 	case 10: // TEMPERANCE - confusion
 	case 10: // TEMPERANCE - confusion
@@ -4404,7 +4403,7 @@ static int skill_tarotcard(struct block_list* src, struct block_list *target, ui
 		clif_damage(src, target, tick, 0, 0, 6666, 0, DMG_NORMAL, 0, false);
 		clif_damage(src, target, tick, 0, 0, 6666, 0, DMG_NORMAL, 0, false);
 		sc_start(src, target, SC_INCATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv));
 		sc_start(src, target, SC_INCATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv));
 		sc_start(src, target, SC_INCMATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv));
 		sc_start(src, target, SC_INCMATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv));
-		sc_start(src, target, SC_CURSE, skill_lv, 100, skill_get_time2(skill_id, skill_lv));
+		sc_start(src, target, SC_CURSE, skill_lv, 100, skill_get_time2(status_sc2skill(SC_CURSE), 1));
 		break;
 		break;
 	}
 	}
 	case 12: // THE TOWER - 4444 damage
 	case 12: // THE TOWER - 4444 damage
@@ -4415,7 +4414,7 @@ static int skill_tarotcard(struct block_list* src, struct block_list *target, ui
 	}
 	}
 	case 13: // THE STAR - stun
 	case 13: // THE STAR - stun
 	{
 	{
-		sc_start(src, target, SC_STUN, 100, skill_lv, 5000);
+		sc_start(src, target, SC_STUN, 100, skill_lv, skill_get_time2(status_sc2skill(SC_STUN), 1));
 		break;
 		break;
 	}
 	}
 	default: // THE SUN - atk, matk, hit, flee and def reduced, immune to more tarot card effects
 	default: // THE SUN - atk, matk, hit, flee and def reduced, immune to more tarot card effects
@@ -6179,8 +6178,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			break;
 			break;
 		{
 		{
 			int per = 0, sper = 0;
 			int per = 0, sper = 0;
-			if (tsc && tsc->data[SC_HELLPOWER])
+			if (tsc && tsc->data[SC_HELLPOWER]) {
+				clif_skill_nodamage(src, bl, ALL_RESURRECTION, skill_lv, 1);
 				break;
 				break;
+			}
 
 
 			if (map[bl->m].flag.pvp && dstsd && dstsd->pvp_point < 0)
 			if (map[bl->m].flag.pvp && dstsd && dstsd->pvp_point < 0)
 				break;
 				break;
@@ -6582,7 +6583,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case SG_SUN_COMFORT:
 	case SG_SUN_COMFORT:
 	case SG_MOON_COMFORT:
 	case SG_MOON_COMFORT:
 	case SG_STAR_COMFORT:
 	case SG_STAR_COMFORT:
-	case NPC_HALLUCINATION:
 	case GS_MADNESSCANCEL:
 	case GS_MADNESSCANCEL:
 	case GS_ADJUSTMENT:
 	case GS_ADJUSTMENT:
 	case GS_INCREASING:
 	case GS_INCREASING:
@@ -6626,6 +6626,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
 			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
 		break;
 		break;
 
 
+	case NPC_HALLUCINATION:
+		clif_skill_nodamage(src, bl, skill_id, skill_lv,
+			sc_start(src, bl, type, skill_lv*20, skill_lv, skill_get_time(skill_id, skill_lv)));
+		break;
+
 	case SU_STOOP:
 	case SU_STOOP:
 		clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
 		clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
 		sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
 		sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
@@ -6826,7 +6831,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 				(dstsd->sc.data[type] && dstsd->sc.data[type]->val1 != src->id) || // Cannot Devote a player devoted from another source
 				(dstsd->sc.data[type] && dstsd->sc.data[type]->val1 != src->id) || // Cannot Devote a player devoted from another source
 				(skill_id == ML_DEVOTION && (!mer || mer != dstsd->md)) || // Mercenary only can devote owner
 				(skill_id == ML_DEVOTION && (!mer || mer != dstsd->md)) || // Mercenary only can devote owner
 				(dstsd->class_&MAPID_UPPERMASK) == MAPID_CRUSADER || // Crusader Cannot be devoted
 				(dstsd->class_&MAPID_UPPERMASK) == MAPID_CRUSADER || // Crusader Cannot be devoted
-				(dstsd->sc.data[SC_HELLPOWER])) // Players affected by SC_HELLPOWERR cannot be devoted.
+				(dstsd->sc.data[SC_HELLPOWER])) // Players affected by SC_HELLPOWER cannot be devoted.
 			{
 			{
 				if( sd )
 				if( sd )
 					clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 					clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -13705,101 +13710,102 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns
 			break;
 			break;
 
 
 		case UNT_GOSPEL:
 		case UNT_GOSPEL:
-			if (rnd()%100 > sg->skill_lv*10 || ss == bl)
+			if (rnd() % 100 > 50 + sg->skill_lv * 5 || ss == bl)
 				break;
 				break;
-			if (battle_check_target(ss,bl,BCT_PARTY)>0)
+			if (battle_check_target(ss, bl, BCT_PARTY) > 0)
 			{ // Support Effect only on party, not guild
 			{ // Support Effect only on party, not guild
 				int heal;
 				int heal;
-				int i = rnd()%13; // Positive buff count
+				int i = rnd() % 13; // Positive buff count
 				int time = skill_get_time2(sg->skill_id, sg->skill_lv); //Duration
 				int time = skill_get_time2(sg->skill_id, sg->skill_lv); //Duration
 				switch (i)
 				switch (i)
 				{
 				{
-					case 0: // Heal 1~9999 HP
-						heal = rnd() %9999+1;
-						clif_skill_nodamage(ss,bl,AL_HEAL,heal,1);
-						status_heal(bl,heal,0,0);
+					case 0: // Heal 1000~9999 HP
+						heal = rnd() % 9000 + 1000;
+						clif_skill_nodamage(ss, bl, AL_HEAL, heal, 1);
+						status_heal(bl, heal, 0, 0);
 						break;
 						break;
 					case 1: // End all negative status
 					case 1: // End all negative status
-						status_change_clear_buffs(bl, SCCB_DEBUFFS|SCCB_REFRESH);
+						status_change_clear_buffs(bl, SCCB_DEBUFFS | SCCB_REFRESH);
 						if (tsd) clif_gospel_info(tsd, 0x15);
 						if (tsd) clif_gospel_info(tsd, 0x15);
 						break;
 						break;
 					case 2: // Immunity to all status
 					case 2: // Immunity to all status
-						sc_start(ss, bl,SC_SCRESIST,100,100,time);
+						sc_start(ss, bl, SC_SCRESIST, 100, 100, time);
 						if (tsd) clif_gospel_info(tsd, 0x16);
 						if (tsd) clif_gospel_info(tsd, 0x16);
 						break;
 						break;
 					case 3: // MaxHP +100%
 					case 3: // MaxHP +100%
-						sc_start(ss, bl,SC_INCMHPRATE,100,100,time);
+						sc_start(ss, bl, SC_INCMHPRATE, 100, 100, time);
 						if (tsd) clif_gospel_info(tsd, 0x17);
 						if (tsd) clif_gospel_info(tsd, 0x17);
 						break;
 						break;
 					case 4: // MaxSP +100%
 					case 4: // MaxSP +100%
-						sc_start(ss, bl,SC_INCMSPRATE,100,100,time);
+						sc_start(ss, bl, SC_INCMSPRATE, 100, 100, time);
 						if (tsd) clif_gospel_info(tsd, 0x18);
 						if (tsd) clif_gospel_info(tsd, 0x18);
 						break;
 						break;
 					case 5: // All stats +20
 					case 5: // All stats +20
-						sc_start(ss, bl,SC_INCALLSTATUS,100,20,time);
+						sc_start(ss, bl, SC_INCALLSTATUS, 100, 20, time);
 						if (tsd) clif_gospel_info(tsd, 0x19);
 						if (tsd) clif_gospel_info(tsd, 0x19);
 						break;
 						break;
 					case 6: // Level 10 Blessing
 					case 6: // Level 10 Blessing
-						sc_start(ss, bl,SC_BLESSING,100,10,time);
+						sc_start(ss, bl, SC_BLESSING, 100, 10, skill_get_time(AL_BLESSING, 10));
 						break;
 						break;
 					case 7: // Level 10 Increase AGI
 					case 7: // Level 10 Increase AGI
-						sc_start(ss, bl,SC_INCREASEAGI,100,10,time);
+						sc_start(ss, bl, SC_INCREASEAGI, 100, 10, skill_get_time(AL_INCAGI, 10));
 						break;
 						break;
 					case 8: // Enchant weapon with Holy element
 					case 8: // Enchant weapon with Holy element
-						sc_start(ss, bl,SC_ASPERSIO,100,1,time);
+						sc_start(ss, bl, SC_ASPERSIO, 100, 1, time);
 						if (tsd) clif_gospel_info(tsd, 0x1c);
 						if (tsd) clif_gospel_info(tsd, 0x1c);
 						break;
 						break;
 					case 9: // Enchant armor with Holy element
 					case 9: // Enchant armor with Holy element
-						sc_start(ss, bl,SC_BENEDICTIO,100,1,time);
+						sc_start(ss, bl, SC_BENEDICTIO, 100, 1, time);
 						if (tsd) clif_gospel_info(tsd, 0x1d);
 						if (tsd) clif_gospel_info(tsd, 0x1d);
 						break;
 						break;
 					case 10: // DEF +25%
 					case 10: // DEF +25%
-						sc_start(ss, bl,SC_INCDEFRATE,100,25,time);
+						sc_start(ss, bl, SC_INCDEFRATE, 100, 25, 10000); //10 seconds
 						if (tsd) clif_gospel_info(tsd, 0x1e);
 						if (tsd) clif_gospel_info(tsd, 0x1e);
 						break;
 						break;
 					case 11: // ATK +100%
 					case 11: // ATK +100%
-						sc_start(ss, bl,SC_INCATKRATE,100,100,time);
+						sc_start(ss, bl, SC_INCATKRATE, 100, 100, time);
 						if (tsd) clif_gospel_info(tsd, 0x1f);
 						if (tsd) clif_gospel_info(tsd, 0x1f);
 						break;
 						break;
 					case 12: // HIT/Flee +50
 					case 12: // HIT/Flee +50
-						sc_start(ss, bl,SC_INCHIT,100,50,time);
-						sc_start(ss, bl,SC_INCFLEE,100,50,time);
+						sc_start(ss, bl, SC_INCHIT, 100, 50, time);
+						sc_start(ss, bl, SC_INCFLEE, 100, 50, time);
 						if (tsd) clif_gospel_info(tsd, 0x20);
 						if (tsd) clif_gospel_info(tsd, 0x20);
 						break;
 						break;
 				}
 				}
 			}
 			}
-			else if (battle_check_target(&unit->bl,bl,BCT_ENEMY)>0)
+			else if (battle_check_target(&unit->bl, bl, BCT_ENEMY) > 0)
 			{ // Offensive Effect
 			{ // Offensive Effect
-				int i = rnd()%9; // Negative buff count
+				int i = rnd() % 10; // Negative buff count
 				int time = skill_get_time2(sg->skill_id, sg->skill_lv);
 				int time = skill_get_time2(sg->skill_id, sg->skill_lv);
 				switch (i)
 				switch (i)
 				{
 				{
-					case 0: // Deal 1~9999 damage
-						skill_attack(BF_MISC,ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
+					case 0: // Deal 3000~7999 damage reduced by DEF
+					case 1: // Deal 1500~5499 damage unreducable
+						skill_attack(BF_MISC, ss, &unit->bl, bl, sg->skill_id, sg->skill_lv, tick, i);
 						break;
 						break;
-					case 1: // Curse
-						sc_start(ss, bl,SC_CURSE,100,1,time);
+					case 2: // Curse
+						sc_start(ss, bl, SC_CURSE, 100, 1, 1800000); //30 minutes
 						break;
 						break;
-					case 2: // Blind
-						sc_start(ss, bl,SC_BLIND,100,1,time);
+					case 3: // Blind
+						sc_start(ss, bl, SC_BLIND, 100, 1, 1800000); //30 minutes
 						break;
 						break;
-					case 3: // Poison
-						sc_start2(ss, bl,SC_POISON,100,1,ss->id,time);
+					case 4: // Poison
+						sc_start2(ss, bl, SC_POISON, 100, 1, ss->id, 1800000); //30 minutes
 						break;
 						break;
-					case 4: // Level 10 Provoke
-						sc_start(ss, bl,SC_PROVOKE,100,10,time);
+					case 5: // Level 10 Provoke
+						clif_skill_nodamage(NULL, bl, SM_PROVOKE, 10, sc_start(ss, bl, SC_PROVOKE, 100, 10, -1)); //Infinite
 						break;
 						break;
-					case 5: // DEF -100%
-						sc_start(ss, bl,SC_INCDEFRATE,100,-100,time);
+					case 6: // DEF -100%
+						sc_start(ss, bl, SC_INCDEFRATE, 100, -100, 20000); //20 seconds
 						break;
 						break;
-					case 6: // ATK -100%
-						sc_start(ss, bl,SC_INCATKRATE,100,-100,time);
+					case 7: // ATK -100%
+						sc_start(ss, bl, SC_INCATKRATE, 100, -100, 20000); //20 seconds
 						break;
 						break;
-					case 7: // Flee -100%
-						sc_start(ss, bl,SC_INCFLEERATE,100,-100,time);
+					case 8: // Flee -100%
+						sc_start(ss, bl, SC_INCFLEERATE, 100, -100, 20000); //20 seconds
 						break;
 						break;
-					case 8: // Speed/ASPD -25%
-						sc_start4(ss, bl,SC_GOSPEL,100,1,0,0,BCT_ENEMY,time);
+					case 9: // Speed/ASPD -25%
+						sc_start4(ss, bl, SC_GOSPEL, 100, 1, 0, 0, BCT_ENEMY, 20000); //20 seconds
 						break;
 						break;
 				}
 				}
 			}
 			}

+ 3 - 4
src/map/status.c

@@ -217,7 +217,7 @@ void initChangeTables(void)
 	add_sc( NPC_STUNATTACK		, SC_STUN		);
 	add_sc( NPC_STUNATTACK		, SC_STUN		);
 	add_sc( NPC_SLEEPATTACK		, SC_SLEEP		);
 	add_sc( NPC_SLEEPATTACK		, SC_SLEEP		);
 	set_sc( NPC_POISON		, SC_POISON		, SI_BLANK		, SCB_DEF2|SCB_REGEN );
 	set_sc( NPC_POISON		, SC_POISON		, SI_BLANK		, SCB_DEF2|SCB_REGEN );
-	set_sc( NPC_CURSEATTACK		, SC_CURSE		, SI_BLANK		, SCB_LUK|SCB_BATK|SCB_WATK|SCB_SPEED );
+	set_sc( NPC_WIDECURSE		, SC_CURSE		, SI_BLANK		, SCB_LUK|SCB_BATK|SCB_WATK|SCB_SPEED );
 	add_sc( NPC_SILENCEATTACK	, SC_SILENCE		);
 	add_sc( NPC_SILENCEATTACK	, SC_SILENCE		);
 	add_sc( NPC_WIDECONFUSE		, SC_CONFUSION		);
 	add_sc( NPC_WIDECONFUSE		, SC_CONFUSION		);
 	set_sc( NPC_BLINDATTACK		, SC_BLIND		, SI_BLANK		, SCB_HIT|SCB_FLEE );
 	set_sc( NPC_BLINDATTACK		, SC_BLIND		, SI_BLANK		, SCB_HIT|SCB_FLEE );
@@ -7753,6 +7753,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
 		case SC_POISON:
 		case SC_POISON:
 		case SC_DPOISON:
 		case SC_DPOISON:
 			sc_def = status->vit*100;
 			sc_def = status->vit*100;
+#ifndef RENEWAL
 			sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
 			sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
 			if (sd) {
 			if (sd) {
 				// For players: 60000 - 450*vit - 100*luk
 				// For players: 60000 - 450*vit - 100*luk
@@ -7763,6 +7764,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
 				tick>>=1;
 				tick>>=1;
 				tick_def = (status->vit*200)/3;
 				tick_def = (status->vit*200)/3;
 			}
 			}
+#endif
 			break;
 			break;
 		case SC_STUN:
 		case SC_STUN:
 			sc_def = status->vit*100;
 			sc_def = status->vit*100;
@@ -9919,9 +9921,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			if (val1 < 1)
 			if (val1 < 1)
 				val1 = 1;
 				val1 = 1;
 			break;
 			break;
-		case SC_HALLUCINATION:
-			val2 = 5+val1; // Factor by which displayed damage is increased by
-			break;
 		case SC_DOUBLECAST:
 		case SC_DOUBLECAST:
 			val2 = 30+10*val1; // Trigger rate
 			val2 = 30+10*val1; // Trigger rate
 			break;
 			break;

+ 2 - 0
src/map/unit.c

@@ -2869,6 +2869,8 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 		status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
 		status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
 		if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
 		if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
 			status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
 			status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
+		if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->timer == INVALID_TIMER)
+			status_change_end(bl, SC_PROVOKE, INVALID_TIMER); //End infinite provoke to prevent exploit
 		status_change_end(bl, SC_CHANGE, INVALID_TIMER);
 		status_change_end(bl, SC_CHANGE, INVALID_TIMER);
 		status_change_end(bl, SC_STOP, INVALID_TIMER);
 		status_change_end(bl, SC_STOP, INVALID_TIMER);
 		status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
 		status_change_end(bl, SC_WUGDASH, INVALID_TIMER);