User:Nexii Malthus/Object-based health
This is pretty much as simple as it gets. No damage adjustment, just processing final damage. We initialise with a set amount of health which other scripts can read via llGetHealth. The presence of the final_damage event marks this as a DAMAGEABLE object for sensors and collisions.
For object-based health the script needs to manually manage it's own health, applying the final damage to the health amount and setting the objects health. If the health reaches 0 or below during the damage processing, it should be considered dead and stop further processing.
Because objects don't generate death events, whether the on_death or the system generated combat log messages, we have to handle that aspect ourselves. A community proposals is to send a synthetic OBJECT_DEATH event into the combat channel.
<syntaxhighlight lang="lsl2"> default {
state_entry() { llSetLinkPrimitiveParamsFast(LINK_THIS, [ PRIM_HEALTH, 300.0, PRIM_TEXT, "300/300", <0,1,0>, 1 ]); } final_damage(integer count) { float health = llGetHealth(llGetKey()); integer deadlyDamage = -1; integer index; for(index = 0; index < count; ++index) { list damage = llDetectedDamage(index); float amount = llList2Float(damage, 0); health -= amount; // Check which damage dealt a deadly blow and break the loop if(health <= 0) { health = 0; deadlyDamage = index; index = count; } // Prevent overhealing else if(health > 300.0) health = 300.0; } // Update the scripted health and set a useful hovertext llSetLinkPrimitiveParamsFast(LINK_THIS, [ PRIM_HEALTH, health, PRIM_TEXT, (string)llRound(health) + "/300", <0,1,0>, 1 ]); if(health == 0) { // Generate synthetic object death event as per https://wiki.secondlife.com/wiki/Talk:Combat_Log#Damageable_Object_Deaths vector sourcePos = llDetectedPos(deadlyDamage); vector targetPos = llGetPos(); llRegionSay(COMBAT_CHANNEL, llList2Json(JSON_ARRAY, [ llList2Json(JSON_OBJECT, [ "event", "OBJECT_DEATH", "owner", llDetectedOwner(deadlyDamage), "rezzer", llDetectedRezzer(deadlyDamage), "source", llDetectedKey(deadlyDamage), "source_pos", llList2Json(JSON_ARRAY, [sourcePos.x, sourcePos.y, sourcePos.z]), "target", llGetKey(), "target_pos", llList2Json(JSON_ARRAY, [targetPos.x, targetPos.y, targetPos.z]), "type", llList2Integer(llDetectedDamage(deadlyDamage), 1) ]) ])); state dead; } }
}
state dead {
state_entry() { // We are dead, jim llSetText("dead", <1,0,0>, 1); }
} </syntaxhighlight>