@ -5599,6 +5599,10 @@ public class PlayerCharacter extends AbstractCharacter {
				@@ -5599,6 +5599,10 @@ public class PlayerCharacter extends AbstractCharacter {
					 
			
		
	
		
			
				
					    public  void  resetRegenUpdateTime ( )  {   
			
		
	
		
			
				
					        this . lastUpdateTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					        this . lastStamUpdateTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					        this . timestamps . put ( "LastRegenHealth" ,  System . currentTimeMillis ( ) ) ;   
			
		
	
		
			
				
					        this . timestamps . put ( "LastRegenMana" ,  System . currentTimeMillis ( ) ) ;   
			
		
	
		
			
				
					        this . timestamps . put ( "LastRegenStamina" ,  System . currentTimeMillis ( ) ) ;   
			
		
	
		
			
				
					        this . timestamps . put ( "LastConsumeStamina" ,  System . currentTimeMillis ( ) ) ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    public  float  getCharacterHeight ( )  {   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -5690,211 +5694,6 @@ public class PlayerCharacter extends AbstractCharacter {
				@@ -5690,211 +5694,6 @@ public class PlayerCharacter extends AbstractCharacter {
					 
			
		
	
		
			
				
					        dirtyLock . writeLock ( ) . unlock ( ) ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    public  void  RunRegen ( ) {   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        float  healthRegen  =  0f ;   
			
		
	
		
			
				
					        float  manaRegen  =  0f ;   
			
		
	
		
			
				
					        float  stamRegen  =  0f ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        boolean  updateClient  =  false ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // Early exit if char is dead or disconnected
   
			
		
	
		
			
				
					        if  ( ( this . isAlive ( )  = =  false )   
			
		
	
		
			
				
					                | |  ( this . isActive ( )  = =  false )  | |  this . getLoc ( ) . x  = =  0  & &  this . getLoc ( ) . z  = =  0 )   
			
		
	
		
			
				
					            return ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // Calculate Regen amount from last simulation tick
   
			
		
	
		
			
				
					        switch  ( this . movementState )  {   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					            case  IDLE :   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                healthRegen  =  ( ( this . healthMax  *  MBServerStatics . HEALTH_REGEN_IDLE )  +  MBServerStatics . HEALTH_REGEN_IDLE_STATIC )  *  ( getRegenModifier ( ModType . HealthRecoverRate ) ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                if  ( this . isCasting ( )  | |  this . isItemCasting ( ) )   
			
		
	
		
			
				
					                    healthRegen  * =  . 75f ;   
			
		
	
		
			
				
					                // Characters regen mana when in only walk mode and idle
   
			
		
	
		
			
				
					                if  ( this . walkMode )   
			
		
	
		
			
				
					                    manaRegen  =  ( this . manaMax  *  0 . 01f )  *  getRegenModifier ( ModType . ManaRecoverRate )  *  MBServerStatics . MANA_REGEN_WALK ;   
			
		
	
		
			
				
					                else  {   
			
		
	
		
			
				
					                    manaRegen  =  ( this . manaMax  *  0 . 01f )  *  getRegenModifier ( ModType . ManaRecoverRate )  *  MBServerStatics . MANA_REGEN_IDLE ;   
			
		
	
		
			
				
					                }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                if  ( ! PlayerCharacter . CanBreathe ( this ) )   
			
		
	
		
			
				
					                    stamRegen  =  MBServerStatics . STAMINA_REGEN_SWIM ;   
			
		
	
		
			
				
					                else  if  ( ( ! this . isCasting ( )  & &  ! this . isItemCasting ( ) )  | |  this . lastMovementState . equals ( MovementState . FLYING ) )   
			
		
	
		
			
				
					                    stamRegen  =  MBServerStatics . STAMINA_REGEN_IDLE  *  getRegenModifier ( ModType . StaminaRecoverRate ) ;   
			
		
	
		
			
				
					                else   
			
		
	
		
			
				
					                    stamRegen  =  0 ;   
			
		
	
		
			
				
					                break ;   
			
		
	
		
			
				
					            case  SITTING :   
			
		
	
		
			
				
					                healthRegen  =  ( ( this . healthMax  *  MBServerStatics . HEALTH_REGEN_SIT )  +  MBServerStatics . HEALTH_REGEN_SIT_STATIC )  *  getRegenModifier ( ModType . HealthRecoverRate ) ;   
			
		
	
		
			
				
					                manaRegen  =  ( this . manaMax  *  MBServerStatics . MANA_REGEN_SIT )  *  ( getRegenModifier ( ModType . ManaRecoverRate ) ) ;   
			
		
	
		
			
				
					                stamRegen  =  MBServerStatics . STAMINA_REGEN_SIT  *  getRegenModifier ( ModType . StaminaRecoverRate ) ;   
			
		
	
		
			
				
					                break ;   
			
		
	
		
			
				
					            case  RUNNING :   
			
		
	
		
			
				
					                if  ( this . walkMode  = =  true )  {   
			
		
	
		
			
				
					                    healthRegen  =  ( ( this . healthMax  *  MBServerStatics . HEALTH_REGEN_WALK )  +  MBServerStatics . HEALTH_REGEN_IDLE_STATIC )  *  getRegenModifier ( ModType . HealthRecoverRate ) ;   
			
		
	
		
			
				
					                    manaRegen  =  this . manaMax  *  MBServerStatics . MANA_REGEN_WALK  *  getRegenModifier ( ModType . ManaRecoverRate ) ;   
			
		
	
		
			
				
					                    stamRegen  =  MBServerStatics . STAMINA_REGEN_WALK ;   
			
		
	
		
			
				
					                }  else  {   
			
		
	
		
			
				
					                    healthRegen  =  0 ;   
			
		
	
		
			
				
					                    manaRegen  =  0 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    if  ( this . combat  = =  true )   
			
		
	
		
			
				
					                        stamRegen  =  MBServerStatics . STAMINA_REGEN_RUN_COMBAT ;   
			
		
	
		
			
				
					                    else   
			
		
	
		
			
				
					                        stamRegen  =  MBServerStatics . STAMINA_REGEN_RUN_NONCOMBAT ;   
			
		
	
		
			
				
					                }   
			
		
	
		
			
				
					                break ;   
			
		
	
		
			
				
					            case  FLYING :   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                float  seventyFive  =  this . staminaMax  *  . 75f ;   
			
		
	
		
			
				
					                float  fifty  =  this . staminaMax  *  . 5f ;   
			
		
	
		
			
				
					                float  twentyFive  =  this . staminaMax  *  . 25f ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                if  ( this . getDesiredAltitude ( )  = =  0  & &  this . getAltitude ( )  < =  10 )  {   
			
		
	
		
			
				
					                    if  ( this . isCombat ( ) )   
			
		
	
		
			
				
					                        stamRegen  =  0 ;   
			
		
	
		
			
				
					                    else   
			
		
	
		
			
				
					                        stamRegen  =  MBServerStatics . STAMINA_REGEN_IDLE  *  getRegenModifier ( ModType . StaminaRecoverRate ) ;   
			
		
	
		
			
				
					                }  else  if  ( ! this . useFlyMoveRegen ( ) )  {   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    healthRegen  =  ( ( this . healthMax  *  MBServerStatics . HEALTH_REGEN_IDLE )  +  MBServerStatics . HEALTH_REGEN_IDLE_STATIC )  *  ( getRegenModifier ( ModType . HealthRecoverRate ) ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    if  ( this . isCasting ( )  | |  this . isItemCasting ( ) )   
			
		
	
		
			
				
					                        healthRegen  * =  . 75f ;   
			
		
	
		
			
				
					                    // Characters regen mana when in only walk mode and idle
   
			
		
	
		
			
				
					                    if  ( this . walkMode )   
			
		
	
		
			
				
					                        manaRegen  =  ( this . manaMax  *  MBServerStatics . MANA_REGEN_IDLE  +  ( this . getSpiMod ( )  *  . 015f ) )  *  ( getRegenModifier ( ModType . ManaRecoverRate ) ) ;   
			
		
	
		
			
				
					                    else  if  ( ! this . isCasting ( )  & &  ! this . isItemCasting ( ) )   
			
		
	
		
			
				
					                        manaRegen  =  ( this . manaMax  *  MBServerStatics . MANA_REGEN_IDLE  +  ( this . getSpiMod ( )  *  . 015f ) )  *  ( getRegenModifier ( ModType . ManaRecoverRate ) ) ;   
			
		
	
		
			
				
					                    else   
			
		
	
		
			
				
					                        manaRegen  =  0 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    if  ( ! this . isItemCasting ( )  & &  ! this . isCasting ( )  | |  this . getTakeOffTime ( )  ! =  0 )   
			
		
	
		
			
				
					                        stamRegen  =  MBServerStatics . STAMINA_REGEN_FLY_IDLE ;   
			
		
	
		
			
				
					                    else   
			
		
	
		
			
				
					                        stamRegen  =  - 1f ;   
			
		
	
		
			
				
					                }  else  if  ( this . walkMode  = =  true )  {   
			
		
	
		
			
				
					                    healthRegen  =  ( ( this . healthMax  *  MBServerStatics . HEALTH_REGEN_WALK )  +  MBServerStatics . HEALTH_REGEN_IDLE_STATIC )  *  getRegenModifier ( ModType . HealthRecoverRate ) ;   
			
		
	
		
			
				
					                    manaRegen  =  ( ( this . manaMax  *  MBServerStatics . MANA_REGEN_WALK )  +  ( this . getSpiMod ( )  *  . 015f ) )  *  ( getRegenModifier ( ModType . ManaRecoverRate ) ) ;   
			
		
	
		
			
				
					                    stamRegen  =  MBServerStatics . STAMINA_REGEN_FLY_WALK ;   
			
		
	
		
			
				
					                }  else  {   
			
		
	
		
			
				
					                    healthRegen  =  0 ;   
			
		
	
		
			
				
					                    manaRegen  =  0 ;   
			
		
	
		
			
				
					                    if  ( this . isCombat ( ) )   
			
		
	
		
			
				
					                        stamRegen  =  MBServerStatics . STAMINA_REGEN_FLY_RUN_COMBAT ;   
			
		
	
		
			
				
					                    else   
			
		
	
		
			
				
					                        stamRegen  =  MBServerStatics . STAMINA_REGEN_FLY_RUN ;   
			
		
	
		
			
				
					                }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                float  oldStamina  =  this . stamina . get ( ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                if  ( FastMath . between ( oldStamina ,  0 ,  twentyFive )  & &  ! this . wasTripped25 )  {   
			
		
	
		
			
				
					                    updateClient  =  true ;   
			
		
	
		
			
				
					                    this . wasTripped25  =  true ;   
			
		
	
		
			
				
					                    this . wasTripped50  =  false ;   
			
		
	
		
			
				
					                    this . wasTripped75  =  false ;   
			
		
	
		
			
				
					                }  else  if  ( FastMath . between ( oldStamina ,  twentyFive ,  fifty )  & &  ! this . wasTripped50 )  {   
			
		
	
		
			
				
					                    updateClient  =  true ;   
			
		
	
		
			
				
					                    this . wasTripped25  =  false ;   
			
		
	
		
			
				
					                    this . wasTripped50  =  true ;   
			
		
	
		
			
				
					                    this . wasTripped75  =  false ;   
			
		
	
		
			
				
					                }  else  if  ( FastMath . between ( oldStamina ,  fifty ,  seventyFive )  & &  ! this . wasTripped75 )  {   
			
		
	
		
			
				
					                    updateClient  =  true ;   
			
		
	
		
			
				
					                    this . wasTripped25  =  false ;   
			
		
	
		
			
				
					                    this . wasTripped50  =  false ;   
			
		
	
		
			
				
					                    this . wasTripped75  =  true ;   
			
		
	
		
			
				
					                }   
			
		
	
		
			
				
					                break ;   
			
		
	
		
			
				
					            case  SWIMMING :   
			
		
	
		
			
				
					                if  ( this . walkMode  = =  true )  {   
			
		
	
		
			
				
					                    healthRegen  =  ( ( this . healthMax  *  MBServerStatics . HEALTH_REGEN_WALK )  +  MBServerStatics . HEALTH_REGEN_IDLE_STATIC )  *  getRegenModifier ( ModType . HealthRecoverRate ) ;   
			
		
	
		
			
				
					                    manaRegen  =  ( ( this . manaMax  *  MBServerStatics . MANA_REGEN_WALK )  +  ( this . getSpiMod ( )  *  . 015f ) )  *  ( getRegenModifier ( ModType . ManaRecoverRate ) ) ;   
			
		
	
		
			
				
					                    stamRegen  =  MBServerStatics . STAMINA_REGEN_SWIM ;   
			
		
	
		
			
				
					                }  else  {   
			
		
	
		
			
				
					                    healthRegen  =  0 ;   
			
		
	
		
			
				
					                    manaRegen  =  0 ;   
			
		
	
		
			
				
					                    stamRegen  =  MBServerStatics . STAMINA_REGEN_SWIM ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					                    if  ( this . combat  = =  true )   
			
		
	
		
			
				
					                        stamRegen  + =  MBServerStatics . STAMINA_REGEN_RUN_COMBAT ;   
			
		
	
		
			
				
					                    else   
			
		
	
		
			
				
					                        stamRegen  + =  MBServerStatics . STAMINA_REGEN_RUN_NONCOMBAT ;   
			
		
	
		
			
				
					                }   
			
		
	
		
			
				
					                break ;   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // Are we drowning?
   
			
		
	
		
			
				
					        if  ( ( this . getStamina ( )  < =  0 )   
			
		
	
		
			
				
					                & &  ( PlayerCharacter . CanBreathe ( this )  = =  false ) )   
			
		
	
		
			
				
					            healthRegen  =  ( this . healthMax  *  - . 03f ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // Multiple regen values by current deltaTime
   
			
		
	
		
			
				
					        //     Logger.info("", healthRegen + "");
   
			
		
	
		
			
				
					        long  currentTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					        Long  regenTime ;   
			
		
	
		
			
				
					        if ( this . timestamps . containsKey ( "LastRegen" ) )   
			
		
	
		
			
				
					            regenTime  =  this . timestamps . get ( "LastRegen" ) ;   
			
		
	
		
			
				
					        else   
			
		
	
		
			
				
					            regenTime  =  currentTime ;   
			
		
	
		
			
				
					        float  secondsPassed  =  ( currentTime  -  regenTime )  /  1000f ;   
			
		
	
		
			
				
					        healthRegen  * =  secondsPassed ;   
			
		
	
		
			
				
					        manaRegen  * =  secondsPassed ;   
			
		
	
		
			
				
					        stamRegen  * =  secondsPassed ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        this . timestamps . put ( "LastRegen" , currentTime ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        //ChatManager.chatSystemInfo(this,"Mana: " + this.mana.get());
   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        boolean  workedHealth  =  false ;   
			
		
	
		
			
				
					        boolean  workedMana  =  false ;   
			
		
	
		
			
				
					        boolean  workedStamina  =  false ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        float  old ,  mod ;   
			
		
	
		
			
				
					        while  ( ! workedHealth  | |  ! workedMana  | |  ! workedStamina )  {   
			
		
	
		
			
				
					            if  ( ! this . isAlive ( )  | |  ! this . isActive ( ) )   
			
		
	
		
			
				
					                return ;   
			
		
	
		
			
				
					            if  ( ! workedHealth )  {   
			
		
	
		
			
				
					                old  =  this . health . get ( ) ;   
			
		
	
		
			
				
					                mod  =  old  +  healthRegen ;   
			
		
	
		
			
				
					                if  ( mod  >  this . healthMax )   
			
		
	
		
			
				
					                    mod  =  healthMax ;   
			
		
	
		
			
				
					                else  if  ( mod  < =  0 )  {   
			
		
	
		
			
				
					                    if  ( this . isAlive . compareAndSet ( true ,  false ) )   
			
		
	
		
			
				
					                        killCharacter ( "Water" ) ;   
			
		
	
		
			
				
					                    return ;   
			
		
	
		
			
				
					                }   
			
		
	
		
			
				
					                workedHealth  =  this . health . compareAndSet ( old ,  mod ) ;   
			
		
	
		
			
				
					            }   
			
		
	
		
			
				
					            if  ( ! workedStamina )  {   
			
		
	
		
			
				
					                old  =  this . stamina . get ( ) ;   
			
		
	
		
			
				
					                mod  =  old  +  stamRegen ;   
			
		
	
		
			
				
					                if  ( mod  >  this . staminaMax )   
			
		
	
		
			
				
					                    mod  =  staminaMax ;   
			
		
	
		
			
				
					                else  if  ( mod  <  0 )   
			
		
	
		
			
				
					                    mod  =  0 ;   
			
		
	
		
			
				
					                workedStamina  =  this . stamina . compareAndSet ( old ,  mod ) ;   
			
		
	
		
			
				
					            }   
			
		
	
		
			
				
					            if  ( ! workedMana )  {   
			
		
	
		
			
				
					                old  =  this . mana . get ( ) ;   
			
		
	
		
			
				
					                mod  =  old  +  manaRegen ;   
			
		
	
		
			
				
					                if  ( mod  >  this . manaMax )   
			
		
	
		
			
				
					                    mod  =  manaMax ;   
			
		
	
		
			
				
					                else  if  ( mod  <  0 )   
			
		
	
		
			
				
					                    mod  =  0 ;   
			
		
	
		
			
				
					                workedMana  =  this . mana . compareAndSet ( old ,  mod ) ;   
			
		
	
		
			
				
					            }   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        if  ( updateClient )   
			
		
	
		
			
				
					            this . syncClient ( ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        // Reset this char's frame time.
   
			
		
	
		
			
				
					        this . lastUpdateTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					        this . lastStamUpdateTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    public  static  float  getRegenRate ( PlayerCharacter  player ,  ModType  type ) {   
			
		
	
		
			
				
					        float  regenRate  =  player . getRegenModifier ( type ) ;   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -6064,4 +5863,156 @@ public class PlayerCharacter extends AbstractCharacter {
				@@ -6064,4 +5863,156 @@ public class PlayerCharacter extends AbstractCharacter {
					 
			
		
	
		
			
				
					            }   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    public  void  doRegen ( ) {   
			
		
	
		
			
				
					        if  ( this . updateLock . writeLock ( ) . tryLock ( ) )  {   
			
		
	
		
			
				
					            try  {   
			
		
	
		
			
				
					                regenerateHealth ( ) ;   
			
		
	
		
			
				
					                regenerateMana ( ) ;   
			
		
	
		
			
				
					                regenerateStamina ( ) ;   
			
		
	
		
			
				
					                consumeStamina ( ) ;   
			
		
	
		
			
				
					            }  catch  ( Exception  e )  {   
			
		
	
		
			
				
					                Logger . error ( e ) ;   
			
		
	
		
			
				
					            }  finally  {   
			
		
	
		
			
				
					                this . updateLock . writeLock ( ) . unlock ( ) ;   
			
		
	
		
			
				
					            }   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    public  void  regenerateHealth ( ) {   
			
		
	
		
			
				
					        Long  regenTime ;   
			
		
	
		
			
				
					        Long  currentTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					        regenTime  =  this . timestamps . getOrDefault ( "LastRegenHealth" ,  currentTime ) ;   
			
		
	
		
			
				
					        float  secondsPassed  =  ( currentTime  -  regenTime )  /  1000f ;   
			
		
	
		
			
				
					        float  onePercent  =  this . healthMax  *  0 . 01f ;   
			
		
	
		
			
				
					        float  rate  =  RecoveryType . getRecoveryType ( this ) . healthRate ;   
			
		
	
		
			
				
					        rate  * =  this . getRegenModifier ( ModType . HealthRecoverRate ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        float  healthRegenerated  =  onePercent  *  secondsPassed  *  rate ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        boolean  workedHealth  =  false ;   
			
		
	
		
			
				
					        float  old , mod ;   
			
		
	
		
			
				
					        while ( ! workedHealth )  {   
			
		
	
		
			
				
					            old  =  this . health . get ( ) ;   
			
		
	
		
			
				
					            mod  =  old  +  healthRegenerated ;   
			
		
	
		
			
				
					            if  ( mod  >  this . healthMax )   
			
		
	
		
			
				
					                mod  =  healthMax ;   
			
		
	
		
			
				
					            else  if  ( mod  < =  0 )  {   
			
		
	
		
			
				
					                if  ( this . isAlive . compareAndSet ( true ,  false ) )   
			
		
	
		
			
				
					                    killCharacter ( "Water" ) ;   
			
		
	
		
			
				
					                return ;   
			
		
	
		
			
				
					            }   
			
		
	
		
			
				
					            workedHealth  =  this . health . compareAndSet ( old ,  mod ) ;   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        this . timestamps . put ( "LastRegenHealth" , currentTime ) ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					    public  void  regenerateMana ( ) {   
			
		
	
		
			
				
					        Long  regenTime ;   
			
		
	
		
			
				
					        Long  currentTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					        regenTime  =  this . timestamps . getOrDefault ( "LastRegenMana" ,  currentTime ) ;   
			
		
	
		
			
				
					        float  secondsPassed  =  ( currentTime  -  regenTime )  /  1000f ;   
			
		
	
		
			
				
					        float  onePercent  =  this . manaMax  *  0 . 01f ;   
			
		
	
		
			
				
					        float  rate  =  RecoveryType . getRecoveryType ( this ) . manaRate ;   
			
		
	
		
			
				
					        rate  * =  this . getRegenModifier ( ModType . ManaRecoverRate ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        float  manaRegenerated  =  onePercent  *  secondsPassed  *  rate ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        boolean  workedMana  =  false ;   
			
		
	
		
			
				
					        float  old , mod ;   
			
		
	
		
			
				
					        while ( ! workedMana )  {   
			
		
	
		
			
				
					            old  =  this . mana . get ( ) ;   
			
		
	
		
			
				
					            mod  =  old  +  manaRegenerated ;   
			
		
	
		
			
				
					            if  ( mod  >  this . manaMax )   
			
		
	
		
			
				
					                mod  =  manaMax ;   
			
		
	
		
			
				
					            else  if  ( mod  <  0 )   
			
		
	
		
			
				
					                mod  =  0 ;   
			
		
	
		
			
				
					            workedMana  =  this . mana . compareAndSet ( old ,  mod ) ;   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        this . timestamps . put ( "LastRegenMana" , currentTime ) ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					    public  void  regenerateStamina ( ) {   
			
		
	
		
			
				
					        Long  regenTime ;   
			
		
	
		
			
				
					        Long  currentTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					        regenTime  =  this . timestamps . getOrDefault ( "LastRegenStamina" ,  currentTime ) ;   
			
		
	
		
			
				
					        float  secondsPassed  =  ( currentTime  -  regenTime )  /  1000f ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        float  rate  =  RecoveryType . getRecoveryType ( this ) . staminaRate ;   
			
		
	
		
			
				
					        rate  * =  this . getRegenModifier ( ModType . StaminaRecoverRate ) ;  // Adjust rate with modifiers
   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        float  staminaRegenerated  =  secondsPassed  /  rate ;  // Stamina regenerates 1 point per `rate` seconds
   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        boolean  workedStamina  =  false ;   
			
		
	
		
			
				
					        float  old ,  mod ;   
			
		
	
		
			
				
					        while  ( ! workedStamina )  {   
			
		
	
		
			
				
					            old  =  this . stamina . get ( ) ;   
			
		
	
		
			
				
					            mod  =  old  +  staminaRegenerated ;   
			
		
	
		
			
				
					            if  ( mod  >  this . staminaMax )   
			
		
	
		
			
				
					                mod  =  staminaMax ;   
			
		
	
		
			
				
					            else  if  ( mod  <  0 )   
			
		
	
		
			
				
					                mod  =  0 ;   
			
		
	
		
			
				
					            workedStamina  =  this . stamina . compareAndSet ( old ,  mod ) ;   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        this . timestamps . put ( "LastRegenStamina" ,  currentTime ) ;   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					    public  void  consumeStamina ( ) {   
			
		
	
		
			
				
					        Long  regenTime ;   
			
		
	
		
			
				
					        Long  currentTime  =  System . currentTimeMillis ( ) ;   
			
		
	
		
			
				
					        regenTime  =  this . timestamps . getOrDefault ( "LastConsumeStamina" ,  currentTime ) ;   
			
		
	
		
			
				
					        float  secondsPassed  =  ( currentTime  -  regenTime )  /  1000f ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        float  consumption ;   
			
		
	
		
			
				
					        if ( ! this . isMoving ( )  & &  ! this . isFlying ( ) )   
			
		
	
		
			
				
					            return ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        if ( ! this . combat ) {   
			
		
	
		
			
				
					            consumption  =  0 . 4f  *  secondsPassed ;   
			
		
	
		
			
				
					        } else {   
			
		
	
		
			
				
					            consumption  =  0 . 65f  *  secondsPassed ;   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					        if ( ! this . canBreathe  | |  this . isFlying ( ) )   
			
		
	
		
			
				
					            consumption  * =  2 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        boolean  workedStamina  =  false ;   
			
		
	
		
			
				
					        float  old , mod ;   
			
		
	
		
			
				
					        while  ( ! workedStamina )  {   
			
		
	
		
			
				
					            old  =  this . stamina . get ( ) ;   
			
		
	
		
			
				
					            mod  =  old  -  consumption ;   
			
		
	
		
			
				
					            if  ( mod  < =  0 )   
			
		
	
		
			
				
					                mod  =  0 ;   
			
		
	
		
			
				
					            workedStamina  =  this . stamina . compareAndSet ( old ,  mod ) ;   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    enum  RecoveryType {   
			
		
	
		
			
				
					        //Values for health and mana are in terms of the number of seconds it takes to recover 1% of max pool
   
			
		
	
		
			
				
					        //Values for stamina are in terms of the number of seconds it takes to recover 1 point
   
			
		
	
		
			
				
					        RESTING ( 3 . 0f , 1 . 2f , 0 . 5f ) ,  //sitting
   
			
		
	
		
			
				
					        IDLING ( 15 . 0f , 6 . 0f , 5 . 0f ) ,  //standing not moving
   
			
		
	
		
			
				
					        WALKING ( 20 . 0f , 8 . 0f , 0 . 0f ) ,  // moving in walk mode
   
			
		
	
		
			
				
					        RUNNING ( 0 . 0f , 0 . 0f , 0 . 0f ) ;  // moving in run mode
   
			
		
	
		
			
				
					        public  float  healthRate ;   
			
		
	
		
			
				
					        public  float  manaRate ;   
			
		
	
		
			
				
					        public  float  staminaRate ;   
			
		
	
		
			
				
					        RecoveryType ( float  health ,  float  mana ,  float  stamina )  {   
			
		
	
		
			
				
					            this . healthRate  =  health ;   
			
		
	
		
			
				
					            this . manaRate  =  mana ;   
			
		
	
		
			
				
					            this . staminaRate  =  stamina ;   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					        public  static  RecoveryType  getRecoveryType ( PlayerCharacter  pc ) {   
			
		
	
		
			
				
					            if  ( pc . isMoving ( ) )  {   
			
		
	
		
			
				
					                if ( pc . walkMode ) {   
			
		
	
		
			
				
					                    return  RecoveryType . WALKING ;   
			
		
	
		
			
				
					                } else {   
			
		
	
		
			
				
					                    return  RecoveryType . RUNNING ;   
			
		
	
		
			
				
					                }   
			
		
	
		
			
				
					            } else  if ( pc . isSit ( ) ) {   
			
		
	
		
			
				
					                return  RecoveryType . RESTING ;   
			
		
	
		
			
				
					            } else {   
			
		
	
		
			
				
					                return  RecoveryType . IDLING ;   
			
		
	
		
			
				
					            }   
			
		
	
		
			
				
					        }   
			
		
	
		
			
				
					    }   
			
		
	
		
			
				
					}