Thirst System added to Code

Want to discuss changes to the UOX3 source code? Got a code-snippet you'd like to post? Anything related to coding/programming goes here!
Post Reply
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Thirst System added to Code

Post by dragon slayer »

after testing it all seems to work correctly. What this does is take the hunger system and make a new system for Thirst So now you can define Thirst and Hunger in a JS , This new functions will give you more roleplay power to the emulator.

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 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),
Find this Line:
const SI08          DEFCHAR_HUNGER              = 6;
Add this:
const SI08          DEFCHAR_THIRST              = 6;
Find this Line:
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)));
                }
            }
        }
    }
}
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);
}
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());
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));
}
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;
}
These users thanked the author dragon slayer for the post:
Xuri
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

Now Lets Add to cChar.h
Find This Line:
    tCHAR_HUNGER,
Add this:
    tCHAR_THIRST,
Find This Line:
        UI16                tamedHungerRate;    // The rate at which hunger decreases when char is tamed
Add This:
        UI16                tamedThirstRate;    // The rate at which thirst decreases when char is tamed
Find This Line:
        UI08                hungerWildChance;   // The chance that the char get's wild when hungry
Add This
        UI08                thirstWildChance;   // The chance that the char get's wild when hungry
Find this Line:
    SI08        hunger;     // Level of hungerness, 6 = full, 0 = "empty"
Add This:
    SI08        thirst;     // Level of Thirstyness, 6 = full, 0 = "empty"
Find This Line:
void        DoHunger( CSocket *mSock );
Add This:
    void        DoThirst(CSocket* mSock);

Find This Line:
    SI08        GetHunger( void ) const;
Add This:
    SI08        GetThirst(void) const;

Find This Line:
    UI16        GetTamedHungerRate( void ) const;
Add This
    UI16        GetTamedThirstRate(void) const;
Find This Line
    UI08        GetTamedHungerWildChance( void ) const;
Add This
    UI08        GetTamedThirstWildChance(void) const;

Find This Line:
    bool        SetHunger( SI08 newValue );
Add This
    bool        SetThirst(SI08 newValue);

Find This Line:
    void        SetTamedHungerRate( UI16 newValue );
Add This:
    void        SetTamedThirstRate(UI16 newValue);

Find This Line
    void        SetTamedHungerWildChance( UI08 newValue );
Add This
    void        SetTamedThirstWildChance(UI08 newValue);

Find This Line
    bool        DecHunger( const SI08 amt = 1 );
Add This
    bool        DecThirst(const SI08 amt = 1);

Find This Line
    bool        WillHunger( void ) const;
Add This
    bool        WillThirst(void) const;

Find This Line
    void        SetHungerStatus( bool newValue );
Add This
    void        SetThirstStatus(bool newValue);
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

cScript.cpp
Find this block of code
OnHungerChange

Add this Block of Code
//o-----------------------------------------------------------------------------------------------o
//| Function    -   bool OnThirstChange( CChar *pChanging, SI08 newStatus )
//o-----------------------------------------------------------------------------------------------o
//| Purpose     -   Triggers for character with event attached when Thirst level changes
//o-----------------------------------------------------------------------------------------------o
bool cScript::OnThirstChange(CChar* pChanging, SI08 newStatus)
{
    if (!ValidateObject(pChanging))
        return false;
    if (!ExistAndVerify(seOnThirstChange, "onThirstChange"))
        return false;

    jsval params[2], rval;
    JSObject* charObj = JSEngine->AcquireObject(IUE_CHAR, pChanging, runTime);
    params[0] = OBJECT_TO_JSVAL(charObj);
    params[1] = INT_TO_JSVAL(newStatus);
    JSBool retVal = JS_CallFunctionName(targContext, targObject, "onThirstChange", 2, params, &rval);
    if (retVal == JS_FALSE)
        SetEventExists(seOnThirstChange, false);

    return (retVal == JS_TRUE);
}
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

