Originally Posted by
AccadaccA
local.player.health (tried both with and without the period, "local.player health") but what was to follow that?
a) +5
b) "+5"
c) (+5)
d) = local.player.health +5
Adding onto the player's existing health means you need to get what they already have. This can be done a couple of ways:
// local.player.health will become the value already stored in local.player.health plus 5
local.player.health = local.player.health + 5
// does the same as above but is nicer
local.player.health += 5
Then via command:
local.player health (local.player.health + 5)
The above wouldn't work for you though, as setting the 'health' of an entity ALSO sets the 'max_health'. This means that if you set the health to '50' the max_health will also become '50', meaning the health bar on the HUD will be full, because they have 100% of their health (50 out of 50).
That's why they also included a 'healthonly' command:
local.player healthonly (local.player.health + 5)
That one does for you. 'heal', the one you were using, is nice because it does the 'local.player.health + 5' calculation for you in the engine, but 'healthonly' is better because it appears to provide more accurate results and you don't need to convert the value (dividing by 100) before passing it in.
Originally Posted by
AccadaccA
I was initially "thinking" (that's dangerous for the local community and more work for you lol) to have one use per player or a timed cool-off period between that player's heals.
You can code it as to give yourself a choice of timed, per session, or single use.
It gets a little trickier if you want to restrict triggers for specific players, as you need some method of storing those restrictions, preferably on the players themselves...
...which is what I went with .
Now, you'll notice how 'local.' has been changed to 'group.' in some instances, and this means that those variables will be accessible from all the threads we are calling, meaning we don't need to worry about manually passing data between the threads.
Also, the triggers in Radiant now have extra properties. setthread will be the same ('Heal' in this example), but now it will come with a '$mode' and '#time' on top of the existing '#hp'. There are 3 modes: 'session' (only once per player per map), 'timed' (has a 'recharge' time before it can be used by the same player again) and 'single' (used once and then removed). Note dollar ($) symbol before 'mode', this is because we are passing in a string. $ for strings and # for integers. '#time' is number of seconds e.g. key: #time value: 10 will be ten seconds. If your $mode is set to 'time' and you don't include a #time then it defaults to 30 seconds.
Heal:
group.player = parm.other
group.trigger = self
// we don't want the player to use healing spot if they already have full health
// or if they are restricted (temporarily or otherwise)
if (waitthread Restricted || group.player.health == group.player.max_health) end
local.hp = group.trigger.hp // grab the hp property
local.mode = group.trigger.mode // grab the mode
local.time = group.trigger.time // grab the time
// do the heal
group.player healthonly (group.player.health + group.trigger.hp)
// play sound (comment this out if you don't want health sound, or include your own)
group.trigger playsound med_kit
switch (local.mode)
{
// if mode is session or timed then restrict this healing spot for this player
case "session":
case "timed":
thread RestrictHealingSpot; break
case "single":
default:
group.trigger remove; break // remove the trigger as this is a single use trigger
}
end
RestrictHealingSpot:
if !(group.player.restricted_healing_spots)
{
// this is the first healing spot to be restricted so make index start at 1
group.player.restricted_healing_spots[1] = group.trigger
}
else
{
// grab number of existing healing spot restrictions
local.existing_restrictions = group.player.restricted_healing_spots.size
// grab the position at which the new restriction will reside
local.new_restriction_pos = local.existing_restrictions + 1
// now set the restriction by placing the restricted healing trigger inside this new array position
group.player.restricted_healing_spots[local.new_restriction_pos] = group.trigger
}
if (group.trigger.mode == "timed")
{
// if there is no time property, then default will be 30 seconds
if !(group.trigger.time) group.trigger.time = 30
// start the timer
thread RechargeTimer
}
end
RechargeTimer:
// set the time that the player can use this again
local.recharge_time = level.time + group.trigger.time
// wait until we have reached the rechard time
while (group.player && local.recharge_time > level.time)
{
wait 1
}
// if player is still around, then remove their restriction from this healing spot
if (group.player)
{
thread RemoveRestriction
}
end
RemoveRestriction:
// grab number of existing restrictions
local.restrictions = group.player.restricted_healing_spots.size
// grab the restricted healing spot
local.healing_spot = group.trigger
// loop over all the restrictions
for (local.i = 1; local.i <= local.restrictions; local.i++)
{
// if we have found the restriction we want to remove
if (group.player.restricted_healing_spots[local.i] == local.healing_spot)
{
// if there are any restrictions to the right in the array we want to move them all down to fill in this empty space
if (group.player.restricted_healing_spots[local.i + 1])
{
// this will update the array without the targeted restriction (restriction thus removed)
thread ResortRestrictionArray local.i
}
else
{
// there aren't anymore restrictions to the right in the array, so just remove it here
group.player.restricted_healing_spots[local.i] = NIL
}
break // we found and sorted the restriction, so leave the for loop
}
}
end
ResortRestrictionArray local.index:
// grab the old array we want to change
local.old_array = group.player.restricted_healing_spots
// use a temporary 'new' array that we can use to write over the old array
local.new_array[1] = NIL
// this is the indexing the new array will use (starting at 1)
local.j = 1
// loop over the old array
for (local.i = 1; local.i <= local.old_array.size; local.i++)
{
// add all the restrictions to the new array EXCEPT for the restriction we want to remove
if (local.i != local.index)
{
local.new_array[local.j] = local.old_array[local.i]
local.j++
}
}
// now write over the old array, meaning only valid restrictions are remaining
group.player.restricted_healing_spots = local.new_array
end
// what this does is return either '1' or '0' (true or false)
Restricted:
local.healing_spots = group.player.restricted_healing_spots.size
if (local.healing_spots > 0)
{
for (local.i = 1; local.i <= local.healing_spots; local.i++)
{
if (group.trigger == group.player.restricted_healing_spots[local.i])
{
end 1 // return true as this healing spot for this player is currently restricted
}
}
}
end 0 // return false as this healing spot for this player is not restricted
You can use any type of trigger with this code, not just trigger_use.
I tested this myself, but you'll probably want to keep an eye out for any bugs I've missed, especially when multiple players are in a server.
I've tried to include useful comments. If you have any queries, let me know.