OSSLNPC/fr

From OpenSimulator

Jump to: navigation, search


Contents

Introduction

Depuis OpenSimulator 0.7.2, un certain nombre de fonctions sont fournies pour créer et manipuler des NPC côté serveur.

Celles ci remplacent les fonctions précédentes qui ont arrêté de fonctionner depuis OpenSimulator 0.7.1.1 (probablement cassées depuis OpenSimulator 0.6.9).

La philosophie générale dans la création de ces nouvelles fonctions est de:

  1. Donner aux auteurs de scripts des outils simples pour créer des comportements plus sophistiqués.
  2. Eviter de dupliquer les fonctions existantes en LSL et OSSL. Par exemple, trouver l'état dans lequel se trouve un agent peut être effectué avec travers la fonction llGetAgentInfo() plutôt qu'en créant une fonction spéciale pour NPC.

Les NPC sont contrôlés par un script qui peut être dans la même région que le NPC. Il peut être hébergé dans un attachement qui est attaché au maître.

Les utilisateurs créés en NPC ne peuvent pas quitter la région dans laquelle ils sont nés. Si vous voulez un comportement de franchissement de région, regardez les options sur la page wiki concernant les NPC.

L'apparence des NPC est sauvée et chargée en sérialisant la structure de données de l'apparence dans une notecard présente dans le même objet que le script. Les textures requises doivent être préservées quand un OAR est sauvegardé puis chargé.

Malheureusement, le format de données de l'apparence est actuellement le même que celui utilisé pour la liaison avec OpenSimulator donc n'est pas prévu pour être édité directement. Cependant en y prenant bien attention, ceci peut être possible, voir Appearance Formats pour plus de détails.

Activer

Pour utiliser ces fonctions, vous avez besoin de des configurations suivantes dans votre fichier OpenSim.ini

  1. Enabled = true défini dans la section [NPC].
  2. Enabled = true défini dans la section [XEngine].
  3. AllowOSFunctions = true défini dans la section [XEngine].
  4. OSFunctionThreatLevel = VeryHigh défini dans la section [XEngine]. Les fonctions osAgentSaveAppearance(), osAvatarPlayAnimation() et osAvatarStopAnimation() ont besoin de ce niveau. Si vous n'avez pas besoin de ces fonctions, alors un niveau "High" sera suffisant.

Voir Configuring Simulator Parameters#Getting information about parameters si vous avez besoin de confirmer que ces paramètres sont correctement définis.

Notes

  • Quand vous utilisez votre avatar pour modéliser l'apparence avant la sauvegarde, vous devez attendre quelques secondes avant d'invoquer une commande de changement d'apparence. C'est ainsi car la sauvegarde d'apparence opère actuellement avec un délai afin de gérer de multiples mises à jour de l'apparence depuis le client.
  • OpenSimulator 0.7.3-rc1 introduit le concept de "owned" et "unowned" NPC. Un NPC "owned" ne peut être manipulé seulement par les scripts ayant le même "owner" que celui ayant créé le NPC. Un NPC "unowned" peut être manipulé par n'importe quel script ayant les bonnes permissions (comme défini dans la section de configuration de [XEngine]). Dans OpenSimulator 0.7.3, tous les avatars sont "owned" par défaut tant que le contraire n'est pas spécifié dans l'appel à osNpcCreate().

Détection

llAgentSensor() peut être utilisé pour définir un capteur qui va détecter les NPC au même titre que les autres entités de région.

Dans OpenSimulator 0.7.2, les capteurs LSL détecteront les NPC comme des agents originaires.

Dans OpenSimulator 0.7.3-rc1 et supérieur, tant que le contraire n'est pas précisé, les NPC ne seront seulement détectés qu'en utilisant le drapeau OpenSimulator-specific.

Avec la version git master bcfc392 (Fri Jul 20 21:08:04 2012), la constante OS_NPC devrait maintenant être utilisée à la place de NPC, afin d'éviter de futurs problèmes si LL décide d'utiliser des NPC eux-mêmes dans d'autres directions. La constante NPC sera déconseillée à partir de la version 0.7.4 mais restera utilisable.

//Author: mewtwo0641
 
list keys = [];
key npc;
string toucher;
key toucherkey;
vector toucherPos;
integer npc_on = FALSE;
 