cScript.h
Find This Line
    seOnHungerChange,       //  **
Add This Line
    seOnThirstChange,       //  **
Find This Line
    bool        OnHungerChange( CChar *pChanging, SI08 newStatus );
Add This Line
    bool        OnThirstChange(CChar* pChanging, SI08 newStatus);
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

cRaces.cpp
Find this block of code
DoesHunger

Add this Block After that
void cRaces::DoesThirst(RACEID race, bool value)
{
    if (InvalidRace(race))
        return;
    races[race]->DoesThirst(value);
}
bool cRaces::DoesThirst(RACEID race) const
{
    if (InvalidRace(race))
        return 0;
    return races[race]->DoesThirst();
}
Find this Block of Code
SetHungerRate

Add this Block After that
void cRaces::SetThirstRate(RACEID race, UI16 value)
{
    if (InvalidRace(race))
        return;
    races[race]->SetThirstRate(value);
}
UI16 cRaces::GetThirstRate(RACEID race) const
{
    if (InvalidRace(race))
        return 0;
    return races[race]->GetThirstRate();
}
Find This Block of code
SetHungerDamage
Add this after that
void cRaces::SetThirstDamage(RACEID race, SI16 value)
{
    if (InvalidRace(race))
        return;
    races[race]->SetThirstDamage(value);
}
SI16 cRaces::GetThirstDamage(RACEID race) const
{
    if (InvalidRace(race))
        return 0;
    return races[race]->GetThirstDamage();
}
Find this block of code
GetHungerRate

Add this after that
UI16 CRace::GetThirstRate(void) const
{
    return thirstRate;
}
void CRace::SetThirstRate(UI16 newValue)
{
    thirstRate = newValue;
}

Find this block of code
GetHungerDamage

Add this after that
SI16 CRace::GetThirstDamage(void) const
{
    return thirstDamage;
}
void CRace::SetThirstDamage(SI16 newValue)
{
    thirstDamage = newValue;
}

Find this block of code
DoesHunger

Add this block after that
bool CRace::DoesThirst(void) const
{
    return doesThirst;
}
void CRace::DoesThirst(bool newValue)
{
    doesThirst = newValue;
}
Find this code
    DoesHunger( false );
    SetHungerRate( 0 );
    SetHungerDamage( 0 );
Add this after that
    DoesThirst(false);
    SetThirstRate(0);
    SetThirstDamage(0);

Further down find this block of code
    DoesHunger( false );
    SetHungerRate( 0 );
    SetHungerDamage( 0 );

add this after that
    DoesThirst(false);
    SetThirstRate(0);
    SetThirstDamage(0);
Find this code
            case 'S':

Add this after that
            case 't':
            case 'T':
                if (UTag == "THIRST") {// does race suffer from thirst
                    if (data.sectionCount(",") != 0)
                    {
                        SetThirstRate(static_cast<UI16>(data.section(",", 0, 0).stripWhiteSpace().toUShort()));
                        SetThirstDamage(static_cast<SI16>(data.section(",", 1, 1).stripWhiteSpace().toShort()));
                    }
                    else
                    {
                        SetThirstRate(0);
                        SetThirstDamage(0);
                    }
                    if (GetThirstRate() > 0)
                    {
                        DoesThirst(true);
                    }
                    else
                    {
                        DoesThirst(false);
                    }
                }
                break;
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

cRaces.h
Find this Line
    bool            doesHunger;
Add this Line
    bool            doesThirst;

Find this Line
    UI16            hungerRate;
Add this line
    UI16            thirstRate;

Find this Line
    SI16            hungerDamage;
Add this Line
    SI16            thirstDamage;
Find this Line
    UI16            GetHungerRate( void ) const;
Add this Line
    UI16            GetThirstRate(void) const;

Find this Line
    void            SetHungerRate( UI16 newValue );
