Przeglądaj źródła

Fixes Elemental Converter behavior (#6743)

* Fixes #6627.
* Elemental Converters will now be removed on weapon unequip/swap.
* Adds RemoveOnUnequip, RemoveOnUnequipWeapon, and RemoveOnUnequipArmor status flags and dehardcoded statuses to utilize these flags.
* Hovering Booster's cancellation of SC_HOVERING now takes place in the UnEquipScript, releasing the hard coded check.
Thanks to @Everade, @Daraen1, @Toshiro90, and @Lemongrass3110!
Aleos 3 lat temu
rodzic
commit
9bc1c53db4

+ 67 - 1
db/pre-re/status.yml

@@ -323,13 +323,15 @@ Body:
     DurationLookup: AS_ENCHANTPOISON
     CalcFlags:
       Atk_Ele: true
-    Fail:
+    End:
+      Aspersio: true
       Fireweapon: true
       Waterweapon: true
       Windweapon: true
       Earthweapon: true
       Shadowweapon: true
       Ghostweapon: true
+      Enchantarms: true
   - Status: Poisonreact
     Icon: EFST_POISONREACT
     DurationLookup: AS_POISONREACT
@@ -453,6 +455,16 @@ Body:
     DurationLookup: PR_ASPERSIO
     CalcFlags:
       Atk_Ele: true
+    Flags:
+      RemoveOnUnequipWeapon: true
+    End:
+      Encpoison: true
+      Fireweapon: true
+      Waterweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Benedictio
     Icon: EFST_BENEDICTIO
     DurationLookup: PR_BENEDICTIO
@@ -461,6 +473,7 @@ Body:
     Flags:
       NoSave: true
       NoClearance: true
+      #RemoveOnUnequipArmor: true
   - Status: Kyrie
     Icon: EFST_KYRIE
     DurationLookup: PR_KYRIE
@@ -936,6 +949,14 @@ Body:
       Atk_Ele: true
     Flags:
       NoRemoveOnDead: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Waterweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Waterweapon
     Icon: EFST_PROPERTYWATER
     DurationLookup: SA_FROSTWEAPON
@@ -943,6 +964,14 @@ Body:
       Atk_Ele: true
     Flags:
       NoRemoveOnDead: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Windweapon
     Icon: EFST_PROPERTYWIND
     DurationLookup: SA_LIGHTNINGLOADER
@@ -950,6 +979,14 @@ Body:
       Atk_Ele: true
     Flags:
       NoRemoveOnDead: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Waterweapon: true
+      Earthweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Earthweapon
     Icon: EFST_PROPERTYGROUND
     DurationLookup: SA_SEISMICWEAPON
@@ -957,6 +994,14 @@ Body:
       Atk_Ele: true
     Flags:
       NoRemoveOnDead: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Waterweapon: true
+      Windweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Volcano
     Icon: EFST_GROUNDMAGIC
     DurationLookup: SA_VOLCANO
@@ -1391,6 +1436,14 @@ Body:
     Flags:
       NoSave: true
       NoClearance: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Waterweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Ghostweapon: true
   - Status: Adrenaline2
     Icon: EFST_ADRENALINE2
     DurationLookup: BS_ADRENALINE2
@@ -1411,6 +1464,14 @@ Body:
     Flags:
       NoSave: true
       NoClearance: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Waterweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Shadowweapon: true
   - Status: Kaizel
     Icon: EFST_KAIZEL
     DurationLookup: SL_KAIZEL
@@ -2329,6 +2390,10 @@ Body:
     Flags:
       SendVal1: true
       OverlapIgnoreLevel: true
+      RemoveOnUnequipWeapon: true
+    End:
+      Enchantarms: true
+      Aspersio: true
   - Status: Magicalattack
     DurationLookup: NPC_MAGICALATTACK
     CalcFlags:
@@ -2461,6 +2526,7 @@ Body:
       All: true
     Flags:
       OverlapIgnoreLevel: true
+      RemoveOnUnequipArmor: true
   - Status: Spcost_Rate
     Icon: EFST_ATKER_BLOOD
     CalcFlags:

+ 2 - 0
db/re/item_db_equip.yml

@@ -35099,6 +35099,8 @@ Body:
     EquipLevelMin: 99
     Script: |
       bonus bAgi,1;
+    UnEquipScript: |
+      sc_end SC_HOVERING;
   - Id: 2802
     AegisName: Suicidal_Device
     Name: Suicidal Device

+ 71 - 1
db/re/status.yml

@@ -331,7 +331,8 @@ Body:
     DurationLookup: AS_ENCHANTPOISON
     CalcFlags:
       Atk_Ele: true
-    Fail:
+    End:
+      Aspersio: true
       Fireweapon: true
       Waterweapon: true
       Windweapon: true
@@ -465,6 +466,17 @@ Body:
     DurationLookup: PR_ASPERSIO
     CalcFlags:
       Atk_Ele: true
+    Flags:
+      RemoveOnUnequipWeapon: true
+    End:
+      Encpoison: true
+      Fireweapon: true
+      Waterweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
+      Enchantarms: true
   - Status: Benedictio
     Icon: EFST_BENEDICTIO
     DurationLookup: PR_BENEDICTIO
@@ -473,6 +485,7 @@ Body:
     Flags:
       NoSave: true
       NoClearance: true
+      #RemoveOnUnequipArmor: true
   - Status: Kyrie
     Icon: EFST_KYRIE
     DurationLookup: PR_KYRIE
@@ -949,6 +962,14 @@ Body:
       All: true
     Flags:
       NoRemoveOnDead: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Waterweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Waterweapon
     Icon: EFST_PROPERTYWATER
     DurationLookup: SA_FROSTWEAPON
@@ -956,6 +977,14 @@ Body:
       All: true
     Flags:
       NoRemoveOnDead: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Windweapon
     Icon: EFST_PROPERTYWIND
     DurationLookup: SA_LIGHTNINGLOADER
@@ -963,6 +992,14 @@ Body:
       All: true
     Flags:
       NoRemoveOnDead: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Waterweapon: true
+      Earthweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Earthweapon
     Icon: EFST_PROPERTYGROUND
     DurationLookup: SA_SEISMICWEAPON
@@ -970,6 +1007,14 @@ Body:
       All: true
     Flags:
       NoRemoveOnDead: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Waterweapon: true
+      Windweapon: true
+      Shadowweapon: true
+      Ghostweapon: true
   - Status: Volcano
     Icon: EFST_GROUNDMAGIC
     DurationLookup: SA_VOLCANO
@@ -1404,6 +1449,14 @@ Body:
     Flags:
       NoSave: true
       NoClearance: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Waterweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Ghostweapon: true
   - Status: Adrenaline2
     Icon: EFST_ADRENALINE2
     DurationLookup: BS_ADRENALINE2
@@ -1424,6 +1477,14 @@ Body:
     Flags:
       NoSave: true
       NoClearance: true
+    End:
+      Encpoison: true
+      Aspersio: true
+      Fireweapon: true
+      Waterweapon: true
+      Windweapon: true
+      Earthweapon: true
+      Shadowweapon: true
   - Status: Kaizel
     Icon: EFST_KAIZEL
     DurationLookup: SL_KAIZEL
@@ -1495,6 +1556,7 @@ Body:
     Flags:
       MadoCancel: true
       NoSave: true
+      RemoveOnUnequipWeapon: true
     End:
       Overthrust: true
   - Status: Hermode
@@ -2437,6 +2499,10 @@ Body:
     Flags:
       SendVal1: true
       OverlapIgnoreLevel: true
+      RemoveOnUnequipWeapon: true
+    End:
+      Enchantarms: true
+      Aspersio: true
   - Status: Magicalattack
     DurationLookup: NPC_MAGICALATTACK
     CalcFlags:
@@ -2569,6 +2635,7 @@ Body:
       All: true
     Flags:
       OverlapIgnoreLevel: true
+      RemoveOnUnequipArmor: true
   - Status: Spcost_Rate
     Icon: EFST_ATKER_BLOOD
     CalcFlags:
@@ -3170,6 +3237,7 @@ Body:
       NoDispell: true
       NoBanishingBuster: true
       NoClearance: true
+      RemoveOnUnequipWeapon: true
   - Status: Electricshocker
     Icon: EFST_ELECTRICSHOCKER
     DurationLookup: RA_ELECTRICSHOCKER
@@ -3666,6 +3734,7 @@ Body:
       NoDispell: true
       NoBanishingBuster: true
       NoClearance: true
+      RemoveOnUnequipWeapon: true
   - Status: Prestige
     Icon: EFST_PRESTIGE
     DurationLookup: LG_PRESTIGE
@@ -5653,6 +5722,7 @@ Body:
       NoDispell: true
       NoBanishingBuster: true
       NoClearance: true
+      RemoveOnUnequip: true
     Fail:
       P_Alter: true
       Madnesscancel: true

+ 3 - 0
doc/status.txt

@@ -229,6 +229,9 @@ Flags: Various status flags for specific status change events.
 	RemoveOnChangeMap     - Removed when changing map-server.
 	RemoveChemicalProtect - Removed by AM_CP_ARMOR/AM_CP_HELM/AM_CP_SHIELD/AM_CP_WEAPON.
 	RemoveElementalOption - Removed by elemental changing modes/quitting/EL_TIDAL_WEAPON/EL_WATER_SCREEN on the master and elemental.
+	RemoveOnUnequip       - Removed when unequipping any type of equipment.
+	RemoveOnUnequipWeapon - Removed when unequipping a weapon.
+	RemoveOnUnequipArmor  - Removed when unequipping an armor.
 
 	StopAttacking         - Makes the unit stop attacking.
 	StopCasting           - Makes the unit stop casting skills.

+ 1 - 2
src/map/itemdb.hpp

@@ -146,8 +146,7 @@ enum rune_item_list : t_itemid
 enum mechanic_item_list : t_itemid
 {
 	ITEMID_ACCELERATOR				= 2800,
-	ITEMID_HOVERING_BOOSTER,
-	ITEMID_SUICIDAL_DEVICE,
+	ITEMID_SUICIDAL_DEVICE				= 2802,
 	ITEMID_SHAPE_SHIFTER,
 	ITEMID_COOLING_DEVICE,
 	ITEMID_MAGNETIC_FIELD_GENERATOR,

+ 4 - 11
src/map/pc.cpp

@@ -11645,7 +11645,8 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
 	clif_unequipitemack(sd,n,pos,1);
 	pc_set_costume_view(sd);
 
-	status_change_end(&sd->bl,SC_HEAT_BARREL,INVALID_TIMER);
+	status_db.removeByStatusFlag(&sd->bl, { SCF_REMOVEONUNEQUIP });
+
 	// On weapon change (right and left hand)
 	if ((pos & EQP_ARMS) && sd->inventory_data[n]->type == IT_WEAPON) {
 		if (battle_config.ammo_unequip && !(flag & 4)) {
@@ -11670,20 +11671,12 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
 			}
 		}
 
-		skill_enchant_elemental_end(&sd->bl, SC_NONE);
-		status_change_end(&sd->bl, SC_FEARBREEZE, INVALID_TIMER);
-		status_change_end(&sd->bl, SC_EXEEDBREAK, INVALID_TIMER);
-#ifdef RENEWAL
-		status_change_end(&sd->bl, SC_MAXOVERTHRUST, INVALID_TIMER);
-#endif
+		status_db.removeByStatusFlag(&sd->bl, { SCF_REMOVEONUNEQUIPWEAPON });
 	}
 
 	// On armor change
 	if (pos & EQP_ARMOR) {
-		if (sd->sc.data[SC_HOVERING] && sd->inventory_data[n]->nameid == ITEMID_HOVERING_BOOSTER)
-			status_change_end(&sd->bl, SC_HOVERING, INVALID_TIMER);
-		//status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER); // No longer is removed? Need confirmation
-		status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
+		status_db.removeByStatusFlag(&sd->bl, { SCF_REMOVEONUNEQUIPARMOR });
 	}
 
 	// On equipment change

+ 3 - 0
src/map/script_constants.hpp

@@ -8904,6 +8904,9 @@
 	export_constant(SCF_SENDVAL3);
 	export_constant(SCF_NOFORCEDEND);
 	export_constant(SCF_NOWARNING);
+	export_constant(SCF_REMOVEONUNEQUIP);
+	export_constant(SCF_REMOVEONUNEQUIPWEAPON);
+	export_constant(SCF_REMOVEONUNEQUIPARMOR);
 
 	#undef export_constant
 	#undef export_constant2

+ 0 - 31
src/map/skill.cpp

@@ -19763,37 +19763,6 @@ int skill_maelstrom_suction(struct block_list *bl, va_list ap)
 	return 0;
 }
 
