Lets start by adding the code to cChars.cpp
// Bitmask bits
Find this line:
const UI32 BIT_EVADE = 29; // This property is not saved
add this:
const UI32 BIT_WILLTHIRST = 30;
Find this line:
const UI32 BIT_EVADE = 29; // This property is not saved
add this:
const UI32 BIT_WILLTHIRST = 30;
Find this Line:
const UI16 DEFNPC_TAMEDHUNGERRATE = 0;
Add this:
const UI16 DEFNPC_TAMEDTHIRSTRATE = 0;
Find this line:
const UI08 DEFNPC_HUNGERWILDCHANCE = 0;
Add this:
const UI08 DEFNPC_THIRSTWILDCHANCE = 0;
const UI16 DEFNPC_TAMEDHUNGERRATE = 0;
Add this:
const UI16 DEFNPC_TAMEDTHIRSTRATE = 0;
Find this line:
const UI08 DEFNPC_HUNGERWILDCHANCE = 0;
Add this:
const UI08 DEFNPC_THIRSTWILDCHANCE = 0;
Find this line:
tamedHungerRate( DEFNPC_TAMEDHUNGERRATE ),
add this:
tamedThirstRate(DEFNPC_TAMEDTHIRSTRATE),
Find this Line:
hungerWildChance( DEFNPC_HUNGERWILDCHANCE ),
Add this:
thirstWildChance(DEFNPC_THIRSTWILDCHANCE),
tamedHungerRate( DEFNPC_TAMEDHUNGERRATE ),
add this:
tamedThirstRate(DEFNPC_TAMEDTHIRSTRATE),
Find this Line:
hungerWildChance( DEFNPC_HUNGERWILDCHANCE ),
Add this:
thirstWildChance(DEFNPC_THIRSTWILDCHANCE),
Find this Line:
const SI08 DEFCHAR_HUNGER = 6;
Add this:
const SI08 DEFCHAR_THIRST = 6;
const SI08 DEFCHAR_HUNGER = 6;
Add this:
const SI08 DEFCHAR_THIRST = 6;
Find this Line:
hunger( DEFCHAR_HUNGER ),
Add this:
thirst(DEFCHAR_THIRST),
hunger( DEFCHAR_HUNGER ),
Add this:
thirst(DEFCHAR_THIRST),
Find this Code Block
void CChar::DoHunger( CSocket *mSock )
After that Code Block Add all this
//o-----------------------------------------------------------------------------------------------o
//| Function - SI08 GetThirst( void ) const
//| bool SetThirst( SI08 newValue )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Get/Set Thirst level of the character
//o-----------------------------------------------------------------------------------------------o
SI08 CChar::GetThirst(void) const
{
return thirst;
}
bool CChar::SetThirst(SI08 newValue)
{
bool JSEventUsed = false;
thirst = newValue;
const UI16 ThirstTrig = GetScriptTrigger();
cScript* toExecute = JSMapping->GetScript(ThirstTrig);
if (toExecute != NULL)
JSEventUsed = toExecute->OnThirstChange((this), thirst);
return JSEventUsed;
}
//o-----------------------------------------------------------------------------------------------o
//| Function - void DoThirst()
//| Date - 6. June, 2021
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Calculate Thirst level of the character and do all related effects.
//o-----------------------------------------------------------------------------------------------o
void CChar::DoThirst(CSocket* mSock)
{
if (!IsDead() && !IsInvulnerable()) // No need to do anything on dead or invulnerable chars
{
UI16 thirstRate;
SI16 thirstDamage;
if (!IsNpc() && mSock != NULL) // Do Hunger for player chars
{
if (WillThirst() && GetCommandLevel() == CL_PLAYER)
{
if (GetTimer(tCHAR_HUNGER) <= cwmWorldState->GetUICurrentTime() || cwmWorldState->GetOverflow())
{
if (Races->DoesHunger(GetRace())) // prefer the hunger settings frome the race
{
thirstRate = Races->GetThirstRate(GetRace());
thirstDamage = Races->GetThirstDamage(GetRace());
}
else // use the global values if there is no race setting
{
thirstRate = cwmWorldState->ServerData()->SystemTimer(tSERVER_HUNGERRATE);
thirstDamage = cwmWorldState->ServerData()->ThirstDamage();
}
if (GetThirst() > 0)
{
bool doThirstMessage = !DecThirst();
if (doThirstMessage)
{
switch (GetThirst())
{
default:
case 6: break;
case 5: mSock->sysmessage(1973); break;
case 4: mSock->sysmessage(1974); break;
case 3: mSock->sysmessage(1975); break;
case 2: mSock->sysmessage(1976); break;
case 1: mSock->sysmessage(1977); break;
case 0: mSock->sysmessage(1978); break;
}
}
}
else if (GetStamina() > 0 && thirstDamage > 0)
{
mSock->sysmessage(1979);
Damage(thirstDamage);
if (GetStamina() <= 0)
mSock->sysmessage(1980);
}
SetTimer(tCHAR_THIRST, BuildTimeValue(static_cast<R32>(thirstRate)));
}
}
}
else if (IsNpc() && !IsTamed() && Races->DoesThirst(GetRace()))
{
if (WillThirst() && !GetMounted() && !GetStabled())
{
if (GetTimer(tCHAR_THIRST) <= cwmWorldState->GetUICurrentTime() || cwmWorldState->GetOverflow())
{
thirstRate = Races->GetHungerRate(GetRace());
thirstDamage = Races->GetHungerDamage(GetRace());
if (GetThirst() > 0)
DecThirst();
else if (GetStamina() > 0 && thirstDamage > 0)
Damage(thirstDamage);
SetTimer(tCHAR_THIRST, BuildTimeValue(static_cast<R32>(thirstRate)));
}
}
}
else if (IsTamed() && GetTamedThirstRate() > 0)
{
if (WillThirst() && !GetMounted() && !GetStabled())
{
if (cwmWorldState->ServerData()->PetHungerOffline() == false)
{
CChar* owner = GetOwnerObj();
if (!ValidateObject(owner))
return;
if (!isOnline((*owner)))
return;
}
if (GetTimer(tCHAR_HUNGER) <= cwmWorldState->GetUICurrentTime() || cwmWorldState->GetOverflow())
{
thirstRate = GetTamedThirstRate();
if (GetThirst() > 0)
DecThirst();
else if ((UI08)RandomNum(0, 100) <= GetTamedThirstWildChance())
{
SetOwner(NULL);
SetThirst(6);
}
SetTimer(tCHAR_THIRST, BuildTimeValue(static_cast<R32>(thirstRate)));
}
}
}
}
}
void CChar::DoHunger( CSocket *mSock )
After that Code Block Add all this
//o-----------------------------------------------------------------------------------------------o
//| Function - SI08 GetThirst( void ) const
//| bool SetThirst( SI08 newValue )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Get/Set Thirst level of the character
//o-----------------------------------------------------------------------------------------------o
SI08 CChar::GetThirst(void) const
{
return thirst;
}
bool CChar::SetThirst(SI08 newValue)
{
bool JSEventUsed = false;
thirst = newValue;
const UI16 ThirstTrig = GetScriptTrigger();
cScript* toExecute = JSMapping->GetScript(ThirstTrig);
if (toExecute != NULL)
JSEventUsed = toExecute->OnThirstChange((this), thirst);
return JSEventUsed;
}
//o-----------------------------------------------------------------------------------------------o
//| Function - void DoThirst()
//| Date - 6. June, 2021
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Calculate Thirst level of the character and do all related effects.
//o-----------------------------------------------------------------------------------------------o
void CChar::DoThirst(CSocket* mSock)
{
if (!IsDead() && !IsInvulnerable()) // No need to do anything on dead or invulnerable chars
{
UI16 thirstRate;
SI16 thirstDamage;
if (!IsNpc() && mSock != NULL) // Do Hunger for player chars
{
if (WillThirst() && GetCommandLevel() == CL_PLAYER)
{
if (GetTimer(tCHAR_HUNGER) <= cwmWorldState->GetUICurrentTime() || cwmWorldState->GetOverflow())
{
if (Races->DoesHunger(GetRace())) // prefer the hunger settings frome the race
{
thirstRate = Races->GetThirstRate(GetRace());
thirstDamage = Races->GetThirstDamage(GetRace());
}
else // use the global values if there is no race setting
{
thirstRate = cwmWorldState->ServerData()->SystemTimer(tSERVER_HUNGERRATE);
thirstDamage = cwmWorldState->ServerData()->ThirstDamage();
}
if (GetThirst() > 0)
{
bool doThirstMessage = !DecThirst();
if (doThirstMessage)
{
switch (GetThirst())
{
default:
case 6: break;
case 5: mSock->sysmessage(1973); break;
case 4: mSock->sysmessage(1974); break;
case 3: mSock->sysmessage(1975); break;
case 2: mSock->sysmessage(1976); break;
case 1: mSock->sysmessage(1977); break;
case 0: mSock->sysmessage(1978); break;
}
}
}
else if (GetStamina() > 0 && thirstDamage > 0)
{
mSock->sysmessage(1979);
Damage(thirstDamage);
if (GetStamina() <= 0)
mSock->sysmessage(1980);
}
SetTimer(tCHAR_THIRST, BuildTimeValue(static_cast<R32>(thirstRate)));
}
}
}
else if (IsNpc() && !IsTamed() && Races->DoesThirst(GetRace()))
{
if (WillThirst() && !GetMounted() && !GetStabled())
{
if (GetTimer(tCHAR_THIRST) <= cwmWorldState->GetUICurrentTime() || cwmWorldState->GetOverflow())
{
thirstRate = Races->GetHungerRate(GetRace());
thirstDamage = Races->GetHungerDamage(GetRace());
if (GetThirst() > 0)
DecThirst();
else if (GetStamina() > 0 && thirstDamage > 0)
Damage(thirstDamage);
SetTimer(tCHAR_THIRST, BuildTimeValue(static_cast<R32>(thirstRate)));
}
}
}
else if (IsTamed() && GetTamedThirstRate() > 0)
{
if (WillThirst() && !GetMounted() && !GetStabled())
{
if (cwmWorldState->ServerData()->PetHungerOffline() == false)
{
CChar* owner = GetOwnerObj();
if (!ValidateObject(owner))
return;
if (!isOnline((*owner)))
return;
}
if (GetTimer(tCHAR_HUNGER) <= cwmWorldState->GetUICurrentTime() || cwmWorldState->GetOverflow())
{
thirstRate = GetTamedThirstRate();
if (GetThirst() > 0)
DecThirst();
else if ((UI08)RandomNum(0, 100) <= GetTamedThirstWildChance())
{
SetOwner(NULL);
SetThirst(6);
}
SetTimer(tCHAR_THIRST, BuildTimeValue(static_cast<R32>(thirstRate)));
}
}
}
}
}
Find this Code Block
WillHunger
Add this Code Block
//o-----------------------------------------------------------------------------------------------o
//| Function - bool WillThirst( void ) const
//| void SetThirstStatus( bool newValue )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Returns/Sets whether the character will get thirst
//o-----------------------------------------------------------------------------------------------o
bool CChar::WillThirst(void) const
{
return bools.test(BIT_WILLTHIRST);
}
void CChar::SetThirstStatus(bool newValue)
{
bools.set(BIT_WILLTHIRST, newValue);
}
WillHunger
Add this Code Block
//o-----------------------------------------------------------------------------------------------o
//| Function - bool WillThirst( void ) const
//| void SetThirstStatus( bool newValue )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Returns/Sets whether the character will get thirst
//o-----------------------------------------------------------------------------------------------o
bool CChar::WillThirst(void) const
{
return bools.test(BIT_WILLTHIRST);
}
void CChar::SetThirstStatus(bool newValue)
{
bools.set(BIT_WILLTHIRST, newValue);
}
Find this Line:
target->SetHunger( hunger );
Add this:
target->SetThirst(thirst);
Find This Line:
target->SetTamedHungerRate( GetTamedHungerRate() );
Add This:
target->SetTamedThirstRate(GetTamedThirstRate());
Find This Line:
target->SetTamedHungerWildChance( GetTamedHungerWildChance() );
Add This:
target->SetTamedThirstWildChance(GetTamedThirstWildChance());
target->SetHunger( hunger );
Add this:
target->SetThirst(thirst);
Find This Line:
target->SetTamedHungerRate( GetTamedHungerRate() );
Add This:
target->SetTamedThirstRate(GetTamedThirstRate());
Find This Line:
target->SetTamedHungerWildChance( GetTamedHungerWildChance() );
Add This:
target->SetTamedThirstWildChance(GetTamedThirstWildChance());
Find this Code Block
DecHunger
Add this Block After
//o-----------------------------------------------------------------------------------------------o
//| Function - bool DecThirst( const SI08 amt )
//| Date - 6 June 2021
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Decrements the character's thirst
//o-----------------------------------------------------------------------------------------------o
bool CChar::DecThirst(const SI08 amt)
{
return SetThirst((SI08)(GetThirst() - amt));
}
DecHunger
Add this Block After
//o-----------------------------------------------------------------------------------------------o
//| Function - bool DecThirst( const SI08 amt )
//| Date - 6 June 2021
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Decrements the character's thirst
//o-----------------------------------------------------------------------------------------------o
bool CChar::DecThirst(const SI08 amt)
{
return SetThirst((SI08)(GetThirst() - amt));
}
Find this Code Block
GetTamedHungerRate
Add this Block After
//o-----------------------------------------------------------------------------------------------o
//| Function - UI16 GetTamedThirstRate( void ) const
//| void SetTamedThirstRate( UI16 newValue )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Get/Set the rate at which a pet Thirst
//o-----------------------------------------------------------------------------------------------o
UI16 CChar::GetTamedThirstRate(void) const
{
UI16 retVal = DEFNPC_TAMEDTHIRSTRATE;
if (IsValidNPC())
retVal = mNPC->tamedHungerRate;
return retVal;
}
void CChar::SetTamedThirstRate(UI16 newValue)
{
if (!IsValidNPC())
{
if (DEFNPC_TAMEDTHIRSTRATE != newValue)
CreateNPC();
}
if (IsValidNPC())
mNPC->tamedThirstRate = newValue;
}
Find this code block
GetTamedHungerWildChance
Add this Block After
//o-----------------------------------------------------------------------------------------------o
//| Function - UI08 GetTamedThirstWildChance( void ) const
//| void SetTamedThirstWildChance( UI08 newValue )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Gets/Sets chance for a thirst pet to go wild
//o-----------------------------------------------------------------------------------------------o
UI08 CChar::GetTamedThirstWildChance(void) const
{
UI08 retVal = DEFNPC_THIRSTWILDCHANCE;
if (IsValidNPC())
retVal = mNPC->thirstWildChance;
return retVal;
}
void CChar::SetTamedThirstWildChance(UI08 newValue)
{
if (!IsValidNPC())
{
if (DEFNPC_THIRSTWILDCHANCE != newValue)
CreateNPC();
}
if (IsValidNPC())
mNPC->thirstWildChance = newValue;
}
GetTamedHungerRate
Add this Block After
//o-----------------------------------------------------------------------------------------------o
//| Function - UI16 GetTamedThirstRate( void ) const
//| void SetTamedThirstRate( UI16 newValue )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Get/Set the rate at which a pet Thirst
//o-----------------------------------------------------------------------------------------------o
UI16 CChar::GetTamedThirstRate(void) const
{
UI16 retVal = DEFNPC_TAMEDTHIRSTRATE;
if (IsValidNPC())
retVal = mNPC->tamedHungerRate;
return retVal;
}
void CChar::SetTamedThirstRate(UI16 newValue)
{
if (!IsValidNPC())
{
if (DEFNPC_TAMEDTHIRSTRATE != newValue)
CreateNPC();
}
if (IsValidNPC())
mNPC->tamedThirstRate = newValue;
}
Find this code block
GetTamedHungerWildChance
Add this Block After
//o-----------------------------------------------------------------------------------------------o
//| Function - UI08 GetTamedThirstWildChance( void ) const
//| void SetTamedThirstWildChance( UI08 newValue )
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Gets/Sets chance for a thirst pet to go wild
//o-----------------------------------------------------------------------------------------------o
UI08 CChar::GetTamedThirstWildChance(void) const
{
UI08 retVal = DEFNPC_THIRSTWILDCHANCE;
if (IsValidNPC())
retVal = mNPC->thirstWildChance;
return retVal;
}
void CChar::SetTamedThirstWildChance(UI08 newValue)
{
if (!IsValidNPC())
{
if (DEFNPC_THIRSTWILDCHANCE != newValue)
CreateNPC();
}
if (IsValidNPC())
mNPC->thirstWildChance = newValue;
}