Add This Line
    void            SetThirstRate(UI16 newValue);

Find this Line
    SI16            GetHungerDamage( void ) const;
Add This Line
    SI16            GetThirstDamage(void) const;

Find This Line
    void            SetHungerDamage( SI16 newValue );
Add This Line
    void            SetThirstDamage(SI16 newValue);

Find This Line
    bool            DoesHunger( void ) const;
Add This Line
    bool            DoesThirst(void) const;

Find This Line
    void            DoesHunger( bool newValue );
Add This Line
    void            DoesThirst(bool newValue);
Find This Line
    bool            DoesHunger( RACEID race ) const;
Add This Line
    bool            DoesThirst(RACEID race) const;

Find this Line
    UI16            GetHungerRate( RACEID race ) const;
Add this Line
    UI16            GetThirstRate(RACEID race) const;

Find this Line
    SI16            GetHungerDamage( RACEID race ) const;
Add This Line
    SI16            GetThirstDamage(RACEID race) const;
Find This Line
    void            DoesHunger( RACEID race, bool value );
Add This Line
    void            DoesThirst(RACEID race, bool value);

Find This Line
    void            SetHungerRate( RACEID race, UI16 value );
Add this line
    void            SetThirstRate(RACEID race, UI16 value);

Find This Line
    void            SetHungerDamage( RACEID race, SI16 value );
Add this line
    void            SetThirstDamage(RACEID race, SI16 value);
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

cServerData.cpp
Find This Line
const UI32 BIT_ITEMSDETECTSPEECH = 47;
Add this line
const UI32 BIT_PETTHIRSTOFFLINE = 48;
Find this Line
regINIValue("MAXPLAYERBANKITEMS", 228);
Add this line
    regINIValue("THIRSTRATE", 229);
    regINIValue("THIRSTDMGVAL", 230);
    regINIValue("PETTHIRSTOFFLINE", 148);
Find this line
    SystemTimer( tSERVER_HUNGERRATE, 6000 );
    HungerDamage( 2 );
Add this Line
    SystemTimer(tSERVER_THIRSTRATE, 6000);
    ThirstDamage(2);
Find this code block
HungerDamage
Add this code block
//o-----------------------------------------------------------------------------------------------o
//| Function    -   SI16 ThirstDamage( void ) const
//|                 void ThirstDamage( SI16 value )
//o-----------------------------------------------------------------------------------------------o
//| Purpose     -   Gets/Sets the damage taken from players being thirst
//o-----------------------------------------------------------------------------------------------o
SI16 CServerData::ThirstDamage(void) const
{
    return thirstdamage;
}
void CServerData::ThirstDamage(SI16 value)
{
    thirstdamage = value;
}

Find this code block
PetHungerOffline
Add this Code block
//o-----------------------------------------------------------------------------------------------o
//| Function    -   bool PetThirstOffline( void ) const
//|                 void PetThirstOffline( bool newVal )
//o-----------------------------------------------------------------------------------------------o
//| Purpose     -   Gets/Sets whether pets should thirst while the player (owner) is offline or not
//o-----------------------------------------------------------------------------------------------o
bool CServerData::PetThirstOffline(void) const
{
    return boolVals.test(BIT_PETTHIRSTOFFLINE);
}
void CServerData::PetThirstOffline(bool newVal)
{
    boolVals.set(BIT_PETTHIRSTOFFLINE, newVal);
}
Find this Code Block
        ofsOutput << '\n' << "[hunger]" << '\n' << "{" << '\n';
        ofsOutput << "HUNGERRATE=" << SystemTimer( tSERVER_HUNGERRATE ) << '\n';
        ofsOutput << "HUNGERDMGVAL=" << HungerDamage() << '\n';
        ofsOutput << "PETHUNGEROFFLINE=" << (PetHungerOffline()?1:0) << '\n';
        ofsOutput << "PETOFFLINETIMEOUT=" << PetOfflineTimeout() << '\n';
        ofsOutput << "}" << '\n';

