Difference between revisions of "User:Nexii Malthus/Object-based health"

From Second Life Wiki
Jump to navigation Jump to search
m
Line 45: Line 45:
         {
         {
             // Generate synthetic object death event as per https://wiki.secondlife.com/wiki/Talk:Combat_Log#Damageable_Object_Deaths
             // Generate synthetic object death event as per https://wiki.secondlife.com/wiki/Talk:Combat_Log#Damageable_Object_Deaths
            key source = llDetectedKey(deadlyDamage);
             vector sourcePos = llDetectedPos(deadlyDamage);
             vector sourcePos = llDetectedPos(deadlyDamage);
             vector targetPos = llGetPos();
             vector targetPos = llGetPos();
Line 53: Line 52:
                     "owner", llDetectedOwner(deadlyDamage),
                     "owner", llDetectedOwner(deadlyDamage),
                     "rezzer", llDetectedRezzer(deadlyDamage),
                     "rezzer", llDetectedRezzer(deadlyDamage),
                     "source", source,
                     "source", llDetectedKey(deadlyDamage),
                     "source_pos", llList2Json(JSON_ARRAY, [sourcePos.x, sourcePos.y, sourcePos.z]),
                     "source_pos", llList2Json(JSON_ARRAY, [sourcePos.x, sourcePos.y, sourcePos.z]),
                     "target", llGetKey(),
                     "target", llGetKey(),

Revision as of 01:43, 11 August 2024


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.

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.

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 unless healed
            if(health <= 0 && deadlyDamage == -1) deadlyDamage = index;
            else if(health > 0 && deadlyDamage >= 0) deadlyDamage = -1;
        }
        
        if(health < 0) health = 0;
        else if(health > 300.0) health = 300.0;
        
        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);
    }
}