QHealth
Want to alter the health of a player? Then this is the tutorial for you. It’s quite short, because it is based on my QHealth mutator, which is also very small.
QHealth does two things. It lets players start with 125% health, and slowly takes down your health if you have more than 100%. This gives freshly spawned players a little more protection so that they can find some killing gear.
This tutorial not only covers the basic function of the mutator, but also shows a common programming error and its solution, which you might want to be aware of.
Originally written on 21-jan-2000
Assumptions
I assume you have read the Simpe Notifier Mod tutorial, and you have downloaded & examined the QHealth mutator.
The Tutorial
QHealth does two things. It lets players start with 125% health, and slowly takes down your health if you have more than 100%.
Starting with more health
This one is easy. Three lines will do the trick:
function ModifyPlayer(PlayerPawn Other) {
Other.Health=125;
}
That’s all! ModifyPlayer
is called at the server side every time a player (re)spawns. The Other
argument refers to the player being respawned. I guess you get the point.
Slowly dropping the health
var config float SpeedFactor;
var float HealthTime;
function Tick(float DeltaTime) {
local Pawn P;
Super.Tick(DeltaTime);
HealthTime += SpeedFactor*DeltaTime;
if (HealthTime<1.0) return;
for (P=Level.PawnList; P!=None; P=P.NextPawn) {
if (P.Health > 100)
P.Health -= int(HealthTime);
}
HealthTime -= int(HealthTime);
}
The Tick
function is called as many times as possible, with DeltaTime
being
the time between this call and the previous. Let’s assume it is called 10 times
every second, so DeltaTime
will be 0.1. The health of a player is stored as
an integer, so if we would simply substract DeltaTime
from the health, you’ll
get this effect:
- Health is 130%
- Substract 0.1, so the result is 129.9%
- This is stored as an integer, so remove all the digits after the decimal point.
- Health is now 129%
As you can see, the health would be reduced by 1% ten times per second! This is not wat we want, so I used a different approach.
I stored the passed time in a float variable called HealthTime
. After 1
second, this variable will be exactly 1. The mutator does nothing until a
second or more has passed. After that second, the integer part of HealthTime is
substracted from the health of each player healthier than 100%, and is
substracted from itself as well.
This way, we have bridged the gap between floating point and integer variables.
One glitch might show up if the server is really slow. If Tick
is called less
than one time per second, the integer part of HealthTime
might be 2 or more.
Let’s assume it is 3 (REALLY slow server!), and a player is at 101% health.
Because now 3 is substracted, the player will end up with 98% instead of 100%
health.
Please note: I am talking about the speed the server runs UScript. This is entirely different from network/connection speeds, ping times etc.
I wanted the speed with which the health drops to be configurable, so I created
a SpeedFactor
. It is stored in QHealth.ini
because of the config
keywords.
Network issues
I haven’t tested the code on a networked game yet. However, since the code runs at the server side, and health is also stored at the server, things should be ok. The health is replicated to the client in the Engine.Pawn class.