Add this code Block
        ofsOutput << '\n' << "[thirst]" << '\n' << "{" << '\n';
        ofsOutput << "THIRSTRATE=" << SystemTimer(tSERVER_THIRSTRATE) << '\n';
        ofsOutput << "THIRSTDMGVAL=" << ThirstDamage() << '\n';
        ofsOutput << "PETTHIRSTOFFLINE=" << (PetThirstOffline() ? 1 : 0) << '\n';
        ofsOutput << "}" << '\n';
Find this code
        case 228:   // MAXPLAYERBANKITEMS[0217]
            MaxPlayerBankItems( value.toUShort() );
            break;
Add this code
        case 229:    // THIRSTRATE[0218]
            SystemTimer(tSERVER_THIRSTRATE, value.toUShort());
            break;
        case 230:    // THIRSTDMGVAL[0219]
            ThirstDamage(value.toShort());
            break;
        case 231:    // PETTHIRSTOFFLINE[0220]
            PetThirstOffline((value.toByte() == 1));
            break;
dragon slayer
UOX3 Guru
Posts: 776
Joined: Thu Dec 21, 2006 7:37 am
Has thanked: 4 times
Been thanked: 26 times

Post by dragon slayer »

cServerData.h
Find this Code
    tSERVER_HUNGERRATE,         // Amount of time a player has before his hunger level decreases.
Add this Code
    tSERVER_THIRSTRATE,         // Amount of time a player has before his thirst level decreases.

Find this code
    // Hunger & Food
    SI16        hungerdamage;                   //  Amount of damage applied if hungry and below threshold
Add this code
    // Thirst
    SI16        thirstdamage;                   //  Amount of damage applied if thirst and below threshold
Find this Code
    void        HungerDamage( SI16 value );
    SI16        HungerDamage( void ) const;
Add this Code
    void        ThirstDamage(SI16 value);
    SI16        ThirstDamage(void) const;

Find this Code
    void        PetHungerOffline( bool value );
    bool        PetHungerOffline( void ) const;

Add this Code
    void        PetThirstOffline(bool value);
    bool        PetThirstOffline(void) const;
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

This is great, looks good so far! I like stuff like this which can add to shard customizability. A couple of notes, though:

1) Do you want to do this as a PR on GitHub? It's ok if you don't, in which case I'll integrate the code and commit it on your behalf. But if you'd like, you can fork the UOX3 repo, make your changes based on the develop branch, and make a PR to the UOX3 repo.
Example on how to do this, if you're not familiar: http://www.dasblinkenlichten.com/how-to ... equest-pr/

2) Make sure to base your changes off of the develop branch, not master, and refer to an up-to-date dictionary file when adding new dictionary messages. Currently you have some that use IDs 1973 to 1978, which in the latest dictionary in the develop branch are used by something else. Develop branch is up to 2037 already! :)

3) What exactly are the new dictionary messages?

4) Thirsty characters currently seem to take damage, rather than a hit to their stamina, via the line Damage(thirstDamage). This seems true for both players and pets. Should change this to reduce their stamina instead of inflicting damage.

5) With thirst affecting a character's stamina, there's a risk that a player might run out of stamina and be unable to move. If they don't have a means of quenching their thirst, they might be permanently stuck on the spot. I would set a minimum value (of 1 ) for how much stamina can be drained from someone who's thirsty, just to make sure they can at least always walk (if not run).

6) Some comments in the code that handles thirst still refers to hunger/hungry characters. Should update these for consistency. :)
-= Ho Eyo He Hum =-
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

Just to post an update for this thread - a PR was submitted, and it was merged to the develop branch at https://github.com/UOX3DevTeam/UOX3 after a couple of small tweaks. Thanks, dragon slayer! 🙏🏻
-= Ho Eyo He Hum =-
Post Reply