Skip to content

Commit 24a9cca

Browse files
committed
added Facial-Layering Plugin
1 parent 117ad4c commit 24a9cca

File tree

1 file changed

+309
-0
lines changed

1 file changed

+309
-0
lines changed
Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
/*
2+
The nPose scripts are licensed under the GPLv2 (http://www.gnu.org/licenses/gpl-2.0.txt), with the following addendum:
3+
4+
The nPose scripts are free to be copied, modified, and redistributed, subject to the following conditions:
5+
- If you distribute the nPose scripts, you must leave them full perms.
6+
- If you modify the nPose scripts and distribute the modifications, you must also make your modifications full perms.
7+
8+
"Full perms" means having the modify, copy, and transfer permissions enabled in Second Life and/or other virtual world platforms derived from Second Life (such as OpenSim). If the platform should allow more fine-grained permissions, then "full perms" will mean the most permissive possible set of permissions allowed by the platform.
9+
*/
10+
integer LAYER_POSE = -218;
11+
list AnimsList; //[string command, string animation name] use a list to layer multiple animations.
12+
list Lastanim;
13+
integer Primcount;
14+
integer Newprimcount;
15+
list Faceanims;
16+
integer GotFaceAnim = 0;
17+
integer Seatcount;
18+
19+
integer OPTIONS = -240;
20+
integer SEAT_UPDATE = 35353;
21+
integer MENU_USAGE = 34334;
22+
list FaceTimes = [];
23+
list Slots;
24+
key ThisAV;
25+
integer Stop;
26+
integer FACIALS_FLAG = -241;
27+
integer FacialEnable = 1;
28+
29+
30+
31+
list SeatedAvs() {
32+
list avs = [];
33+
integer n = llGetNumberOfPrims();
34+
for(; n >= llGetObjectPrimCount(llGetKey()); --n) {
35+
key id = llGetLinkKey(n);
36+
if(llGetAgentSize(id) != ZERO_VECTOR) {
37+
avs = [id] + avs;
38+
}
39+
}
40+
return avs;
41+
}
42+
43+
doSeats(integer slotNum, key avKey) {
44+
llSetTimerEvent(0.0);
45+
if(avKey != "") {
46+
Stop = llGetListLength(Slots)/8;
47+
llRequestPermissions(avKey, PERMISSION_TRIGGER_ANIMATION);
48+
}
49+
}
50+
51+
integer AvLinkNum(key av) {
52+
integer linkcount = llGetNumberOfPrims();
53+
while(av != llGetLinkKey(linkcount)) {
54+
if(llGetAgentSize(llGetLinkKey(linkcount)) == ZERO_VECTOR) {
55+
return -1;
56+
}
57+
linkcount--;
58+
}
59+
return linkcount;
60+
}
61+
62+
default {
63+
state_entry() {
64+
Primcount = llGetNumberOfPrims();
65+
Newprimcount = Primcount;
66+
}
67+
68+
link_message(integer sender, integer num, string str, key id) {
69+
if(num == LAYER_POSE) {
70+
key av;
71+
list tempList = llParseString2List(str, ["/"], []);
72+
if(llListFindList(SeatedAvs(), [(key)llList2String(tempList, 0)]) != -1) {
73+
av = (key)llList2String(tempList, 0);
74+
}
75+
if(av) {
76+
llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION);
77+
av = llGetPermissionsKey();
78+
list tempList1 = llParseString2List(llList2String(tempList, 1), ["~"], []);
79+
integer instruction;
80+
integer layerStop = llGetListLength(tempList1);
81+
for(instruction = 0; instruction < layerStop; ++instruction) {
82+
tempList = llParseString2List(llList2String(tempList1, instruction), [","],[]);
83+
if(llList2String(tempList,0)=="stopAll") {
84+
AnimsList = [av, llList2String(tempList, 0), llList2String(tempList, 1)] + AnimsList;
85+
}
86+
else {
87+
integer index = llListFindList(AnimsList, [llList2String(tempList, 1)]);
88+
if(index>=1 & (key)llList2String(AnimsList, index - 2) == av) {
89+
AnimsList = llDeleteSubList(AnimsList, index-2, index);
90+
}
91+
AnimsList += [av, llList2String(tempList, 0), llList2String(tempList, 1)];
92+
}
93+
}
94+
integer n;
95+
layerStop = llGetListLength(AnimsList)/3;
96+
for(n=0; n<layerStop; ++n) {
97+
if((key)llList2String(AnimsList, n*3) == av) {
98+
if(llList2String(AnimsList, n*3+1) == "stopAll") {
99+
AnimsList = llDeleteSubList(AnimsList, n*3, n*3+2);
100+
n-=1;
101+
layerStop-=1;
102+
integer x;
103+
integer animsStop = llGetListLength(AnimsList)/3;
104+
if(animsStop > 0) {
105+
for(x = 0; x<animsStop; ++x) {
106+
if ((key)llList2String(AnimsList, x*3) == av && llList2String(AnimsList, x*3+2) != ""){
107+
llStopAnimation(llList2String(AnimsList, x*3+2));
108+
AnimsList = llDeleteSubList(AnimsList, x*3, x*3+2);
109+
x-=1;
110+
animsStop-=1;
111+
}
112+
}
113+
}
114+
}
115+
else if(llList2String(AnimsList, n*3+1) == "start" && llList2String(AnimsList, n*3) == av
116+
&& llList2String(AnimsList, n*3+2) != "") {
117+
if(llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) {
118+
llStartAnimation(llList2String(AnimsList, n*3+2));
119+
}
120+
}
121+
else if(llList2String(AnimsList, n*3+1) == "stop") {
122+
if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION){
123+
llStopAnimation(llList2String(AnimsList, n*3+2));
124+
AnimsList = llDeleteSubList(AnimsList, n*3, n*3+2);
125+
n-=1;
126+
layerStop-=1;
127+
}
128+
}
129+
}
130+
}
131+
}
132+
// llSay(0, "anim list:\n" + llList2CSV(llGetAnimationList(av)));
133+
}
134+
else if(num == SEAT_UPDATE){
135+
list seatsavailable = llParseStringKeepNulls(str, ["^"], []);
136+
str = "";
137+
integer stop = llGetListLength(seatsavailable)/8;
138+
Slots = [];
139+
FaceTimes = [];
140+
GotFaceAnim = 0;
141+
for(Seatcount = 1; Seatcount <= stop; ++Seatcount) {
142+
Slots = Slots + [llList2String(seatsavailable, (Seatcount-1)*8), (vector)llList2String(seatsavailable, (Seatcount-1)*8+1),
143+
(rotation)llList2String(seatsavailable, (Seatcount-1)*8+2), llList2String(seatsavailable, (Seatcount-1)*8+3),
144+
(key)llList2String(seatsavailable, (Seatcount-1)*8+4), llList2String(seatsavailable, (Seatcount-1)*8+5),
145+
llList2String(seatsavailable, (Seatcount-1)*8+6), llList2String(seatsavailable, (Seatcount-1)*8+7)];
146+
if(llList2String(seatsavailable, (Seatcount-1)*8+3) != "") {
147+
//we need a list consisting of sitter key followed by each face anim and the associated time of each
148+
//put face anims for this slot in a list
149+
list faceanimsTemp = llParseString2List(llList2String(seatsavailable, (Seatcount-1)*8+3), ["~"], []);
150+
integer facecount = llGetListLength(faceanimsTemp);
151+
list faces = [];
152+
integer nFace;
153+
integer hasNewFaceTime = 0;
154+
for(nFace=0; nFace<facecount; ++nFace) {
155+
//parse this face anim for anim name and time
156+
list temp = llParseString2List(llList2String(faceanimsTemp, nFace), ["="], []);
157+
//time must be optional so we will make default a zero
158+
//queue on zero to revert to older stuff
159+
if(llList2String(temp, 1)) {
160+
//collect the name of the anim and the time
161+
faces += [llList2String(temp, 0), (integer)llList2String(temp, 1)];
162+
hasNewFaceTime = 1;
163+
}
164+
else {
165+
faces += [llList2String(temp, 0), -1];
166+
}
167+
}
168+
GotFaceAnim=1;
169+
//add sitter key and flag if timer defined followed by a stride 2 list containing face anim name and associated time
170+
FaceTimes += [(key)llList2String(seatsavailable, (Seatcount-1)*8+4), hasNewFaceTime, facecount] + faces;
171+
}
172+
}
173+
//we have our new list of AV's and positions so put them where they belong. fire off the first seated AV and run time will do the rest.
174+
for(Seatcount = 0; Seatcount < stop; ++Seatcount) {
175+
if(llList2Key(Slots, Seatcount*8+4) != "") {
176+
if(llListFindList(SeatedAvs(), [llList2Key(Slots, Seatcount*8+4)]) != -1) {
177+
doSeats(Seatcount, llList2String(Slots, (Seatcount)*8+4));
178+
return;
179+
}
180+
}
181+
}
182+
}
183+
else if(num == OPTIONS) {
184+
//save new option(s) from LINKMSG
185+
list optionsToSet = llParseStringKeepNulls(str, ["~","|"], []);
186+
integer length = llGetListLength(optionsToSet);
187+
integer index;
188+
for(; index<length; ++index) {
189+
list optionsItems = llParseString2List(llList2String(optionsToSet, index), ["="], []);
190+
string optionItem = llToLower(llStringTrim(llList2String(optionsItems, 0), STRING_TRIM));
191+
string optionString = llList2String(optionsItems, 1);
192+
string optionSetting = llToLower(llStringTrim(optionString, STRING_TRIM));
193+
integer optionSettingFlag = optionSetting=="on" || (integer)optionSetting;
194+
if(optionItem == "facialexp") {
195+
FacialEnable = optionSettingFlag;
196+
}
197+
}
198+
}
199+
}
200+
201+
run_time_permissions(integer perm) {
202+
ThisAV = llGetPermissionsKey();
203+
//start timer if we have face anims for any slot
204+
if(GotFaceAnim==1) {
205+
llSetTimerEvent(1.0);
206+
}
207+
else {
208+
llSetTimerEvent(0.0);
209+
}
210+
}
211+
212+
timer() {
213+
integer n;
214+
integer SlotStop = llGetListLength(Slots)/8;
215+
key av;
216+
integer facecount;
217+
integer faceindex;
218+
if(FacialEnable) {
219+
for(n=0; n<SlotStop; ++n) {
220+
//doing each seat
221+
av = (key)llList2String(Slots, n*8+4);
222+
faceindex = 0;
223+
//locate our stride in FaceTimes list
224+
integer keyHasFacial = llListFindList(FaceTimes, [av]);
225+
//get number of face anims for this seat
226+
integer newFaceTimeFlag = llList2Integer(FaceTimes, keyHasFacial+1);
227+
228+
if(newFaceTimeFlag == 0) {
229+
//need to know if someone seated in this seat, if not we won't do any facials
230+
if(av != "") {
231+
Faceanims = llParseString2List(llList2String(Slots, n*8+3), ["~"], []);
232+
facecount = llGetListLength(Faceanims);
233+
if(facecount > 0 && (llListFindList(SeatedAvs(), [ThisAV]) != -1)) {//modified cause face anims were being imposed after AV stands.
234+
ThisAV = llGetPermissionsKey();
235+
llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION);
236+
}
237+
}
238+
integer x;
239+
for(x=0; x<facecount; ++x){
240+
if (facecount>0) {
241+
if(faceindex < facecount) {
242+
if(AvLinkNum(av) != -1) {
243+
llStartAnimation(llList2String(Faceanims, faceindex));
244+
}
245+
}
246+
faceindex++;
247+
}
248+
}
249+
}
250+
else if(av != ""){
251+
//need to know if someone seated in this seat, if not we won't do any facials
252+
//do our stuff with defined facial times
253+
facecount = llList2Integer(FaceTimes, keyHasFacial+2);
254+
//if we have facial anims make sure we have permissions for this av
255+
if((facecount > 0) && (llListFindList(SeatedAvs(), [ThisAV]) != -1)) { //modified cause face anims were being imposed after AV stands.
256+
ThisAV = llGetPermissionsKey();
257+
llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION);
258+
}
259+
integer x;
260+
for(x=1; x<=facecount; ++x) {
261+
//non looping we check if anim has run long enough
262+
if(faceindex < facecount) {
263+
integer faceStride = keyHasFacial+1+(x*2);
264+
string animName = llList2String(FaceTimes, faceStride);
265+
if(llList2Integer(FaceTimes, faceStride+1) > 0) {
266+
FaceTimes = llListReplaceList(FaceTimes, [llList2Integer(FaceTimes, faceStride+1)-1],
267+
faceStride+1, faceStride+1);
268+
}
269+
if(facecount>0) {
270+
if(AvLinkNum(av) != -1 && llList2Integer(FaceTimes, faceStride+1) > 0) {
271+
llStartAnimation(animName);
272+
}
273+
else if(AvLinkNum(av) != -1 && llList2Integer(FaceTimes, faceStride+1) == -1) {
274+
llStartAnimation(animName);
275+
}
276+
faceindex++;
277+
}
278+
}
279+
}
280+
281+
}
282+
}
283+
if(llGetListLength(SeatedAvs())<1) {
284+
llSetTimerEvent(0.0);
285+
}
286+
}
287+
}
288+
289+
changed(integer change) {
290+
if(change & CHANGED_LINK) {
291+
integer newPrimCount1 = llGetNumberOfPrims();
292+
if(Newprimcount>newPrimCount1) {
293+
//we have lost a sitter so find out who and remove them from the list.
294+
integer n;
295+
integer LaStop = llGetListLength(Lastanim)/2;
296+
for(; n<LaStop; ++n) {
297+
if(AvLinkNum((key)llList2String(Lastanim, n*2)) == -1) {
298+
integer index = llListFindList(AnimsList, [(key)llList2String(Lastanim, n*2)]);
299+
if(index != -1) {
300+
AnimsList = llDeleteSubList(AnimsList, index, index + 2);
301+
}
302+
Lastanim = llDeleteSubList(Lastanim, n*2, n*2+1);
303+
}
304+
}
305+
}
306+
Newprimcount = newPrimCount1;
307+
}
308+
}
309+
}

0 commit comments

Comments
 (0)