NPC Emotions script

.[npcEmotions500] series

NPC Emotions is a component part of the IruMoto NPC Engine for use in virtual worlds running Open Simulator 9 and later. This script is based on cut-down code for the PUMP Expressions HUD which also runs IruMoto scripts.

Purpose and functionality

The purpose of .[npcEmotions] is an emoter, i.e. it provides facial expressions to the NPC, via 1) the parameters you set in each scene in the .[npcAction] script, and 2) the blue menu generated by .[npcExist].

The only difference is that parameter option provides more types of expressions, especially since v600 onwards, as it is not limited by the number of buttons available on a blue menu.

The NPC Emotions feature enhances or alters the mood of animations to make your NPC appear more human instead of the standard null expression.

NPC Emotions can be controlled either by a script or drop down menu.

This current series has the name format “.[npcEmotions500.??]” where ?? is a number then letter, representing the version. The six digit number afterwards (where listed in the version notes) is a date format: YYMMDD.

Variables

The .[npcEmotions] script has no variables that need customising. It is drag and drop, set and forget. The script receives commands from .[npcAction] and .[npcExist] via link_message(), and resets itself every time the NPC is born or dies.

Other components

Several other scripts, notecards and contents are necessary for the NPC Engine to function. Visit the main IruMoto NPC Engine page for full information.

Code (.[npcEmotions500.1c])

You may use this script for whatever purpose but must retain the commented header section.

/*
NPC EMOTIONS - IRUMOTO NPC ENGINE
based on PUMP Expressions HUD v1.6
developed by Xay Tomsen in:
InWorldz 2013-14, Reef VR 2015, DigiWorldz 2016-2023.
Script purpose and version notes are online at:
http://www.andrewt2020.com/irumoto/npc-engine/npc-emotions-script/
---------------------------------------------------
*/
key bot;

integer botLive = 0; // 0 to save prim moving with timeGen unless bot exists

integer EMO_STATE = 0;
integer AFRAID = 0;
integer BAWL = 0;
integer CRY = 0;
integer GRIN = 0;
integer KISS = 0;
integer OMG = 0;
integer OOPS = 0;
integer RAPT = 0;
integer SAD = 0;
integer SLEEP = 0;
integer WORRY = 0;

