2019-07-07 20:56:15 +00:00
# include <StdAfx.h>
2018-03-29 17:01:57 -04:00
# include "WeenieObject.h"
# include "Healer.h"
# include "Player.h"
CHealerWeenie : : CHealerWeenie ( )
{
SetName ( " Healer " ) ;
m_Qualities . m_WeenieType = Healer_WeenieType ;
}
CHealerWeenie : : ~ CHealerWeenie ( )
{
}
void CHealerWeenie : : ApplyQualityOverrides ( )
{
}
2018-07-12 14:41:21 -07:00
int CHealerWeenie : : UseWith ( CPlayerWeenie * player , CWeenieObject * with )
2018-03-29 17:01:57 -04:00
{
2018-12-18 03:26:48 +00:00
if ( ! with - > AsPlayer ( ) )
{
player - > NotifyWeenieError ( WERROR_HEAL_PLAYERS_ONLY ) ;
player - > NotifyUseDone ( 0 ) ;
return WERROR_NONE ;
}
2019-01-27 09:13:17 +00:00
if ( player - > IsInPortalSpace ( ) )
{
player - > NotifyUseDone ( 0 ) ;
return WERROR_ACTIONS_LOCKED ;
}
2019-07-07 20:56:15 +00:00
uint32_t healing_skill = 0 ;
2018-03-29 17:01:57 -04:00
if ( ! player - > InqSkill ( HEALING_SKILL , healing_skill , TRUE ) | | ! healing_skill )
{
player - > NotifyWeenieError ( WERROR_HEAL_NOT_TRAINED ) ;
player - > NotifyUseDone ( 0 ) ;
return WERROR_NONE ;
}
2019-07-07 20:56:15 +00:00
uint32_t boostEnum = m_Qualities . GetInt ( BOOSTER_ENUM_INT , 0 ) ;
2018-08-05 19:57:08 -05:00
switch ( boostEnum )
{
case HEALTH_ATTRIBUTE_2ND :
{
if ( with - > GetHealth ( ) = = with - > GetMaxHealth ( ) )
{
2018-12-18 03:26:48 +00:00
player - > NotifyWeenieErrorWithString ( WERROR_HEAL_FULL_HEALTH , with - > GetName ( ) . c_str ( ) ) ;
2018-08-05 19:57:08 -05:00
player - > NotifyUseDone ( 0 ) ;
return WERROR_NONE ;
}
else
break ;
}
case STAMINA_ATTRIBUTE_2ND :
2018-06-16 12:56:46 -05:00
{
2018-08-05 19:57:08 -05:00
if ( with - > GetStamina ( ) = = with - > GetMaxStamina ( ) )
{
2018-12-18 03:26:48 +00:00
player - > NotifyWeenieError ( WERROR_NONE ) ;
2018-08-05 19:57:08 -05:00
player - > NotifyUseDone ( 0 ) ;
return WERROR_NONE ;
}
else
break ;
}
case MANA_ATTRIBUTE_2ND :
{
if ( with - > GetMana ( ) = = with - > GetMaxMana ( ) )
{
2018-12-18 03:26:48 +00:00
player - > NotifyWeenieError ( WERROR_NONE ) ;
2018-08-05 19:57:08 -05:00
player - > NotifyUseDone ( 0 ) ;
return WERROR_NONE ;
}
else
break ;
}
2018-06-16 12:56:46 -05:00
}
2018-03-29 17:01:57 -04:00
CHealerUseEvent * useEvent = new CHealerUseEvent ;
useEvent - > _target_id = with - > GetID ( ) ;
useEvent - > _tool_id = GetID ( ) ;
useEvent - > _max_use_distance = 1.0 ;
2018-12-18 23:01:11 +00:00
useEvent - > _initial_use_position = player - > m_Position ;
2018-03-29 17:01:57 -04:00
player - > ExecuteUseEvent ( useEvent ) ;
return WERROR_NONE ;
}
void CHealerUseEvent : : OnReadyToUse ( )
{
2018-08-04 19:50:47 +00:00
if ( _weenie - > GetStamina ( ) = = 0 )
{
//don't perform healing animation if there's zero stamina
_weenie - > NotifyWeenieError ( WERROR_STAMINA_TOO_LOW ) ;
Cancel ( ) ;
return ;
}
2018-07-12 14:41:21 -07:00
if ( _target_id = = _weenie - > GetID ( ) )
2018-03-29 17:01:57 -04:00
{
2018-10-01 22:52:58 +00:00
_weenie - > DoForcedStopCompletely ( ) ;
ExecuteUseAnimation ( Motion_SkillHealSelf ) ;
2018-03-29 17:01:57 -04:00
}
else
{
2018-10-01 22:52:58 +00:00
_weenie - > DoForcedStopCompletely ( ) ;
2018-03-31 21:50:57 -05:00
ExecuteUseAnimation ( Motion_Woah ) ;
2018-03-29 17:01:57 -04:00
}
}
2019-07-07 20:56:15 +00:00
void CHealerUseEvent : : OnUseAnimSuccess ( uint32_t motion )
2018-03-29 17:01:57 -04:00
{
2018-07-12 14:41:21 -07:00
CWeenieObject * target = GetTarget ( ) ;
CWeenieObject * tool = GetTool ( ) ;
2018-03-29 17:01:57 -04:00
if ( tool & & target & & ! target - > IsDead ( ) & & ! target - > IsInPortalSpace ( ) )
{
2018-12-23 23:16:49 -06:00
if ( _target_id = = _weenie - > GetID ( ) & & _weenie - > m_Position . distance ( _initial_use_position ) > 5.0 ) //Distance check between initial use and now but only if heal was executed on self.
2018-12-18 23:01:11 +00:00
return Cancel ( WERROR_MOVED_TOO_FAR ) ;
2018-03-29 17:01:57 -04:00
int amountHealed = 0 ;
int usesLeft = tool - > InqIntQuality ( STRUCTURE_INT , - 1 ) ;
if ( usesLeft ! = 0 )
{
if ( usesLeft > 0 )
usesLeft - - ;
const char * prefix = " " ;
const char * vitalName = " " ;
2019-07-07 20:56:15 +00:00
uint32_t boost_stat = tool - > InqIntQuality ( BOOSTER_ENUM_INT , 0 ) ;
uint32_t boost_value = tool - > InqIntQuality ( BOOST_VALUE_INT , 0 ) ;
2018-03-29 17:01:57 -04:00
bool success = false ;
switch ( boost_stat )
{
case HEALTH_ATTRIBUTE_2ND :
case STAMINA_ATTRIBUTE_2ND :
case MANA_ATTRIBUTE_2ND :
{
STypeAttribute2nd maxStatType = ( STypeAttribute2nd ) ( boost_stat - 1 ) ;
STypeAttribute2nd statType = ( STypeAttribute2nd ) boost_stat ;
2019-07-07 20:56:15 +00:00
uint32_t statValue = 0 , maxStatValue = 0 ;
2018-03-29 17:01:57 -04:00
target - > m_Qualities . InqAttribute2nd ( statType , statValue , FALSE ) ;
target - > m_Qualities . InqAttribute2nd ( maxStatType , maxStatValue , FALSE ) ;
int missingVital = max ( 0 , ( int ) maxStatValue - ( int ) statValue ) ;
2018-09-13 01:07:33 -05:00
double combat_mod = _weenie - > IsInPeaceMode ( ) ? 1.0 : 1.1 ;
2018-10-02 09:37:21 -05:00
int difficulty = max ( 0 , ( int ) ( ( missingVital * 2 ) * combat_mod ) ) ;
2018-03-29 17:01:57 -04:00
2018-09-13 01:07:33 -05:00
Skill skill ;
2019-07-07 20:56:15 +00:00
uint32_t healing_skill = 0 ;
2018-07-12 14:41:21 -07:00
_weenie - > InqSkill ( HEALING_SKILL , healing_skill , FALSE ) ;
2018-09-13 01:07:33 -05:00
_weenie - > m_Qualities . InqSkill ( HEALING_SKILL , skill ) ;
2019-07-07 20:56:15 +00:00
uint32_t base_skill = healing_skill ;
2018-09-28 14:07:42 -07:00
2018-09-13 22:36:07 +00:00
double sac_mod = skill . _sac = = SPECIALIZED_SKILL_ADVANCEMENT_CLASS ? 1.5 : 1.1 ;
2018-09-13 01:07:33 -05:00
healing_skill = ( healing_skill + boost_value ) * sac_mod ;
2018-09-28 14:07:42 -07:00
success = Random : : RollDice ( 0.0 , 1.0 ) < = GetSkillChance ( healing_skill , difficulty ) ;
if ( success )
2018-09-13 01:07:33 -05:00
{
2018-09-28 17:42:02 -07:00
double heal_min = 0 ;
double heal_max = 0 ;
2018-09-28 14:07:42 -07:00
if ( skill . _sac = = SPECIALIZED_SKILL_ADVANCEMENT_CLASS )
{
2018-09-28 18:47:23 -07:00
heal_min = 0.09 ;
heal_max = 0.28 ;
2018-09-28 14:07:42 -07:00
}
else
{
2018-09-28 18:47:23 -07:00
heal_min = 0.07 ;
heal_max = 0.235 ;
2018-09-28 14:07:42 -07:00
}
2018-03-29 17:01:57 -04:00
2018-09-28 17:42:02 -07:00
double healedVariance = Random : : GenFloat ( heal_min , heal_max ) ;
2018-09-13 01:07:33 -05:00
2018-09-28 14:07:42 -07:00
amountHealed = ( int ) ( base_skill * healedVariance * tool - > InqFloatQuality ( HEALKIT_MOD_FLOAT , 1.0 ) ) ;
if ( Random : : RollDice ( 0.0 , 1.0 ) < = 0.15 )
{
prefix = " expertly " ;
amountHealed * = difficulty / 2 ;
}
2018-09-13 01:07:33 -05:00
2018-09-28 14:07:42 -07:00
if ( amountHealed > missingVital )
amountHealed = missingVital ;
2018-03-29 17:01:57 -04:00
2018-09-28 14:07:42 -07:00
int staminaNecessary = amountHealed / 5 ; //1 point of stamina used for every 5 health healed.
2018-03-29 17:01:57 -04:00
2018-09-28 14:07:42 -07:00
if ( _weenie - > GetStamina ( ) < staminaNecessary )
2018-08-04 19:50:47 +00:00
{
2018-09-28 14:07:42 -07:00
staminaNecessary = _weenie - > GetStamina ( ) ;
amountHealed = staminaNecessary * 5 ;
if ( CPlayerWeenie * pPlayer = _weenie - > AsPlayer ( ) )
{
pPlayer - > SendText ( " You're exhausted! " , LTT_ERROR ) ;
}
2018-08-04 19:50:47 +00:00
}
2018-09-28 14:07:42 -07:00
_weenie - > AdjustStamina ( - staminaNecessary ) ;
2019-07-07 20:56:15 +00:00
uint32_t newStatValue = min ( statValue + amountHealed , maxStatValue ) ;
2018-03-29 17:01:57 -04:00
int statChange = newStatValue - statValue ;
if ( statChange )
{
2018-05-15 00:04:29 -05:00
if ( target - > AsPlayer ( ) & & statType = = HEALTH_ATTRIBUTE_2ND )
{
target - > AdjustHealth ( statChange ) ;
target - > NotifyAttribute2ndStatUpdated ( statType ) ;
}
else
{
target - > m_Qualities . SetAttribute2nd ( statType , newStatValue ) ;
target - > NotifyAttribute2ndStatUpdated ( statType ) ;
}
2018-03-29 17:01:57 -04:00
}
}
switch ( boost_stat )
{
case HEALTH_ATTRIBUTE_2ND : vitalName = " Health " ; break ;
case STAMINA_ATTRIBUTE_2ND : vitalName = " Stamina " ; break ;
case MANA_ATTRIBUTE_2ND : vitalName = " Mana " ; break ;
}
break ;
}
}
amountHealed = max ( 0 , amountHealed ) ;
// heal up
if ( success )
{
2018-07-12 14:41:21 -07:00
if ( _target_id = = _weenie - > GetID ( ) )
2018-03-29 17:01:57 -04:00
{
2018-12-18 03:26:48 +00:00
if ( vitalName = = " Health " )
{
if ( usesLeft > = 0 )
_weenie - > SendText ( csprintf ( " You %sheal yourself for %d %s points. Your %s has %u uses left. " , prefix , amountHealed , vitalName , tool - > GetName ( ) . c_str ( ) , usesLeft ) , LTT_DEFAULT ) ;
else
_weenie - > SendText ( csprintf ( " You %sheal yourself for %d %s points with %s. " , prefix , amountHealed , vitalName , tool - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
}
2018-03-29 17:01:57 -04:00
else
2018-12-18 03:26:48 +00:00
{
if ( usesLeft > = 0 )
_weenie - > SendText ( csprintf ( " You %srecover %d %s points. Your %s has %u uses left. " , prefix , amountHealed , vitalName , tool - > GetName ( ) . c_str ( ) , usesLeft ) , LTT_DEFAULT ) ;
else
_weenie - > SendText ( csprintf ( " You %srecover %d %s points with %s. " , prefix , amountHealed , vitalName , tool - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
}
2018-03-29 17:01:57 -04:00
}
else
{
2018-12-18 03:26:48 +00:00
if ( vitalName = = " Health " )
{
if ( usesLeft > = 0 )
_weenie - > SendText ( csprintf ( " You %sheal %s for %d %s points. Your %s has %u uses left. " , prefix , target - > GetName ( ) . c_str ( ) , amountHealed , vitalName , tool - > GetName ( ) . c_str ( ) , usesLeft ) , LTT_DEFAULT ) ;
else
_weenie - > SendText ( csprintf ( " You %sheal %s for %d %s points with %s. " , prefix , target - > GetName ( ) . c_str ( ) , amountHealed , vitalName , tool - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
2018-05-06 02:05:22 +01:00
2018-12-18 03:26:48 +00:00
target - > SendText ( csprintf ( " %s heals you for %d %s points. " , _weenie - > GetName ( ) . c_str ( ) , amountHealed , vitalName ) , LTT_DEFAULT ) ;
}
else
2018-05-06 02:05:22 +01:00
{
2018-12-18 03:26:48 +00:00
if ( usesLeft > = 0 )
_weenie - > SendText ( csprintf ( " You %srestore %s for %d %s points. Your %s has %u uses left. " , prefix , target - > GetName ( ) . c_str ( ) , amountHealed , vitalName , tool - > GetName ( ) . c_str ( ) , usesLeft ) , LTT_DEFAULT ) ;
else
_weenie - > SendText ( csprintf ( " You %srestore %s for %d %s points with %s. " , prefix , target - > GetName ( ) . c_str ( ) , amountHealed , vitalName , tool - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
target - > SendText ( csprintf ( " %s restores you for %d %s points. " , _weenie - > GetName ( ) . c_str ( ) , amountHealed , vitalName ) , LTT_DEFAULT ) ;
2018-05-06 02:05:22 +01:00
}
2018-12-18 03:26:48 +00:00
2018-05-06 02:05:22 +01:00
}
2018-12-22 01:42:35 -05:00
if ( boost_stat = = HEALTH_ATTRIBUTE_2ND )
{
if ( _weenie - > AsPlayer ( ) )
{
// update the target's health on the healing player asap
( ( CPlayerWeenie * ) _weenie ) - > RefreshTargetHealth ( ) ;
}
}
2018-03-29 17:01:57 -04:00
}
else
{
2018-07-12 14:41:21 -07:00
if ( _target_id = = _weenie - > GetID ( ) )
2018-03-29 17:01:57 -04:00
{
2018-12-18 03:26:48 +00:00
if ( vitalName = = " Health " )
_weenie - > SendText ( csprintf ( " You fail to heal yourself. Your %s has %d uses left. " , tool - > GetName ( ) . c_str ( ) , usesLeft ) , LTT_DEFAULT ) ;
else
_weenie - > SendText ( csprintf ( " You fail to recover any vitals. Your %s has %d uses left. " , tool - > GetName ( ) . c_str ( ) , usesLeft ) , LTT_DEFAULT ) ;
2018-03-29 17:01:57 -04:00
}
else
{
2018-12-18 03:26:48 +00:00
if ( vitalName = = " Health " )
{
_weenie - > SendText ( csprintf ( " You fail to heal %s. Your %s has %d uses left. " , target - > GetName ( ) . c_str ( ) , tool - > GetName ( ) . c_str ( ) , usesLeft ) , LTT_DEFAULT ) ;
target - > SendText ( csprintf ( " %s fails to heal you. " , _weenie - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
}
else
{
_weenie - > SendText ( csprintf ( " You fail to restore any vitals to %s. Your %s has %d uses left. " , target - > GetName ( ) . c_str ( ) , tool - > GetName ( ) . c_str ( ) , usesLeft ) , LTT_DEFAULT ) ;
target - > SendText ( csprintf ( " %s fails to restore any of your vitals. " , _weenie - > GetName ( ) . c_str ( ) ) , LTT_DEFAULT ) ;
}
2018-03-29 17:01:57 -04:00
}
}
tool - > DecrementStackOrStructureNum ( true ) ;
}
}
Done ( ) ;
}