crazyarashi пре 2 месеци
родитељ
комит
b683e2f21f

+ 2 - 2
db/re/item_combos.yml

@@ -11976,7 +11976,7 @@ Body:
     Script: |
       bonus bFlee,5;
       if (getequiprefinerycnt(EQI_SHADOW_SHOES)+getequiprefinerycnt(EQI_SHADOW_ARMOR) >= 15)
-         bonus bSpeedRate,25;
+         bonus bMoveHaste;
   - Combos:
       - Combo:
           - S_Hasty_Armor    # 24197
@@ -11984,7 +11984,7 @@ Body:
     Script: |
       bonus bFlee,5;
       if ((getequiprefinerycnt(EQI_SHADOW_ARMOR) + getequiprefinerycnt(EQI_SHADOW_SHOES)) >= 15) {
-         bonus bSpeedRate,25;
+         bonus bMoveHaste;
       }
   - Combos:
       - Combo:

+ 5 - 5
db/re/item_db_equip.yml

@@ -29033,7 +29033,7 @@ Body:
       bonus bMaxHPrate,20;
       bonus bMaxSPrate,20;
       bonus bSPrecovRate,15;
-      bonus bSpeedRate,25;
+      bonus bMoveHaste;
       bonus bInt,25;
   - Id: 2411
     AegisName: Grave
@@ -30289,7 +30289,7 @@ Body:
       bonus bMaxHPrate,20;
       bonus bMaxSPrate,20;
       bonus bSPrecovRate,15;
-      bonus bSpeedRate,25;
+      bonus bMoveHaste;
   - Id: 2463
     AegisName: Feral_Boots
     Name: Feral Boots
@@ -129330,9 +129330,9 @@ Body:
       if (.@r >= 7) {
          bonus bDef,15;
          bonus bFlee,15;
+         if (.@r >= 10)
+            bonus bMoveHaste;
       }
-      if (.@r >= 10)
-         bonus bSpeedRate,25;
   - Id: 24440
     AegisName: S_Sonic_Armor
     Name: Sonic Shadow Armor
@@ -134780,7 +134780,7 @@ Body:
          bonus bDef,15;
          bonus bFlee,15;
          if (.@r>=10) {
-            bonus bSpeedRate,25;
+            bonus bMoveHaste;
          }
       }
   - Id: 24733

+ 1 - 1
db/re/item_db_etc.yml

@@ -4468,7 +4468,7 @@ Body:
       BuyingStore: true
       DropEffect: CLIENT
     Script: |
-      bonus bSpeedRate,25;
+      bonus bMoveHaste;
   - Id: 4132
     AegisName: Mistress_Card
     Name: Mistress Card

+ 6 - 3
doc/item_bonus.txt

