Author Topic: Trying to make a health regeneration script  (Read 1443 times)

All it does is when a player takes damage, it only adds 1 health, it doesn't regenerate no matter what health the player has.
Here's the code:
Code: [Select]
package HealthBar
{
    function gameConnection::onClientEnterGame(%this)
    {
        parent::onClientEnterGame(%this);
        %this.HealthRegenerationBar();
    }

    function gameConnection::onClientLeaveGame(%this)
    {
        cancel(%this.HealthRegenerationBar);
        parent::onClientLeaveGame(%this);
    }
};
activatepackage(HealthBar);

package HealthRegeneration
{
function Player::Damage(%this, %projectile, %position, %damage, %type)
{
parent::damage(%this, %projectile, %position, %damage, %type);
%this.HealthRegenerationBar();
}
};
activatepackage(HealthRegeneration);

function gameConnection::HealthRegenerationBar(%this)
{
%health = %this.player.getDatablock().maxDamage - %this.player.getDamageLevel();
if(%health <= 99 && %health >= 60)
{
%health += 1;
}
else
if(%health <= 59 && %health >= 20)
{
%health += 0.8;
}
else
if(%health <= 19)
{
%health += 0.5;
}
commandToClient(%this,'BottomPrint',"Health: "@%health);
%this.schedule(200,"HealthRegenerationBar");
}

As you can see, I'm not a good coder.
« Last Edit: August 30, 2012, 10:46:04 PM by tkepahama »

in the package, your using %this.healthRegenerationBar(); which is calling it on the player not the client, so you have to do %this.client.healthregenerationbar();
also, your actual health wont be effected by this.

Your scheduled loop looks fine to me, maybe I'm missing something because I just woke up. What I did notice is that you weren't calling %client.player.setDamageLevel(%health); so you weren't actually changing their health.

in the package, your using %this.healthRegenerationBar(); which is calling it on the player not the client, so you have to do %this.client.healthregenerationbar();
also, your actual health wont be effected by this.
Nah, you're mistaken. It both calls it and recalls it on the client, then grabs the variables from the player. He has that part right.

Your scheduled loop looks fine to me, maybe I'm missing something because I just woke up. What I did notice is that you weren't calling %client.player.setDamageLevel(%health); so you weren't actually changing their health.
Nah, you're mistaken. It both calls it and recalls it on the client, then grabs the variables from the player. He has that part right.
in the Player::damage he calls %this.healthregenerationbar(); %this is a player object, not a gameconnection object. He will have to do %this.client because Player::HealthRegeneratioBar doesn't exist.

in the Player::damage he calls %this.healthregenerationbar(); %this is a player object, not a gameconnection object. He will have to do %this.client because Player::HealthRegeneratioBar doesn't exist.
True but he shouldn't even be calling it at that point because it calls it when they join the game and continues calling it until they leave.

In addition to what the other's have said, just calling the health regen function once onClientEnterGame should be plenty, you don't need to do it every time the take damage.
Also, doing it that way, it looks like since there's no cancel, everytime you take damage, it'll add a new loop running simultaneously with the others; you'll start regenerating extremely fast, and eventually it'll just lag the server.


Also, not really an issue, but you don't need two packages; you can just combine them into one.

I did all of what you guys said, doesn't work.  It doesn't regenerate the players health, but the bottomprint flickers.   I tested it different times to each different posts, almost same results.

And it spams errors that it can't find functions "getDamageLevel", "getDataBlock", & "setDamageLevel".


I did all of what you guys said, doesn't work.  It doesn't regenerate the players health, but the bottomprint flickers.   I tested it different times to each different posts, almost same results.

And it spams errors that it can't find functions "getDamageLevel", "getDataBlock", & "setDamageLevel".
Is it spamming that it can't find object '0' attempting to call the above functions?
If so, that's because the client has no player, such as if they're loading or dead.

Also, with the OP code, if the player ever has between 60 and 59 or between 20 and 19 health, the function will stop working until the health is changed from that.

Lastly, I'm unsure if it really matters but I think the proper usage of else/if is
Code: [Select]
if(%blah && %rah)
{
   dostuff();
}
else if(!%rah)
{
  doOtherStuff();
}
In other words, else and if should be on the same line.

Oh wait. The bottomprint may be flickering because you're forgetting to use an argument for how long the bottomprint should last in seconds. It should be the next argument, right after the actual message.

Lastly, I'm unsure if it really matters but I think the proper usage of else/if is
In other words, else and if should be on the same line.

