Healing system

Got something on your mind about the project? This is the correct place for that.


Forum rules

This forum is for feature requests, content changes additions, anything not a Bug in the software.
Please report all bugs on the Support Forums

Post Reply
aomas
Newly Registered User
Posts: 6
Joined: 26 Jun 2011, 20:06

Healing system

Post by aomas »

I'm rather new to TMW, but am liking the game so far :).

I'm curious why the characters can heal when they are not moving, even in combat, but not whilst running around? I think this should be changed so that the heal-rate for moving be equal to, or greater, than the heal-rate during combat. Is there some reason against doing this that I'm not understanding?
User avatar
yubabax116
Warrior
Warrior
Posts: 268
Joined: 05 Apr 2011, 21:20
Location: Elsewhere

Re: Healing system

Post by yubabax116 »

Im pretty sure if you have inma you can move while healing at the same time, maybe you have the magic #lum and is why you cannot run while healing. ;)
▬▬▬▬▬▬▬▬▬▬▬ஜ۩۞۩ஜ▬▬▬▬▬▬▬▬▬▬▬▬▬
♩ ♪ ♫ ♬ ♭ ♮ ❤Quiet And Enj0:00Y The  Music ❤ ♩ ♪ ♫ ♬ ♭
Yubaba
Chicka-Maria
▬▬▬▬▬▬▬▬▬▬▬ஜ۩۞۩ஜ▬▬▬▬▬▬▬▬▬▬▬▬▬
aomas
Newly Registered User
Posts: 6
Joined: 26 Jun 2011, 20:06

Re: Healing system

Post by aomas »

Sorry, my post was confusing and unclear.

I'm talking about how you slowly regenerate health over time if you are standing still. If you are moving around, you don't appear to regen health - but if you are in the middle of a fight, as long as you are standing still, you regen health.

I'm not talking about using healing spells (#lum or #inma) or using potions/items for healing.
User avatar
o11c
Grand Knight
Grand Knight
Posts: 2262
Joined: 20 Feb 2011, 21:09
Location: ^ ^

Re: Healing system

Post by o11c »

The relevant code is:

Code: Select all

static int pc_hpheal(MapSessionData *sd)
{
    int a;

    nullpo_ret(sd);

    a = natural_heal_diff_tick;
    if (pc_issit(sd))
        a += a;

    return a;
}

static int pc_natural_heal_hp(MapSessionData *sd)
{
    int bhp;
    int inc_num, bonus, hp_flag;

    nullpo_ret(sd);

    if (pc_checkoverhp(sd))
    {
        sd->hp_sub = sd->inchealhptick = 0;
        return 0;
    }

    bhp = sd->status.hp;
    hp_flag = 0;

    if (sd->walktimer == NULL)
    {
        inc_num = pc_hpheal(sd);
        sd->hp_sub += inc_num;
        sd->inchealhptick += natural_heal_diff_tick;
    }
    else if (hp_flag)
    {
        inc_num = pc_hpheal(sd);
        sd->hp_sub += inc_num;
        sd->inchealhptick = 0;
    }
    else
    {
        sd->hp_sub = sd->inchealhptick = 0;
        return 0;
    }

    if (sd->hp_sub >= battle_config.natural_healhp_interval)
    {
        bonus = sd->nhealhp;
        if (hp_flag)
        {
            bonus >>= 2;
            if (bonus <= 0)
                bonus = 1;
        }
        while (sd->hp_sub >= battle_config.natural_healhp_interval)
        {
            sd->hp_sub -= battle_config.natural_healhp_interval;
            if (sd->status.hp + bonus <= sd->status.max_hp)
                sd->status.hp += bonus;
            else
            {
                sd->status.hp = sd->status.max_hp;
                sd->hp_sub = sd->inchealhptick = 0;
            }
        }
    }
    if (bhp != sd->status.hp)
        clif_updatestatus(sd, SP_HP);

    if (sd->nshealhp > 0)
    {
        if (sd->inchealhptick >= battle_config.natural_heal_skill_interval
            && sd->status.hp < sd->status.max_hp)
        {
            bonus = sd->nshealhp;
            while (sd->inchealhptick >=
                   battle_config.natural_heal_skill_interval)
            {
                sd->inchealhptick -=
                    battle_config.natural_heal_skill_interval;
                if (sd->status.hp + bonus <= sd->status.max_hp)
                    sd->status.hp += bonus;
                else
                {
                    bonus = sd->status.max_hp - sd->status.hp;
                    sd->status.hp = sd->status.max_hp;
                    sd->hp_sub = sd->inchealhptick = 0;
                }
            }
        }
    }
    else
        sd->inchealhptick = 0;

    return 0;
}
Specifically,

Code: Select all

if (sd->walktimer == NULL)
Note that healing is done in discrete quantities, you can heal at normal rate if you only walk a step at a time, right after you regained some health, then stop again.

Also note that the effective healing rate is doubled if you are sitting.
Former programmer for the TMWA server.
aomas
Newly Registered User
Posts: 6
Joined: 26 Jun 2011, 20:06

Re: Healing system

Post by aomas »

Thanks for the code snippets o11c.

My question, from a game-play point of view, is this: Why would a weary adventurer gain HP while fighting spiders, slimes, wisps, etc. and NOT gain HP while taking a leisurely stroll through the Woodlands?

My question from a code point of view then, I guess, would be: Why even use that

Code: Select all

if (sd->walktimer == NULL)
check at all? Why not just make

Code: Select all

sd->hp_sub += inc_num
the starting condition for all the other tests? (I haven't looked through the code enough to know which MapSessionData attributes correspond to what, but hopefully the point I'm trying to make is clear...)
User avatar
yubabax116
Warrior
Warrior
Posts: 268
Joined: 05 Apr 2011, 21:20
Location: Elsewhere

Re: Healing system

Post by yubabax116 »

Because when you fight against creatures your standing in one spot.
you can always heal while walking when you use items like water.
▬▬▬▬▬▬▬▬▬▬▬ஜ۩۞۩ஜ▬▬▬▬▬▬▬▬▬▬▬▬▬
♩ ♪ ♫ ♬ ♭ ♮ ❤Quiet And Enj0:00Y The  Music ❤ ♩ ♪ ♫ ♬ ♭
Yubaba
Chicka-Maria
▬▬▬▬▬▬▬▬▬▬▬ஜ۩۞۩ஜ▬▬▬▬▬▬▬▬▬▬▬▬▬
aomas
Newly Registered User
Posts: 6
Joined: 26 Jun 2011, 20:06

Re: Healing system

Post by aomas »

I understand that, and the code. I don't understand why that particular choice was made.

It just seems counter-intuitive to me that one is more rested (and hence regenerating HP) while standing still but fighting than one is while walking around. If I'm the only one who thinks this way, then I guess I need to change my intuition :?
Post Reply