mercredi 9 avril 2008
llGetParcelPrimOwners
La fonction du jour permet de recupèrer une list de personne utilisant des prim sur une parcelle.
Notre exemple permet de dire combien d'objet possède la personne qui touche l'objet
La liste de retour à ce format [Key Av1, Integer PrimAv1,Key Av2, Integer PrimAv2,....]
default
{
touch_start(integer total_number)
{
integer count=0;
// identifie l'avatar qui touche
key av=llDetectedKey(0);
// la fonction du jour
list OwnPrim=llGetParcelPrimOwners(llGetPos());
// recherche dans la list l'avatar detecté
integer i=llListFindList(OwnPrim,[av]);
// recupère dans la liste les prims utiliser par l'avatar
if(i!=0)count=llList2Integer(OwnPrim,i+1);
// affiche un message du nombre de prim de l'avatar
llSay(0, llKey2Name(av) + ", vous possedez sur cette parcelle " + (string)count + " prims");
}
}
mardi 8 avril 2008
llGetParcelPrimCount
Désolé pour mon absence prolongée, mais LslToday est de retour.
La fonction du jour, llGetParcelPrimCount, permet de determiner le nombre de prim utilisés sur un terrain.
Elle prend trois paramètres:
- Un vecteur qui determine quelle parcelle de la sim doit être comptée.
- Une constante determinant qu'es ce que l'on doit compter
Category | Value | Meaning |
PARCEL_COUNT_TOTAL | 0 | All prims on the parcel(s). Does not include temp on rez objects. |
PARCEL_COUNT_OWNER | 1 | Prims owned by the parcel owner. |
PARCEL_COUNT_GROUP | 2 | Prims not owned by the owner, but set to or owned by the group of the parcel. |
PARCEL_COUNT_OTHER | 3 | Prims not set to group or owned by the owner. |
PARCEL_COUNT_SELECTED | 4 | All prims selected or sat on. |
PARCEL_COUNT_TEMP | 5 | All temp on rez objects. |
- et un paramètre TRUE/FALSE si on compte la sim en entier
default
{
touch_start(integer total_number)
{
llSay(0, (string)llGetParcelPrimCount(llGetPos(), PARCEL_COUNT_TOTAL,FALSE));
}
}
mercredi 6 février 2008
llEjectFromLand
La foction du jour, llEjectFromLand est assez explicite elle permet d'ejecter un avatar de son terrain.
En la combinant avec Sensor, nous avons fait notre petite alarme maison.
La fonction ne prends que un seul paramètre une Key qui est la personne qui doit etre éjecté.
default
{
state_entry()
{
//verifie la présence d'avatar dans un rayon de 50m toute les 30 sec
llSensorRepeat("",NULL_KEY,AGENT,50,TWO_PI,30);
}
sensor(integer total_number)
{
//l'evenement sensor fonctionne comme touch et fournie le nombre de personnes detectées
integer i;
//on boucle sur toutes les personnes detectés
for(i=0;i<total_number;i++)
{
// si la personne detecté n'est pas le propriétaire on lui donne un avertissement
if(llDetectedKey(0)!=llGetOwner())
{
// la fonction du jour
llEjectFromLand(llDetectedKey(0));
}
}
}
}
mardi 5 février 2008
llSensorRepeat
La fonction llSensorRepeat est strictement identique à la fonction sensor que nous avons vu hier, ca particularité:
Elle possède un paramètre supplémentaire qui est la régularité d'excution qui est fixé en seconde.
Ainsi vous pouvez detecter de manière répétitive une cible. Comme une porte de supermarché qui attends que quelqu'un s'approche pour s'ouvrir
default
{
state_entry()
{
//la fonction du jour
llSensorRepeat("",NULL_KEY,AGENT,50,TWO_PI,30);
}
sensor(integer total_number)
{
//l'evenement sensor fonctionne comme touch et fournie le nombre de personnes detectées
int i;
//on boucle sur toutes les personnes detectés
for(i=0;i<total_number;i++)
{
// si la personne detecté n'est pas le propriétaire on lui donne un avertissement
if(llDetectedKey(0)!=llGetOwner())
llSay(PUBLIC_CHANNEL,"vous n'etes pas le proprietaire, partez");
}
}
}
lundi 4 février 2008
llSensor
La fonction llSensor est très puissante. Elle permet de detecter differentes choses dans une zone. Il faut parcontre l'utiliser avec mesure car elle génère du lag. Elle est très utilisé pour les alarmes qui est un peu le principe de notre script.
La fonction prends 5 paramètres:
Un string qui est le nom de la personne ou objet rechercher
Une key de la personne ou objet rechercher
Un integer qui est le type de chose recherché, object agent...
Un integer qui est la portée qui ne peut excéder 96m (ce qui est gigantesque, utiliser des distances trees courtes)
Et pour fini l'arc, il s'agit de l'angle exprimé en radiant dans notre cas il recherche dans une sphère
default
{
touch_start(integer total_number)
{
//la fonction d jour
llSensor("",NULL_KEY,AGENT,50,TWO_PI);
}
sensor(integer total_number)
{
//l'evenement sensor fonctionne comme touch et fournie le nombre de personnes detectées
int i;
//on boucle sur toutes les personnes detectés
for(i=0;i<total_number;i++)
{
// si la personne detecté n'est pas le propriétaire on lui donne un avertissement
if(llDetectedKey(0)!=llGetOwner())
llSay(PUBLIC_CHANNEL,"vous n'etes pas le proprietaire, partez");
}
}
}
mardi 29 janvier 2008
llPlaySound
Le lsl permet aussi de jouer du son, c'est ce que fais la fonction du jour, Nous allons essayer de rentrer dans une thématique musical.
llPlaySound prend deux paramètres, un string qui est le nom du son et un float qui est le volume, le son varie de 0 à 1.
Notre programme permet de lire le premier son de l'inventaire quand on lance notre programme
default
{
state_entry()
{
//recupère le premier son de l'iventaire
string son=llGetInventoryName(INVENTORY_SOUND,0);
//la fonction du jour
llPlaySound(son,0.8);
}
}
Libellés :
lsl,
script,
second life
jeudi 24 janvier 2008
llListenControl
llListenControl permet d'activer ou de desactiver l'ecoute d'un channel, on avait déjà vu que ce système etait possible avec llRemoveListen.
Cette fonction présente un gros interet voir une nécéssité quand on ecoute le channel publique. Tout simple parcequ'il y a enorment de message qui passe sur ce channel donc beaucoup de travail pour le script.
Les listen sur le channel public font énormement laguer; Il faut bien comprendre qu'il ne sert à rien d'ecouter un channel pour rien.
Donc soit on le remove car on en a besoin qu'une fois soit control si c'est répétitif mais temporaire.
La fonction prends deux paramètres:
Un integer qui permet d'identifier le listen cette valeur nous est retourné par llListen
et un True/False pour arreter ou relancer l'ecoute
integer KeyListen;
default {
state_entry()
{
// ecoute le channel public
KeyListen = llListen(PUBLIC_CHANNEL, "", NULL_KEY, "");
}
touch_start(integer total_number)
{
// la fonction du jour
llListenControl(KeyListen, TRUE);
}
listen(integer channel, string name, key id, string message)
{
if (message == "off")
llListenControl(KeyListen, FALSE);
else
//affiche en float text le contenu du chat public
llSetText(message,<1.0,1.0,1.0>,1.0);
}
}
Libellés :
lsl,
script,
second life
mercredi 23 janvier 2008
llEmail
llEmail comme vous pouvez vous en douter permet d'envoyer des mails. Sur Second Life cette technique est très simple.
IL suffit de fournir à la fonction, adresse, sujet, message. L'exemple d'aujourd'hui permet d'envoyer qui et combien a donné de Tips
default
{
state_entry()
{
llSetPayPrice(PAY_HIDE,[50,100,200,500]);
}
money(key giver, integer amount)
{
string adresse="lancelot.joubert@gmail.com";
string sujet=llGetObjectName();
string message=llKey2Name(giver) + " " + (string)amount;
llEmail(adresse,sujet ,message);
}
}
Libellés :
lsl,
script,
second life
mardi 22 janvier 2008
llMapDestination
llMapDestination pemet de faire un téléport longue portée d'une simà une autre via l'interface de choix de destination.
Ainsi, vous pourrez dans une autre sim faire une pub qui vous emmène dans votre magsin en clickant dessus.
La fonction prend trois paramètres, tout d'abord un string qui est le nom de la sim destination,
un vecteur determinant la position dans la sim, puis aussi une rotation, mais ce n'est que accessoire....
string sim_name;
vector pos;
default
{
touch_start(integer total_number)
{
llMapDestination(sim_name, pos, ZERO_VECTOR);
}
}
Libellés :
lsl,
script,
second life
vendredi 18 janvier 2008
State
Aujourd'hui il ne s'agira pas d'une fonction, mais comment bien utilisé "state" ou etat. Dans notre exemple allons frabriquer un pseudo feu rouge.
Chaque evenement est spécifique à l'etat dans lequel on est ainsi, on peut avoir le même evenement dans fifferent etat et qu'il ne fasse pas la même chose.
Décomposons le programme, je commence dans l'etat default, l'etat de base est l'etat rouge, alors on "saute" dedans.
On mets à rouge noter objet et au bout de 5 secondes, il passe à vert, puis après 5 seconde il passe à l'orange pour seulement 3 secondes.
Il y a biensure une technique pour le faire sans les états mais c'est beaucoup plus compliqué et surtout moins lisible.
Car il aurait fallu faire plein de tests imbriqués, perdant ainsi en clarté de lecture.
Pour savoir quand utilisé les state c'est simple, plus vous avez de conditions dans un seul et même evenement, il serait peut être judicieux de l'utiliser.
default
{
state_entry()
{
state rouge;
}
}
state rouge
{
state_entry()
{
llSetColor(<1.0,0.0,0.0>,ALL_SIDES);
llSetTimerEvent(5);
}
timer()
{
state vert;
}
}
state orange
{
state_entry()
{
llSetColor(<1.0,1.0,0.0>,ALL_SIDES);
llSetTimerEvent(3);
}
timer()
{
state rouge;
}
}
state vert
{
state_entry()
{
llSetColor(<0.0,1.0,0.0>,ALL_SIDES);
llSetTimerEvent(5);
}
timer()
{
state orange;
}
}
Libellés :
lsl,
script,
second life
mercredi 16 janvier 2008
llStopAnimation
Avec cette fonction, nous avons enfin tout pour faire une pose ball rudimentaire. La fonction du jour permet d'arrêter une animation de l'avatar. Quand on fait un sit sur un objet, par défaut cela lance l'animation "sit" (logique). Notre pose ball est déstiné à mettre notre avatar allongé, donc il faut arrêter cette position assise avant de lancer notre position allongée.
llStopAnimation a le même fonctionnement que llStartAnimation pour ses paramètres mais une démarre l'animation et l'autre l'arrête.
Il y a une imperfection dans cette pose ball mais vous trouverez laquelle, la solution se cache dans llSitTarget
Bonne chance et bonne animation
default
{
state_entry()
{
// change le libellé de sit
llSetSitText("Dormir");
}
// l'evenement se produit d'un changement avec un prim
// dans le cas qui nous interesse je m'assieds ou je me lève
changed(integer change)
{
// verifie si il s'agit d'un changement de liaison
if(change==CHANGED_LINK)
{
// la fonction du jour
key user=llAvatarOnSitTarget();
// on verifie la presence de l'avatar
if(user!=NULL_KEY)
{
// arrete l'animation naturelle de sit
llStopAnimation("sit");
// démare l'animation sleep pour mettre l'avatar allonger
llStartAnimation("sleep");
}
else
{
// arretes l'animation quand l'avatar se lève
llStopAnimation("sleep");
}
}
}
}
llStopAnimation a le même fonctionnement que llStartAnimation pour ses paramètres mais une démarre l'animation et l'autre l'arrête.
Il y a une imperfection dans cette pose ball mais vous trouverez laquelle, la solution se cache dans llSitTarget
Bonne chance et bonne animation
default
{
state_entry()
{
// change le libellé de sit
llSetSitText("Dormir");
}
// l'evenement se produit d'un changement avec un prim
// dans le cas qui nous interesse je m'assieds ou je me lève
changed(integer change)
{
// verifie si il s'agit d'un changement de liaison
if(change==CHANGED_LINK)
{
// la fonction du jour
key user=llAvatarOnSitTarget();
// on verifie la presence de l'avatar
if(user!=NULL_KEY)
{
// arrete l'animation naturelle de sit
llStopAnimation("sit");
// démare l'animation sleep pour mettre l'avatar allonger
llStartAnimation("sleep");
}
else
{
// arretes l'animation quand l'avatar se lève
llStopAnimation("sleep");
}
}
}
}
Libellés :
changed,
key,
llDetectedKey,
llRequestPermissions,
llSetSitText,
llSetText,
llStartAnimation,
llStopAnimation
mardi 15 janvier 2008
llStartAnimation
La fonction du jour permet de lancer une animation. Cette fonction nécéssite que l'avatar ait repondu oui à la demande de permission sinon le script fais une erreur.
C'est pour cela que l'on teste si la permission est égal à animation. La fonction prend en paramètre une chaine de caractères correspondant à l'animation.
Cette valeur peut être une animation contenue dans votre objet, soit une des animations déjà existante nativement les "Built In"
default
{
state_entry()
{
// affiche le texte au dessus de l'objet
llSetText("Touchez moi pour danser",<1.0,1.0,1.0>,1.0);
}
touch_start(integer total_number)
{
// demande la permission d'animer l'avatar
llRequestPermissions(llDetectedKey(0),PERMISSION_TRIGGER_ANIMATION);
}
// se produit apres une demande permission
run_time_permissions(integer permissions)
{
// verifie que la réponse est oui pour l'animation
if(permissions==PERMISSION_TRIGGER_ANIMATION)
{
// la fonction du jour
llStartAnimation("dance1");
}
}
}
C'est pour cela que l'on teste si la permission est égal à animation. La fonction prend en paramètre une chaine de caractères correspondant à l'animation.
Cette valeur peut être une animation contenue dans votre objet, soit une des animations déjà existante nativement les "Built In"
aim_l_bow aim_r_bazooka aim_r_handgun aim_r_rifle angry_fingerwag angry_tantrum away backflip blowkiss bow brush busy clap courtbow crouch crouchwalk dance1 dance2 dance3 dance4 dance5 dance6 dance7 dance8 dead drink | express_afraid express_afraid_emote express_anger express_anger_emote express_bored express_bored_emote express_cry express_cry_emote express_disdain express_embarrassed_emote express_frown express_kiss express_laugh express_laugh_emote express_open_mouth express_repulsed express_repulsed_emote express_sad express_sad_emote express_shrug express_shrug_emote express_smile express_surprise express_surprise_emote express_tongue_out express_toothsmile express_wink express_wink_emote express_worry express_worry_emote | falldown female_walk fist_pump fly flyslow hello hold_l_bow hold_r_bazooka hold_r_handgun hold_r_rifle hold_throw_r hover hover_down hover_up impatient jump jumpforjoy kick_roundhouse_r kissmybutt land laugh_short motorcycle_sit musclebeach | no_head no_unhappy nyanya peace point_me point_you prejump punch_l punch_onetwo punch_r rps_countdown rps_paper rps_rock rps_scissors run salute shoot_l_bow shout sit sit_female sit_generic sit_ground sit_to_stand sleep smoke_idle smoke_inhale smoke_throw_down | snapshot soft_land stand stand_1 stand_2 stand_3 stand_4 standup stretch stride surf sword_strike_r talk throw_r tryon_shirt turn_180 turnback_180 turnleft turnright type walk whisper whistle wink_hollywood yes_happy yes_head yoga_float |
default
{
state_entry()
{
// affiche le texte au dessus de l'objet
llSetText("Touchez moi pour danser",<1.0,1.0,1.0>,1.0);
}
touch_start(integer total_number)
{
// demande la permission d'animer l'avatar
llRequestPermissions(llDetectedKey(0),PERMISSION_TRIGGER_ANIMATION);
}
// se produit apres une demande permission
run_time_permissions(integer permissions)
{
// verifie que la réponse est oui pour l'animation
if(permissions==PERMISSION_TRIGGER_ANIMATION)
{
// la fonction du jour
llStartAnimation("dance1");
}
}
}
Libellés :
llDetectedKey,
llRequestPermissions,
llSetText,
llStartAnimation
lundi 14 janvier 2008
llSetSitText
La fonction du jour est relativement basique. Vous avez déjà certainement vu sur les camp ou les teleport que le nom où est marqué sit a été changé.
Grace à llSetSitText vous pouvez changer le nom du menu. Cela permet de s'adapter au contexte.
Juste un paramètre, le nom que vous voulez mettre
default
{
state_entry()
{
// position de destination x,y,z
vector Destination=<512,34,10>;
// distance relative au teleport
vector offset=(Destination-llGetPos())/llGetRot();
// determine la position d'arriver
llSitTarget(offset,ZERO_ROTATION);
// la fonction du jour
llSetSitText("Teleport");
}
// l'evenement se produit d'un changement avec un prim
// dans le cas qui nous interesse je m'assieds ou je me lève
changed(integer change)
{
// verifie si il s'agit d'un changement de liaison
if(change==CHANGED_LINK)
{
// la fonction du jour
key user=llAvatarOnSitTarget();
// on verifie la presence de l'avatar
if(user!=NULL_KEY)
// remet debout l'avatar à la destination
// sinon il arrive en position assise
llUnSit(user);
}
}
}
Libellés :
changed,
llAvatarOnSitTarget,
llSetSitText,
llSitTarget,
llUnSit,
vector
vendredi 11 janvier 2008
llSitTarget
La fonction du jour llSitTarget détermine la position de l'avatar après l'action sit. Une application courante est le téléporteur. En effet on peut determiner la position d'assise mais elle n'est pas forcement sur l'objet lui même, la distance maximum est de 300m.
Le premier paramêtre est la distance relative par raport à notre objet. Attention ce n'est pas les coordonnées d'arrivé mais la distance entre les deux et il ne faut pas oublié de prendre en compte la rotation de l'objet sinon on se retrouve pas au même endroit.
Le deuxième paramètre est la rotation, ce n'est pas important dans le cadre d'un teleport la position finale alors on le mets à ZERO_ROTATION.
j'ai rajouté une autre fonction aujourd'hui llUnSit qui force l'avatar à se relever, sinon il arrive en position assise. Et on ne fait cette action que si il est assis dessus.
default
{
state_entry()
{
// position de destination x,y,z
vector Destination=<512,34,10>;
// distance relative au teleport
vector offset=(Destination-llGetPos())/llGetRot();
// la fonction du jour
llSitTarget(offset,ZERO_ROTATION);
}
// l'evenement se produit d'un changement avec un prim
// dans le cas qui nous interesse je m'assieds ou je me lève
changed(integer change)
{
// verifie si il s'agit d'un changement de liaison
if(change==CHANGED_LINK)
{
// la fonction du jour
key user=llAvatarOnSitTarget();
// on verifie la presence de l'avatar
if(user!=NULL_KEY)
// remet debout l'avatar à la destination
// sinon il arrive en position assise
llUnSit(user);
}
}
}
Libellés :
changed,
key,
llAvatarOnSitTarget,
llGetPos,
llGetRot,
llSitTarget,
llUnSit,
vector
jeudi 10 janvier 2008
llAvatarOnSitTarget
Nous allons commencer une nouvelle thématique avec la fonction llAvatarOnSitTarget(), comment gérer les liaisons et les animations entre prim avatar. Avec pour finalité, ce qu vous avez déjà vu partout dans second life les "pose ball".
Changed se produit quand une interaction vient de se produire avec l'objet. Dans notre cas, si un avatar s'assied ou se lève. Quand on s'assied sur un objet notre avatar est "linker", lié, à l'objet.
le integer change nous indique ce qu'il s'est passé, ici on test si c'est la liaison qui a été modifiée. Mais on ne sait pas s'il s'est levé ou assis. La fonction du jour va nous y aidée.
Elle permet de retourner la key de l'avatar assis sur l'objet, donc si la key n'est pas null c'est qu'il est assis et a contrario c'est qui vient de se lever
default
{
// l'evenement se produit d'un changement avec un prim
// dans le cas qui nous interesse je m'assieds ou je me lève
changed(integer change)
{
// verifie si il s'agit d'un changement de liaison
if(change==CHANGED_LINK)
{
// la fonction du jour
key user=llAvatarOnSitTarget();
// on verifie la presence de l'avatar
if(user!=NULL_KEY)
llInstantMessage(user,"Suis je confortable?");
else
llInstantMessage(user,"merci de m'avoir utilise");
}
}
}
Libellés :
changed,
key,
llAvatarOnSitTarget,
llInstantMessage
mercredi 9 janvier 2008
llListenRemove
Le llListenRemove est très simple à comprendre, il arrete l'ecoute que l'on avait lancé. la fonction llListen renvoit un integer, celui ci identifie de quelle ecoute on parle. Cet identifiant est pris en paramètre par llListenRemove pour etre arreté.
Mais pourquoi avoir fais ca me diriez vous? pour des raisons de sécurité de la vente et de lag.
Si on reprends note script d'hier, le dernier client peut profiter d'une faille car notre channel est toujours ouvert pour lui. Si il connait le channel(pas de bol quand même) il lui suffit de répeter sur ce channel les nom des objets et on lui donne tout ce que l'on veut.
Cette fois-ci c'est blindé car on ecoute que pour le client et une fois qu'il a eu son objet on ecoute plus.
Il y a l'effet lag qui est très important, en utilisant cette fonction, vous scriptez proprement...
// la liste des objet à vendre dans votre vendor
list obj=[];
// permetra l'identification du listen
integer IdListen;
default
{
state_entry()
{
// donne le nombre d'objet contenu dans l'inventaire du prim
integer NbObj=llGetInventoryNumber(INVENTORY_OBJECT);
// compteur de boucle
integer i;
// rempli la list des objets
// les acccolade ne sont pas nécéssaire car il n'y a que
// une ligne dans la boucle
for(i=0;i<NbObj;i++)
obj+=llGetInventoryName(INVENTORY_OBJECT,i);
}
listen(integer channel, string name, key id, string message)
{
// donne l'objet acheté
llGiveInventory(id,message);
// la fonction du jour
llListenRemove(IdListen);
}
money(key giver, integer amount)
{
// choisi un channel au hasard pour securisé
integer mychannel=(integer)llFrand(1000.0)+5000;
// ecoute le channel et concerve le id de l'ecoute
IdListen=llListen(mychannel,"",giver,"");
// laisse le choix de l'objet à l'utilisateur
llDialog(giver,"Choisissez votre objet",obj,mychannel);
}
}
Libellés :
for,
list,
llDialog,
llFrand,
llGetInventoryName,
llGetInventoryNumber,
llGiveInventory,
llListen,
llListenRemove,
money
Inscription à :
Articles (Atom)