Oh wait. The bottomprint may be flickering because you're forgetting to use an argument for how long the bottomprint should last in seconds. It should be the next argument, right after the actual message.
The else if format doesn't matter. You're quite literally using the else from the first if, so it's not a special structure line if or else, it's just an else and an if.

Second, bottomprint lasts indefinitely without a length defined in seconds.

Post your current code
Code: [Select]
package HealthRegeneration
{
    function gameConnection::onClientEnterGame(%this)
    {
        parent::onClientEnterGame(%this);
        %this.client.HealthRegenerationBar();
    }

    function gameConnection::onClientLeaveGame(%this)
    {
        cancel(%this.client.HealthRegenerationBar);
        parent::onClientLeaveGame(%this);
    }
};
activatepackage(HealthRegeneration);

function gameConnection::HealthRegenerationBar(%this)
{
%health = %this.player.getDatablock().maxDamage - %this.player.getDamageLevel();
if(%health <= 99 && %health >= 60)
{
%health += 1;
}
else
if(%health <= 59 && %health >= 20)
{
%health += 0.8;
}
else
if(%health <= 19)
{
%health += 0.5;
}
commandToClient(%this,'BottomPrint',"Health: "@%health);
%this.schedule(200,"HealthRegenerationBar");
}
I seen a post that I had to switch the %this.HealthRegenerationBar(); to %this.client.HealthRegenerationBar();

Is it spamming that it can't find object '0' attempting to call the above functions?
If so, that's because the client has no player, such as if they're loading or dead.

Also, with the OP code, if the player ever has between 60 and 59 or between 20 and 19 health, the function will stop working until the health is changed from that.

Lastly, I'm unsure if it really matters but I think the proper usage of else/if is
Code: [Select]
if(%blah && %rah)
{
   dostuff();
}
else if(!%rah)
{
  doOtherStuff();
}
In other words, else and if should be on the same line.

Oh wait. The bottomprint may be flickering because you're forgetting to use an argument for how long the bottomprint should last in seconds. It should be the next argument, right after the actual message.

And yes but there is a player object.
And I'll try adding that.  *EDIT: I didn't think that really mattered.
« Last Edit: August 31, 2012, 09:55:48 PM by tkepahama »

I seen a post that I had to switch the %this.HealthRegenerationBar(); to %this.client.HealthRegenerationBar();
No, that was only in the Player::Damage function.
The others should be %this.healthRegenerationBar(); because the object you're calling it on is already a client
Also, make the following changes to the healthRegenerationBar function:

- Add cancel(%this.healthRegenerationTick); to the beginning
- Change the schedule call to %this.healthRegenerationTick = %this.schedule(200,"HealthRegenerationBar");

These two are good practice for any sort of ticking function; it prevents more than one concurrent loop from running

- Also, enclose the rest of the code (everything before and after the schedule and cancel function calls) inside an if(isObject(%this.player)) { ..... } block
« Last Edit: August 31, 2012, 10:10:17 PM by Headcrab Zombie »

No, that was only in the Player::Damage function.
The others should be %this.healthRegenerationBar(); because the object you're calling it on is already a client
Also, make the following changes to the healthRegenerationBar function:

- Add cancel(%this.healthRegenerationTick); to the beginning
- Change the schedule call to %this.healthRegenerationTick = %this.schedule(200,"HealthRegenerationBar");

These two are good practice for any sort of ticking function; it prevents more than one concurrent loop from running

- Also, enclose the rest of the code (everything before and after the schedule and cancel function calls) inside an if(isObject(%this.player)) { ..... } block
I took out the Player::Damage function because to me it was useless, the previous posts said to just take out the %this.HealthRegenerationBar(); because it would cause many loops and then in turn would be lagging the server.
I also did what you said but the bottomprint still flickers and the health doesn't regenerate.

But there are no errors in the console...

Oh, yes:
What I did notice is that you weren't calling %client.player.setDamageLevel(%health); so you weren't actually changing their health.

Add %this.player.setDataLevel(%health); %this.player.setDamageLevel(%health); right before (or after, it doesn't really matter) the bottom print

Also, is the bottomprint displaying what the health should be?
« Last Edit: August 31, 2012, 10:27:06 PM by Headcrab Zombie »

Oh, yes:
Add %this.player.setDataLevel(%health); right before (or after, it doesn't really matter) the bottom print

Also, is the bottomprint displaying what the health should be?
Yeah, it's displaying the player's health, just not adding any to it after the player takes damage.