default
{
    touch_start(integer x)
    {
        toucherkey = llDetectedKey(0);
        toucherPos = llDetectedPos(0);
        vector npcPos = llGetPos() + <1,1,1>;
 
        if(npc_on == FALSE)
        {
            npc = osNpcCreate("Fred", "Flintstone", npcPos, toucherkey);
            npc_on = TRUE;
            llSensor("", "", AGENT | NPC, 96.0, PI); //Retournera toujours la clef du NPC par rapport aux options définies dans osNpcCreate
            return;
        }
 
        if(npc_on == TRUE)
        {
            osNpcRemove(npc);
            llResetScript();
        }
    }
 
    sensor(integer num)
    {
        keys = [];
        integer i = 0;
 
        for(i; i < num; i++)
        {
            keys += llDetectedKey(i);
        }
 
        llOwnerSay(llDumpList2String(keys, "\n"));
    }
 
    no_sensor()
    {
        keys = [];
    }
}

Vous pouvez faire en sorte à ce que les NPC soient détectables de nouveau en tant qu' AGENT en utilisant l'option OS_NPC_SENSE_AS_AGENT dans osNpcCreate().

Cette précision sert à corriger le problème que certains scripts, détectant les NPC comme des AGENTS par défaut, peuvent être rendus inutilisables. (ex: les radars qui ne savent rien sur les NPC). Cependant la conversion d'autres scripts peuvent ne pas répondre comme prévu si les avatars ne sont pas détectés comme des agents (ex: les portes qui s'ouvrent automatiquement pour les avatars pourraient ne pas s'ouvrir pour les NPC).

Depuis OpenSimulator git master commit ecf7bb26 (Fri Jul 20 21:36:33 2012), llGetDetectedType() définit le drapeau OS_NPC si un NPC a été détecté. Si le NPC a été créé avec l'option OS_NPC_SENSE_AS_AGENT alors le drapeau AGENT sera aussi défini.

Fonctions

Créer et Retirer

osNpcCreate

osNpcCreate(string firstname, string lastname, vector position, string cloneFrom):key

cloneFrom peut être:

  • Le nom d'une notecard contenant une apparence d'avatar sérialisée, ou
  • L'UUID de l'asset de la notecard, ou
  • L'UUID d'un avatar connecté sur la même région. Cependant, notez que cette apparence ne sera pas persistante tant que osNpcSaveAppearance() n'est pas appellé.

Si le NPC est créé avec succès, alors son UUID est retourné, ce qui est nécessaire pour toutes les fonctions subséquentes. Un exemple est disponible dans osNpcCreate

(seulement depuis OpenSimulator 0.7.3-rc1). Ceci crée un NPC qui est "possédé" par le script de création et détecté en utilisant le drapeau OpenSimulator-only pour les capteurs.

osNpcCreate

Depuis OpenSimulator 0.7.3-rc1.

osNpcCreate(string firstname, string lastname, vector position, string cloneFrom, integer options):key

cloneFrom peut être:

  • Le nom de la notecard contenant une apparence sérialisée d'avatar, ou
  • L'UUID d'asset de la notecard, ou
  • L'UUID d'un avatar actuellement connecté sur la même région. Cependant notez bien que cette apparence ne sera pas persistante tant que osNpcSaveAppearance() n'est pas appellé.

integer est un ensemble de drapeaux qui peut être 0 ou un de ceux ci

  • OS_NPC_NOT_OWNED - crée un "unowned" NPC.
  • OS_NPC_SENSE_AS_AGENT - crée un NPC qui est détecté en tant que AGENT par les capteurs LSL

Si le NPC est créé avec succès, alors son UUID est retourné, ce qui est nécessaire pour toutes les fonctions subséquentes. Un exemple est disponible dans osNpcCreate

osNpcRemove

osNpcRemove(key npc):void

Retire l'avatar donné depuis la région. Exemple à osNpcRemove.

Get et Set

osIsNpc

Depuis OpenSimulator 0.7.3-rc1.

osIsNpc(key npc):integer

Retourne TRUE si la clef donnée est un NPC, FALSE dans les autres cas.

osNpcGetRot

Récupère la rotation de l'avatar. Seulement la rotation autour du plan Z en coordonnées Euler (rotation horizontale) aura une signification.

osNpcGetRot(key npc):rotation

osNpcSetRot

osNpcSetRot(key npc, rotation rot):void

Définit la rotation de l'avatar. Seulement la rotation sur le plan Z en coordonnées Euler aura une signification (faire tourner l'avatar pour le faire pointer dans une direction ou une autre). Définir les valeurs Euler X ou Y résultera en une rotation d'une manière indéfinie.

osNpcGetPos

osNpcGetPos(key npc):vector

Retourne la position actuelle du NPC.