-/**
- * Remove current enchanted element for new element
- * @param bl Char
- * @param type New element
- */
-void skill_enchant_elemental_end(struct block_list *bl, int type)
-{
-	struct status_change *sc;
-	const enum sc_type scs[] = { SC_ENCPOISON, SC_ASPERSIO, SC_FIREWEAPON, SC_WATERWEAPON, SC_WINDWEAPON, SC_EARTHWEAPON, SC_SHADOWWEAPON, SC_GHOSTWEAPON };
-	int i;
-
-	nullpo_retv(bl);
-	nullpo_retv(sc= status_get_sc(bl));
-
-	if (!sc->count)
-		return;
-
-	// If it is not on equip change
-	if (type != SC_NONE)
-		status_change_end(bl, SC_ENCHANTARMS, INVALID_TIMER); // Should always end except on equip change
-	else {
-		// Check for seven wind (but not level seven!)
-		if (sc->data[SC_SEVENWIND] && sc->data[SC_SEVENWIND]->val1 < 7)
-			return;
-	}
-
-	for (i = 0; i < ARRAYLENGTH(scs); i++)
-		if (type != scs[i] && sc->data[scs[i]])
-			status_change_end(bl, scs[i], INVALID_TIMER);
-}
-
 /**
  * Check cloaking condition
  * @param bl

+ 0 - 1
src/map/skill.hpp

@@ -627,7 +627,6 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
 bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce);
 
 // Abnormal status
-void skill_enchant_elemental_end(struct block_list *bl, int type);
 bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd);
 bool skill_isNotOk_hom(struct homun_data *hd, uint16 skill_id, uint16 skill_lv);
 bool skill_isNotOk_mercenary(uint16 skill_id, s_mercenary_data *md);

+ 0 - 10
src/map/status.cpp

@@ -9843,14 +9843,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			break;
 		case SC_ENCPOISON:
 			val2= 250+50*val1; // Poisoning Chance (2.5+0.5%) in 1/10000 rate
-		case SC_ASPERSIO:
-		case SC_FIREWEAPON:
-		case SC_WATERWEAPON:
-		case SC_WINDWEAPON:
-		case SC_EARTHWEAPON:
-		case SC_SHADOWWEAPON:
-		case SC_GHOSTWEAPON:
-			skill_enchant_elemental_end(bl,type);
 			break;
 		case SC_ELEMENTALCHANGE:
 			// val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
@@ -10626,8 +10618,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			val4 = BF_WEAPON|BF_MISC; // Type
 			break;
 		case SC_ENCHANTARMS:
-			// end previous enchants
-			skill_enchant_elemental_end(bl,type);
 			// Make sure the received element is valid.
 			if (val1 >= ELE_ALL)
 				val1 = val1%ELE_ALL;

+ 3 - 0
src/map/status.hpp

@@ -2849,6 +2849,9 @@ enum e_status_change_flag : uint16 {
 	SCF_SENDVAL3,
 	SCF_NOFORCEDEND,
 	SCF_NOWARNING,
+	SCF_REMOVEONUNEQUIP,
+	SCF_REMOVEONUNEQUIPWEAPON,
+	SCF_REMOVEONUNEQUIPARMOR,
 	SCF_MAX
 };