doAfraid() {
    osNpcPlayAnimation(bot, "express_afraid_emote");
    AFRAID = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endAfraid() {
    osNpcStopAnimation(bot, "express_afraid_emote");
    AFRAID = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doBawl() {
    osNpcPlayAnimation(bot, "express_afraid_emote");
    osNpcPlayAnimation(bot, "express_cry_emote");
    BAWL = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endBawl() {
    osNpcStopAnimation(bot, "express_afraid_emote");
    osNpcStopAnimation(bot, "express_cry_emote");
    BAWL = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doCry() {
    osNpcPlayAnimation(bot, "express_cry_emote");
    CRY = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endCry() {
    osNpcStopAnimation(bot, "express_cry_emote");
    CRY = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doGrin() {
    osNpcPlayAnimation(bot, "express_toothsmile");
    GRIN = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endGrin() {
    osNpcStopAnimation(bot, "express_toothsmile");
    GRIN = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doKiss() {
    osNpcPlayAnimation(bot, "express_kiss");
    KISS = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endKiss() {
    osNpcStopAnimation(bot, "express_kiss");
    KISS = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doOMG() {
    osNpcPlayAnimation(bot, "express_open_mouth");
    osNpcPlayAnimation(bot, "express_surprise_emote");
    OMG = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endOMG() {
    osNpcStopAnimation(bot, "express_open_mouth");
    osNpcStopAnimation(bot, "express_surprise_emote");
    OMG = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doOops() {
    osNpcPlayAnimation(bot, "express_embarrassed_emote");
    OOPS = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endOops() {
    osNpcStopAnimation(bot, "express_embarrassed_emote");
    OOPS = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doRapt() {
    osNpcPlayAnimation(bot, "express_open_mouth");
    osNpcPlayAnimation(bot, "express_toothsmile");
    RAPT = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endRapt() {
    osNpcStopAnimation(bot, "express_open_mouth");
    osNpcStopAnimation(bot, "express_toothsmile");
    RAPT = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doSad() {
    osNpcPlayAnimation(bot, "express_sad_emote");
    SAD = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endSad() {
    osNpcStopAnimation(bot, "express_sad_emote");
    SAD = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doSleep() {
    osNpcPlayAnimation(bot, "express_disdain");
    osNpcPlayAnimation(bot, "express_bored_emote");
    SLEEP = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endSleep() {
    osNpcStopAnimation(bot, "express_disdain");
    osNpcStopAnimation(bot, "express_bored_emote");
    SLEEP = 0; EMO_STATE = 0; llSetTimerEvent(0); }

doWorry() {
    osNpcPlayAnimation(bot, "express_worry_emote");
    WORRY = 1; EMO_STATE = 1; llSetTimerEvent(1.0); }
endWorry() {
    osNpcStopAnimation(bot, "express_worry_emote");
    WORRY = 0; EMO_STATE = 0; llSetTimerEvent(0); }

clearEmos() {
    osNpcStopAnimation(bot, "express_afraid_emote");
    AFRAID = 0;
    BAWL = 0;
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_cry_emote");
    CRY = 0;
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_toothsmile");
    GRIN = 0;
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_kiss");
    KISS = 0;
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_bored_emote");
    osNpcStopAnimation(bot, "express_disdain");
    SLEEP = 0; 
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_open_mouth");
    OMG = 0;
    llSleep(0.1);
    OOPS = 0;
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_embarrassed_emote");
    RAPT = 0;
    osNpcStopAnimation(bot, "express_surprise_emote");
    OMG = 0;
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_sad_emote");
    SAD = 0;
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_toothsmile");
    llSleep(0.1);
    osNpcStopAnimation(bot, "express_worry_emote");
    WORRY = 0;
    EMO_STATE = 0;
    llSetTimerEvent(0); }

default
{
    state_entry()
    {
        bot = llGetObjectDesc();
    }

    timer()
    {
        if (EMO_STATE == 1) {
            if (AFRAID == 1) { endAfraid(); llSleep(0.5); doAfraid(); }
            if (BAWL == 1) { endBawl(); llSleep(0.5); doBawl(); }
            if (CRY == 1) { endCry(); llSleep(0.5); doCry(); }
            if (GRIN == 1) { endGrin(); llSleep(0.5); doGrin(); }
            if (KISS == 1) { endKiss(); llSleep(0.5); doKiss(); }
            if (OMG == 1) { endOMG(); llSleep(0.5); doOMG(); }
            if (OOPS == 1) { endOops(); llSleep(0.5); doOops(); }
            if (RAPT == 1) { endRapt(); llSleep(0.5); doRapt(); }
            if (SAD == 1) { endSad(); llSleep(0.5); doSad(); }
            if (SLEEP == 1) { endSleep(); llSleep(0.5); doSleep(); }
            if (WORRY == 1) { endWorry(); llSleep(0.5); doWorry(); }
        }
    }
    link_message(integer sender_num, integer num, string msg, key id)
    {
        if (msg == "resetAll") { llResetScript(); }
        else if (msg == "botLive0") { botLive = 0; }
        else if (msg == "botLive1") { 
            botLive = 1;
            llSleep(5.0); // allow time to update llGetObjectDesc
            bot = llGetObjectDesc();
        }
//Emotions
        else if (msg == "Afraid") {
            if (AFRAID == 0) { doAfraid();} else if (AFRAID == 1) { endAfraid();}
        }
        else if (msg == "Bawl") {
            if (BAWL == 0) { doBawl(); } else if (BAWL == 1) { endBawl(); }
        }
        else if (msg == "Cry") {
            if (CRY == 0) { doCry(); } else if (CRY == 1) { endCry(); }
        }
        else if (msg == "Grin") {
            if (GRIN == 0) { doGrin(); } else if (GRIN == 1) { endGrin(); }
        }
        else if (msg == "Kiss") {
            if (KISS == 0) { doKiss(); } else if (KISS == 1) { endKiss(); }
        }
        else if (msg == "OMG") { 
            if (OMG == 0) { doOMG(); } else if (OMG == 1) { endOMG(); }
        }
        else if (msg == "Oops") { 
            if (OOPS == 0) { doOops(); } else if (OOPS == 1) { endOops(); }
        }
        else if (msg == "Rapt") {
            if (RAPT == 0) { doRapt(); } else if (RAPT == 1) { endRapt(); }
        }
        else if (msg == "Sad") {
            if (SAD == 0) { doSad(); } else if (SAD == 1) { endSad(); }
        }
        else if (msg == "Sleep") {
            if (SLEEP == 0) { doSleep(); } else if (SLEEP == 1) { endSleep(); }
        }
        else if (msg == "ClearEmos") {
            clearEmos();
        }
        else if (msg == "Worry") {
            if (WORRY == 0) { doWorry(); } else if (WORRY == 1) { endWorry(); }
        }
    }
}

Version Notes

2023

  • v600 – 230326 removed llSleep() between endAnim and PlayAnim events
  • added Climax, Doze, Frown, Laugh, Lick, Rage, Shock, and Suck
  • new anims accessible from npcAction but not from npcExist menu.
  • added botLive check from npcAction.
  • v601 230402 fixed animation name error in Doze sequence

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.