Browse Source

Updates SC_CHANGEUNDEAD behavior (#6867)

* Fixes #6834.
* Versus Players
- Animation will be properly displayed for Blessing/Increase Agility when the target has Change Undead active (buffs are not applied even though animation is displayed).
- Target can no longer be killed through the single damage applied by Blessing/Increase Agility and Change Undead.
- If the target has Curse and Stone active, only Curse is removed by Blessing first (buffs are not applied).
- Shadow or Undead armor have no impact on Blessing or Increase Agility at all.
* Versus Monsters
- Blessing is applied normally to the target as long as it's not an Undead element or Demon race.
- Blessing does not cancel out Curse or Stone.
Thanks to @Playtester!
Aleos 3 years ago
parent
commit
d617d9f083
3 changed files with 18 additions and 16 deletions
  1. 0 2
      db/pre-re/status.yml
  2. 7 3
      src/map/skill.cpp
  3. 11 11
      src/map/status.cpp

+ 0 - 2
db/pre-re/status.yml

@@ -418,8 +418,6 @@ Body:
     Flags:
     Flags:
       BossResist: true
       BossResist: true
       TaekwonAngel: true
       TaekwonAngel: true
-    EndReturn:
-      Curse: true
   - Status: Signumcrucis
   - Status: Signumcrucis
     Icon: EFST_CRUCIS
     Icon: EFST_CRUCIS
     DurationLookup: AL_CRUCIS
     DurationLookup: AL_CRUCIS

+ 7 - 3
src/map/skill.cpp

@@ -3650,7 +3650,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 
 
 	if( (skill_id == AL_INCAGI || skill_id == AL_BLESSING ||
 	if( (skill_id == AL_INCAGI || skill_id == AL_BLESSING ||
 		skill_id == CASH_BLESSING || skill_id == CASH_INCAGI ||
 		skill_id == CASH_BLESSING || skill_id == CASH_INCAGI ||
-		skill_id == MER_INCAGI || skill_id == MER_BLESSING) && tsd->sc.data[SC_CHANGEUNDEAD] )
+		skill_id == MER_INCAGI || skill_id == MER_BLESSING) && tsc && tsc->data[SC_CHANGEUNDEAD] )
 		damage = 1;
 		damage = 1;
 
 
 	if( damage && tsc && tsc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){
 	if( damage && tsc && tsc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){
@@ -7564,10 +7564,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case AL_BLESSING:
 	case AL_BLESSING:
 	case MER_INCAGI:
 	case MER_INCAGI:
 	case MER_BLESSING:
 	case MER_BLESSING:
-		if (dstsd != NULL && tsc->data[SC_CHANGEUNDEAD]) {
-			skill_attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
+		clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
+		if (dstsd != nullptr && tsc && tsc->data[SC_CHANGEUNDEAD]) {
+			if (tstatus->hp > 1)
+				skill_attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
 			break;
 			break;
 		}
 		}
+		sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
+		break;
 	case PR_SLOWPOISON:
 	case PR_SLOWPOISON:
 	case PR_LEXAETERNA:
 	case PR_LEXAETERNA:
 #ifndef RENEWAL
 #ifndef RENEWAL

+ 11 - 11
src/map/status.cpp

@@ -5770,7 +5770,7 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
 		if(sc->data[SC_BLESSING]->val2)
 		if(sc->data[SC_BLESSING]->val2)
 			str += sc->data[SC_BLESSING]->val2;
 			str += sc->data[SC_BLESSING]->val2;
 		else
 		else
-			str >>= 1;
+			str -= str / 2;
 	}
 	}
 	if(sc->data[SC_MARIONETTE])
 	if(sc->data[SC_MARIONETTE])
 		str -= ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
 		str -= ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
@@ -6000,7 +6000,7 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
 		if (sc->data[SC_BLESSING]->val2)
 		if (sc->data[SC_BLESSING]->val2)
 			int_ += sc->data[SC_BLESSING]->val2;
 			int_ += sc->data[SC_BLESSING]->val2;
 		else
 		else
-			int_ >>= 1;
+			int_ -= int_ / 2;
 	}
 	}
 	if(sc->data[SC_NEN])
 	if(sc->data[SC_NEN])
 		int_ += sc->data[SC_NEN]->val1;
 		int_ += sc->data[SC_NEN]->val1;
@@ -6091,7 +6091,7 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
 		if (sc->data[SC_BLESSING]->val2)
 		if (sc->data[SC_BLESSING]->val2)
 			dex += sc->data[SC_BLESSING]->val2;
 			dex += sc->data[SC_BLESSING]->val2;
 		else
 		else
-			dex >>= 1;
+			dex -= dex / 2;
 	}
 	}
 	if(sc->data[SC_INCREASING])
 	if(sc->data[SC_INCREASING])
 		dex += 4; // Added based on skill updates [Reddozen]
 		dex += 4; // Added based on skill updates [Reddozen]
@@ -9674,14 +9674,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 	// List of hardcoded status cured.
 	// List of hardcoded status cured.
 	switch (type) {
 	switch (type) {
 		case SC_BLESSING:
 		case SC_BLESSING:
-			// !TODO: Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
-			// !but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
-			if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
-				status_change_end(bl, SC_CURSE, INVALID_TIMER);
-				status_change_end(bl, SC_STONE, INVALID_TIMER);
+			if (bl->type == BL_PC) {
+				// Remove Curse first, Stone is only removed if the target is not cursed
 				if (sc->data[SC_CURSE]) {
 				if (sc->data[SC_CURSE]) {
-						status_change_end(bl, SC_CURSE, INVALID_TIMER);
-						return 1; // End Curse and do not give stat boost
+					status_change_end(bl, SC_CURSE, INVALID_TIMER);
+					return 1; // End Curse and do not give stat boost
+				} else if (sc->data[SC_STONE]) {
+					status_change_end(bl, SC_STONE, INVALID_TIMER);
+					return 1; // End Stone and do not give stat boost
 				}
 				}
 			}
 			}
 			if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
 			if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
@@ -10516,7 +10516,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			val3 = 5*val1; // SP cost
 			val3 = 5*val1; // SP cost
 			break;
 			break;
 		case SC_BLESSING:
 		case SC_BLESSING:
-			if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
+			if (bl->type == BL_PC || (!undead_flag && status->race != RC_DEMON))
 				val2 = val1;
 				val2 = val1;
 			else
 			else
 				val2 = 0; // 0 -> Half stat.
 				val2 = 0; // 0 -> Half stat.