osNpcGetOwner

Depuis OpenSimulator 0.7.3-rc1.

osNpcGetOwner(key npc):key

Retourne le propriétaire du NPC donné. (ex: le propriétaire du script qui l'a créé). Si le NPC est unowned ou la clef fournie n'appartient pas à un NPC, il sera retourné NULL_KEY.

Déplacement

osNpcMoveTo

osNpcMoveTo(key npc, vector position):void

Fonction plus ancienne qui effectue un osNpcMoveToTarget() en volant et atterrissant sur la cible.

osNpcMoveToTarget

osNpcMoveToTarget(key npc, vector target, int options):void

Déplace l'avatar à une cible donnée durant un certain temps. La façon dont l'avatar va rejoindre sa cible dépendra des options suivantes.

  • OS_NPC_FLY - Fait voler l'avatar à la position donnée. L'avatar n'atterrira pas tant que l'option OS_NPC_LAND_AT_TARGET n'est pas aussi définie.
  • OS_NPC_NO_FLY - Ne fait pas voler vers la cible. Le NPC va tenter de marcher vers la destination. Si elle est en hauteur dans les airs, alors l'avatar va rebondir sans cesse jusqu'à ce qu'un autre move to target lui soit donné ou que le déplacement soit interrompu.
  • OS_NPC_LAND_AT_TARGET - Si défini et que l'avatar donné est en train de voler, alors il va atterrir quand il atteindra la cible. Si OS_NPC_NO_FLY est donné, alors cette option n'aura pas d'effet.
  • OS_NPC_RUNNING - Si défini, le NPC se déplacera à vitesse rapide ou lente, sinon à vitesse normale.

OS_NPC_FLY et OS_NPC_NO_FLY sont des options qui ne peuvent être combinées - l'avatar va finir par utiliser soit l'une soit l'autre. Si vous voulez que l'avatar vole et atterrisse sur la cible, alors OS_NPC_LAND_AT_TARGET doit être combiné avec OS_NPC_FLY. Par exemple,

osNpcMoveToTarget(npc, llGetPos() + <9,9,5>, OS_NPC_FLY|OS_NPC_LAND_AT_TARGET);

osNpcStopMoveToTarget

osNpcStopMoveToTarget(key npc):void

Arrête le déplacement actuel vers une cible.

Sitting and standing

osNpcSit

Depuis OpenSimulator 0.7.3-rc1.

osNpcSit(key npc, key target, int options):void

Assied un NPC sur la primitive cible. Actuellement il n'y a aucune option donc donnez lui toujours 0.

osNpcStand

Depuis OpenSimulator 0.7.3-rc1.

osNpcStand(key npc):void

Mettre debout le NPC.

Communication

osNpcSay

osNpcSay(key npc, string message):void
osNpcSay(key npc, int channel, string message):void

Faire dire le message donné au NPC.

Si le canal est spécifié, alors le texte est dit sur le canal donné. Le parametre de canal est seulement disponible dans les versions supérieures à 0.7.4.

osNpcShout

Depuis OpenSimulator 0.7.4.

osNpcShout(key npc, int channel, string message):void

Faire crier le message donné au NPC sur le canal donné.

osNpcWhisper

Depuis OpenSimulator 0.7.4.

osNpcWhisper(key npc, int channel, string message):void

Faire chuchotter le message donné au NPC sur le canal donné.

Animations

osNpcPlayAnimation

Depuis OpenSimulator 0.7.3-rc1.

osNpcPlayAnimation(key npc, string animation):void

Faire jouer une animation au NPC. L'animation peut être soit une clef, soit le nom d'une animation contenue dans le même inventaire que le script.

osNpcStopAnimation

Dans OpenSimulator 0.7.3-rc1 il y a un bug qui fait jouer l'animation à la place. Ceci sera corrigé dans la version finale mais en attendant, utilisez osAvatarStopAnimation() à la place.

osNpcStopAnimation(key npc, string animation):void

Faire stopper une animation jouée par le NPC. L'animation peut être soit une clef, soit le nom d'une animation contenue dans le même inventaire que le script.

Appearance

L'apparence d'un NPC est manipulée en sauvegardant puis chargeant les données d'apparence dans une notecard contenue dans le même inventaire que le script invoqué.

osOwnerSaveAppearance

osOwnerSaveAppearance(string notecard):key

Sauvegarde l'apparence actuelle du propriétaire vers une notecard dans l'inventaire de la primitive. Ceci inclut les données du corps, les vêtements et attachements. Si une notecard ayant le même nom existe déjà, elle sera alors remplacée. Le propriétaire doit être présent sur la région quand la fonction est invoquée. Les texture rendues pour le propriétaire (nécessaires pour recréer l'apparence du NPC) sont sauvées définitivement.

osAgentSaveAppearance

osAgentSaveAppearance(key agentId, string notecard):key

Sauvegarde l'apparence actuelle d'un avatar vers une notecard dans l'inventaire de la primitive. Ceci inclut les données du corps, les vêtements et attachements. Si une notecard ayant le même nom existe déjà, elle sera alors remplacée. L'avatar doit être présent sur la région quand la fonction est invoquée. Les texture rendues pour l'avatar (nécessaires pour recréer l'apparence du NPC) sont sauvées définitivement.

osNpcSaveAppearance

osNpcSaveAppearance(key npc, string notecard):key

Sauvegarde l'apparence actuelle du NPC vers une notecard dans l'inventaire de la primitive. Ceci inclut les données du corps, les vêtements et attachements. Si une notecard ayant le même nom existe déjà, elle sera alors remplacée. L'avatar doit être présent sur la région quand la fonction est invoquée. Les texture rendues pour l'avatar (nécessaires pour recréer l'apparence du NPC) sont sauvées définitivement.

osNpcLoadAppearance

osNpcLoadAppearance(key npc, string notecard):void

Charge l'apparence depuis une notecard. Cette notecard doit contenir des données d'apparence crées avec une des fonctions de sauvegarde d'apparence.


Toucher

osNpcTouch

Depuis OpenSimulator 0.7.4.

osNpcTouch(key npc, key objectKey, integer linkNum)

Autorise le NPC à toucher des objets.

Exemples

Ceci est un exemple brut pour la plupart des fonctionnalités des NPC. Une de ses déficiences majeures est qu'il ne suit pas plus d'un avatar créé à la fois. Bien sûr, n'hesitez pas à l'améliorer.

key npc;
integer listenChannel = 10;
 
default
{
    // NPC manipulator adapted by justincc 0.0.3 released 20121025
    state_entry()
    {
        llListen(listenChannel,"",NULL_KEY,"");
        llSetText("Listening on " + listenChannel, <0, 255, 0>, 1);
        llOwnerSay("Say /" + (string)listenChannel + " help for commands");
    }
 
    listen(integer channel, string name, key id, string msg)
    {
        if (msg != "")
        {
            list commands = llParseString2List(msg, [ " " ], []);
            string msg0 = llList2String(commands, 0);
            string msg1 = llList2String(commands, 1);
            string msg2 = llList2String(commands, 2);
            string msg3 = llList2String(commands, 3);
 
            if (msg0 == "create")
            {
                if (msg1 != "")
                {
                    string notecardName = msg1;
 
                    npc = osNpcCreate("Jane", "Doe", llGetPos() + <5, 5, 0>, notecardName);
 
                    llOwnerSay("Creation du npc depuis la notecard " + notecardName);
                }
                else
                {
                    llOwnerSay("Utilisation: create <notecard-name>");
                }
            }
            else if (msg0 =="createm" && msg1 != "")
            {
                osOwnerSaveAppearance("appearance");
                vector pos = llGetPos();
                integer i;
                for (i = 0; i < (integer)msg1; i++)
                {
                    osNpcCreate("John", "Doe", pos + <8, 0, 0>, "appearance");
                    llSleep(1);
                }
            }
            else if (msg0 == "remove" && npc != NULL_KEY)
            {
                osNpcSay(npc, "Vous le paierez de votre viiiiiieeeeeeee!!!.....");
                osNpcRemove(npc);
            }
            else if (msg0 == "say" && npc != NULL_KEY)
            {
                osNpcSay(npc, "Je suis votre pire cauchemard!!!!");
            }
            else if (msg0 == "move")
            {
                if (msg1 != "" && msg2 != "" && npc != NULL_KEY)
                {
                    vector delta = <(integer)msg1, (integer)msg2, 0>;
 
                    if (msg3 != "")
                    {
                        delta.z = (integer)msg3;
                    }
 
                    osNpcMoveTo(npc, osNpcGetPos(npc) + delta);
                }
                else
                {
                    llOwnerSay("Utilisation: move <x> <y> [<z>]");
                }
            }
            else if (msg0 == "moveto")
            {
                if (msg1 != "" && msg2 != "" && npc != NULL_KEY)
                {
                    vector pos = <(integer)msg1, (integer)msg2, 0>;
 
                    if (msg3 != "")
                    {
                        pos.z = (integer)msg3;
                    }
 
                    osNpcMoveTo(npc, pos);
                }
                else
                {
                    llOwnerSay("Utilisation: move <x> <y> [<z>]");
                }
            }
            else if (msg0 == "movetarget" && npc != NULL_KEY)
            {
                osNpcMoveToTarget(npc, llGetPos() + <9,9,5>, OS_NPC_FLY|OS_NPC_LAND_AT_TARGET);
            }
            else if (msg0 == "movetargetnoland" && npc != NULL_KEY)
            {
                osNpcMoveToTarget(npc, llGetPos() + <9,9,5>, OS_NPC_FLY);
            }
            else if (msg0 == "movetargetwalk" && npc != NULL_KEY)
            {
                osNpcMoveToTarget(npc, llGetPos() + <9,9,0>, OS_NPC_NO_FLY);
            }
            else if (msg0 == "rot" && npc != NULL_KEY)
            {
                vector xyz_angles = <0,0,90>; // Ceci pour définir un changement de 1 degres
                vector angles_in_radians = xyz_angles * DEG_TO_RAD; // Change en Radians
                rotation rot_xyzq = llEuler2Rot(angles_in_radians); // Change vers une Rotation
                rotation rot = osNpcGetRot(npc);
                osNpcSetRot(npc, rot * rot_xyzq);
            }
            else if (msg0 == "rotabs" && msg1 != "")
            {
                vector xyz_angles = <0, 0, (integer)msg1>;
                vector angles_in_radians = xyz_angles * DEG_TO_RAD; // Change en Radians
                rotation rot_xyzq = llEuler2Rot(angles_in_radians); // Change vers une Rotation
                osNpcSetRot(npc, rot_xyzq);
            }
            else if (msg0 == "animate" && npc != NULL_KEY)
            {
                osAvatarPlayAnimation(npc, "stabbed+die_2");
                llSleep(3);
                osAvatarStopAnimation(npc, "stabbed+die_2");
            }
            else if (msg0 == "save" && msg1 != "" && npc != NULL_KEY)
            {
                osNpcSaveAppearance(npc, msg1);
                llOwnerSay("Apparence sauvegardée " + msg1 + " to " + npc);
            }
            else if (msg0 == "load" && msg1 != "" && npc != NULL_KEY)
            {
                osNpcLoadAppearance(npc, msg1);
                llOwnerSay("Apparence chargée " + msg1 + " to " + npc);
            }
            else if (msg0 == "clone")
            {
                if (msg1 != "")
                {
                    osOwnerSaveAppearance(msg1);
                    llOwnerSay("Votre apparence a été clonée vers " + msg1);
                }
                else
                {
                    llOwnerSay("Utilisation: clone <notecard-name-to-save>");
                }
            }
            else if (msg0 == "stop" && npc != NULL_KEY)
            {
                osNpcStopMoveToTarget(npc);
            }
            else if (msg0 == "sit" && msg1 != "" && npc != NULL_KEY)
            {
                osNpcSit(npc, msg1, OS_NPC_SIT_NOW);
            }
            else if (msg0 == "stand" && npc != NULL_KEY)
            {
                osNpcStand(npc);
            }
            else if (msg0 == "help")
            {
                llOwnerSay("Les commandes sont:");
                llOwnerSay("create <notecard-name> - Crée un NPC depuis une notecarde sauvegardée");
                llOwnerSay("createm");
                llOwnerSay("remove - Retire le NPC actuel");
                llOwnerSay("clone <notecard-name> - Cloner sa propre apparence vers une notecard");
                llOwnerSay("load <notecard-name>  - Charge l'apparence d'une notecard vers le NPC actuel");
                llOwnerSay("save <notecard-name>  - Sauvegarde l'apparence du NPC actuel vers une notecard");
                llOwnerSay("animate");
                llOwnerSay("move");
                llOwnerSay("moveto <x> <y> <z> - se déplace vers la position absolue définie");
                llOwnerSay("movetargetnoland");
                llOwnerSay("movetargetwalk");
                llOwnerSay("rot");
                llOwnerSay("say");
                llOwnerSay("sit <target-uuid>");
                llOwnerSay("stop");
                llOwnerSay("stand");
            }
            else
            {
                llOwnerSay("Je ne comprends pas [" + msg + "]");
            }
        }
    }
}

Questions/Commentaires

S'il vous plait, laissez vos questions et commentaires sur la page de discussion de cet article.

Personal tools
About This Wiki