@@ -157,7 +157,7 @@ bonus bFlee2Rate,n;   			Perfect Dodge + n%
 bonus bPerfectHitRate,n;		On-target impact attack probability n% (only the highest among all is applied)
 bonus bPerfectHitAddRate,n;		On-target impact attack probability + n%
 bonus bSpeedRate,n;   			Movement speed + n% (only the highest among all is applied, won't be stacked with SC_SPEEDUP0, SC_SPEEDUP1)
-bonus bSpeedAddRate,n;			Movement speed + n%
+bonus bSpeedAddRate,n;			Additional Movement speed + n%
 bonus bAspd,n;        			Attack speed + n
 bonus bAspdRate,n;    			Attack speed + n%
 bonus bAtkRange,n;    			Attack range + n
@@ -504,8 +504,11 @@ bonus bNoGemStone;      		Skills requiring Gemstones do not require them
                           		NOTE: Hocus Pocus still requires 1 Yellow Gemstone, Ganbantein requirements not reduced
 bonus bIntravision;     		Always see Hiding and Cloaking players/mobs
 bonus bPerfectHide;     		Hidden/cloaked character is no longer detected by monsters with 'detector' mode
-bonus bRestartFullRecover;	When reviving, HP and SP are fully healed
+bonus bRestartFullRecover;	    When reviving, HP and SP are fully healed
 bonus bClassChange,n;     		Gives a n/100% chance to change the attacked monster's class with normal attack
 bonus bAddStealRate,n;    		Increases success rate of Steal skill by n/100%
-bonus bNoMadoFuel;			Nullify Magic Gear Fuel requirement for skills.
+bonus bNoMadoFuel;			    Nullify Magic Gear Fuel requirement for skills.
 bonus bNoWalkDelay;				Give infinite Endure.
+bonus bMoveHaste;			    Increases movement speed by 25% with EFST_MOVHASTE_INFINITY displayed, 
+                                Used in Moonlight Flower Card and several other items.
+                                The speed given is equivalent to 'bonus bSpeedRate,25'

+ 1 - 1
src/map/map.hpp

@@ -581,7 +581,7 @@ enum _sp {
 	SP_LONG_SP_GAIN_VALUE, SP_LONG_HP_GAIN_VALUE, SP_SHORT_ATK_RATE, SP_MAGIC_SUBSIZE, SP_CRIT_DEF_RATE, // 2093-2097
 	SP_MAGIC_SUBDEF_ELE, SP_REDUCE_DAMAGE_RETURN, SP_ADD_ITEM_SPHEAL_RATE, SP_ADD_ITEMGROUP_SPHEAL_RATE, // 2098-2101
 	SP_WEAPON_SUBSIZE, SP_ABSORB_DMG_MAXHP2, // 2102-2103
-	SP_SP_IGNORE_RES_RACE_RATE, SP_SP_IGNORE_MRES_RACE_RATE, SP_EMATK_HIDDEN, // 2104-2106
+	SP_SP_IGNORE_RES_RACE_RATE, SP_SP_IGNORE_MRES_RACE_RATE, SP_EMATK_HIDDEN, SP_MOVE_HASTE, // 2104-2107
 };
 
 enum _look {

+ 6 - 1
src/map/pc.cpp

@@ -3885,7 +3885,7 @@ void pc_bonus(map_session_data *sd,int32 type,int32 val)
 			if (sd->state.lr_flag != LR_FLAG_ARROW)
 				sd->bonus.speed_rate = min(sd->bonus.speed_rate, -val);
 			break;
-		case SP_SPEED_ADDRATE:	//Stackable increase
+		case SP_SPEED_ADDRATE: //Additional increase
 			if (sd->state.lr_flag != LR_FLAG_ARROW)
 				sd->bonus.speed_add_rate -= val;
 			break;
@@ -4385,6 +4385,10 @@ void pc_bonus(map_session_data *sd,int32 type,int32 val)
 			if (sd->state.lr_flag != LR_FLAG_ARROW)
 				sd->bonus.itemsphealrate2 += val;
 			break;
+		case SP_MOVE_HASTE:
+			if (sd->state.lr_flag != LR_FLAG_ARROW)
+				sd->special_state.move_haste = 1;
+			break;
 		default:
 			if (current_equip_combo_pos > 0) {
 				ShowWarning("pc_bonus: unknown bonus type %d %d in a combo with item #%u\n", type, val, sd->inventory_data[pc_checkequip( sd, current_equip_combo_pos )]->nameid);
@@ -10273,6 +10277,7 @@ int64 pc_readparam(map_session_data* sd,int64 type)
 #endif
 		case SP_CRIT_DEF_RATE: val = sd->bonus.crit_def_rate; break;
 		case SP_ADD_ITEM_SPHEAL_RATE: val = sd->bonus.itemsphealrate2; break;
+		case SP_MOVE_HASTE: val = sd->special_state.move_haste ? 1 : 0; break;
 		default:
 			ShowError("pc_readparam: Attempt to read unknown parameter '%lld'.\n", type);
 			return -1;

+ 1 - 0
src/map/pc.hpp

@@ -474,6 +474,7 @@ public:
 		uint32 bonus_coma : 1;
 		uint32 no_mado_fuel : 1; // Disable Magic_Gear_Fuel consumption [Secret]
 		uint32 no_walk_delay : 1;
+		uint32 move_haste : 1;
 	} special_state;
 	uint32 login_id1, login_id2;
 	uint64 class_;	//This is the internal job ID used by the map server to simplify comparisons/queries/etc. [Skotlex]

+ 1 - 0
src/map/script_constants.hpp

@@ -841,6 +841,7 @@
 	export_constant2("bAddItemSPHealRate", SP_ADD_ITEM_SPHEAL_RATE);
 	export_constant2("bAddItemGroupSPHealRate", SP_ADD_ITEMGROUP_SPHEAL_RATE);
 	export_constant2("bWeaponSubSize", SP_WEAPON_SUBSIZE);
+	export_constant2("bMoveHaste", SP_MOVE_HASTE);
 
 	/* equip indices */
 	export_constant(EQI_COMPOUND_ON);

+ 21 - 5
src/map/status.cpp

@@ -3759,6 +3759,9 @@ int32 status_calc_pc_sub(map_session_data* sd, uint8 opt)
 
 	if (sd->special_state.no_walk_delay)
 		clif_status_load(&sd->bl, EFST_ENDURE, 0);
+	
+	if (sd->special_state.move_haste)
+		clif_status_load(&sd->bl, EFST_MOVHASTE_INFINITY, 0);
 
 	memset(&sd->special_state,0,sizeof(sd->special_state));
 
@@ -4276,6 +4279,9 @@ int32 status_calc_pc_sub(map_session_data* sd, uint8 opt)
 		clif_status_load(&sd->bl, EFST_ENDURE, 1);
 		base_status->mdef++;
 	}
+	
+	if (sd->special_state.move_haste)
+		clif_status_load(&sd->bl, EFST_MOVHASTE_INFINITY, 1);
 
 // ----- CONCENTRATION CALCULATION -----
 	if ((skill = pc_checkskill(sd, NW_GRENADE_MASTERY)) > 0)
@@ -7914,8 +7920,12 @@ static uint16 status_calc_speed(struct block_list *bl, status_change *sc, int32
 				val = max( val, 30 );
 			}
 
-			if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // Permanent item-based speedup
-				val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate );
+			// Permanent item-based speed up
+			if( sd != nullptr && sd->bonus.speed_rate > 0 )
+				val = max( val, sd->bonus.speed_rate );
+			// Permanent item-based additional speed
+			if ( sd != nullptr && sd->bonus.speed_add_rate > 0 )
+				val += sd->bonus.speed_add_rate;
 		}
 		speed_rate += val;
 		val = 0;
@@ -7972,9 +7982,15 @@ static uint16 status_calc_speed(struct block_list *bl, status_change *sc, int32
 		if( sc->getSCE(SC_WILD_WALK) != nullptr )
 			val = max( val, sc->getSCE(SC_WILD_WALK)->val2 );
 
-		// !FIXME: official items use a single bonus for this [ultramage]
-		if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // Permanent item-based speedup
-			val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) );
+		// Hasted status
+		if ( sd != nullptr && sd->special_state.move_haste )
+			val = max( val, 25 );
+		// Permanent item-based speed up
+		if( sd != nullptr && sd->bonus.speed_rate < 0 )
+			val = max( val, -(sd->bonus.speed_rate) );
+		// Permanent item-based additional speed
+		if( sd != nullptr && sd->bonus.speed_add_rate < 0 )
+			val += -(sd->bonus.speed_add_rate);
 
 		speed_rate -= val;