Browse Source

Implemented the skills NPC_RELIEVE_ON and NPC_RELIEVE_OFF (#7614)

* Implemented the skills NPC_RELIEVE_ON and NPC_RELIEVE_OFF as part of episode 17.2

Thanks to @aleos89 !
Atemo 2 years ago
parent
commit
81b62348b7
7 changed files with 62 additions and 0 deletions
  1. 24 0
      db/re/skill_db.yml
  2. 19 0
      db/re/status.yml
  3. 9 0
      src/map/battle.cpp
  4. 2 0
      src/map/script_constants.hpp
  5. 2 0
      src/map/skill.cpp
  6. 3 0
      src/map/status.cpp
  7. 3 0
      src/map/status.hpp

+ 24 - 0
db/re/skill_db.yml

@@ -18266,6 +18266,30 @@ Body:
     SplashArea: 14
     SplashArea: 14
     Duration2: 18000
     Duration2: 18000
     Status: Curse
     Status: Curse
+  - Id: 771
+    Name: NPC_RELIEVE_ON
+    Description: NPC_RELIEVE_ON
+    MaxLevel: 1
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+    Flags:
+      IsNpc: true
+    HitCount: 1
+    Duration1: -1
+    Status: Relieve_on
+  - Id: 772
+    Name: NPC_RELIEVE_OFF
+    Description: NPC_RELIEVE_OFF
+    MaxLevel: 1
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+    Flags:
+      IsNpc: true
+    HitCount: 1
+    Duration1: 60000
+    Status: Relieve_off
   - Id: 783
   - Id: 783
     Name: NPC_KILLING_AURA
     Name: NPC_KILLING_AURA
     Description: Killing Aura
     Description: Killing Aura

+ 19 - 0
db/re/status.yml

@@ -8742,3 +8742,22 @@ Body:
       IMMUNE_PROPERTY_SAINT: true
       IMMUNE_PROPERTY_SAINT: true
       IMMUNE_PROPERTY_DARKNESS: true
       IMMUNE_PROPERTY_DARKNESS: true
       IMMUNE_PROPERTY_TELEKINESIS: true
       IMMUNE_PROPERTY_TELEKINESIS: true
+  - Status: RELIEVE_ON
+    Icon: EFST_RELIEVE_DAMAGE
+    DurationLookup: NPC_RELIEVE_ON
+    Flags:
+      BlEffect: true
+      DisplayPc: true
+      NoDispell: true
+      NoBanishingBuster: true
+      NoClearance: true
+    EndOnStart:
+      Relieve_off: true
+  - Status: Relieve_off
+    DurationLookup: NPC_RELIEVE_OFF
+    Flags:
+      NoDispell: true
+      NoBanishingBuster: true
+      NoClearance: true
+    EndOnStart:
+      Relieve_on: true

+ 9 - 0
src/map/battle.cpp

@@ -1931,6 +1931,15 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		pc_overheat(*sd, (battle_get_weapon_element(d, src, bl, skill_id, skill_lv, EQI_HAND_R, false) == ELE_FIRE ? 3 : 1));
 		pc_overheat(*sd, (battle_get_weapon_element(d, src, bl, skill_id, skill_lv, EQI_HAND_R, false) == ELE_FIRE ? 3 : 1));
 	}
 	}
 
 
+	// Target status (again), required for RELIEVE
+	sc = status_get_sc(bl);
+
+	// !TODO: Should RELIEVE needed to be down here or after some other check? Should the skill be independent of damagetaken from mob_db.yml?
+	if (sc && sc->count) {
+		if ((sce = sc->getSCE(SC_RELIEVE_ON)) && !sc->getSCE(SC_RELIEVE_OFF))
+			damage = i64max((damage - damage * sce->val2 / 100), 1);
+	}
+
 	if (bl->type == BL_MOB) { // Reduces damage received for Green Aura MVP
 	if (bl->type == BL_MOB) { // Reduces damage received for Green Aura MVP
 		mob_data *md = BL_CAST(BL_MOB, bl);
 		mob_data *md = BL_CAST(BL_MOB, bl);
 
 

+ 2 - 0
src/map/script_constants.hpp

@@ -1886,6 +1886,8 @@
 	export_constant(SC_IMMUNE_PROPERTY_DARKNESS);
 	export_constant(SC_IMMUNE_PROPERTY_DARKNESS);
 	export_constant(SC_IMMUNE_PROPERTY_TELEKINESIS);
 	export_constant(SC_IMMUNE_PROPERTY_TELEKINESIS);
 	export_constant(SC_IMMUNE_PROPERTY_UNDEAD);
 	export_constant(SC_IMMUNE_PROPERTY_UNDEAD);
+	export_constant(SC_RELIEVE_ON);
+	export_constant(SC_RELIEVE_OFF);
 
 
 #ifdef RENEWAL
 #ifdef RENEWAL
 	export_constant(SC_EXTREMITYFIST2);
 	export_constant(SC_EXTREMITYFIST2);

+ 2 - 0
src/map/skill.cpp

@@ -7854,6 +7854,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case TR_KVASIR_SONATA:
 	case TR_KVASIR_SONATA:
 	case EM_SPELL_ENCHANTING:
 	case EM_SPELL_ENCHANTING:
 	case NPC_DAMAGE_HEAL:
 	case NPC_DAMAGE_HEAL:
+	case NPC_RELIEVE_ON:
+	case NPC_RELIEVE_OFF:
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,
 			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;

+ 3 - 0
src/map/status.cpp

@@ -12498,6 +12498,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 				tick_time = 500; // Avoid being brought down to 0.
 				tick_time = 500; // Avoid being brought down to 0.
 			val4 = tick - tick_time; // Remaining Time
 			val4 = tick - tick_time; // Remaining Time
 			break;
 			break;
+		case SC_RELIEVE_ON:
+			val2 = min(10*val1, 99); // % damage received reduced from 10 * skill lvl up to 99%
+			break;
 		case SC_VIGOR: {
 		case SC_VIGOR: {
 				uint8 hp_loss[10] = { 15, 14, 12, 11, 9, 8, 6, 5, 3, 2 };
 				uint8 hp_loss[10] = { 15, 14, 12, 11, 9, 8, 6, 5, 3, 2 };
 
 

+ 3 - 0
src/map/status.hpp

@@ -1278,6 +1278,9 @@ enum sc_type : int16 {
 	SC_IMMUNE_PROPERTY_TELEKINESIS,
 	SC_IMMUNE_PROPERTY_TELEKINESIS,
 	SC_IMMUNE_PROPERTY_UNDEAD,
 	SC_IMMUNE_PROPERTY_UNDEAD,
 
 
+	SC_RELIEVE_ON,
+	SC_RELIEVE_OFF,
+
 #ifdef RENEWAL
 #ifdef RENEWAL
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
 #endif
 #endif