-
Notifications
You must be signed in to change notification settings - Fork 0
/
horse riding.lsl
402 lines (361 loc) · 14 KB
/
horse riding.lsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
// History
// 0.5 added DustIsOn Boolean for streamlining
// 0.4 unknown
// 0.3 duston/dustoff split & anti-push global on/off
// 0.2 dust call & anti-push
// 0.1 fix attach event problem for attach from inventory
// 0.0 create
// globals
// animation to play when attached
string animation = "badhorseriding";
// this set to true will enable the "anti push" code so acts as a minimal push shield
integer anti_push = TRUE;
// time to wait if avatar does not move to "lock" into place.
// ignore if anti_push is false.
float lockwait = 1.0;
// globals for state tracking
integer have_permissions = FALSE;
integer is_attached = FALSE;
integer is_locked = FALSE;
// globals for boolean lists
integer perm_list;
integer control_list;
//integer clipclop;
integer effectFlags=0;
//integer running=1;
integer dustIsOn = FALSE;
// Color Secelection Variables
// Interpolate between startColor and endColor
integer colorInterpolation = 1;
// Starting color for each particle
vector startColor = <.85,.75,.72>;
// Ending color for each particle
vector endColor = <.85,.75,.72>;
// Starting Transparency for each particle (1.0 is solid)
float startAlpha = .5;
// Ending Transparency for each particle (0.0 is invisible)
float endAlpha = 0;
// Enables Absolute color (true) ambient lighting (false)
integer glowEffect = 0;
// Size & Shape Selection Variables
// Interpolate between startSize and endSize
integer sizeInterpolation = 1;
// Starting size of each particle
vector startSize = <.75,.75,0>;
// Ending size of each particle
vector endSize = <4,4,0>;
// Turns particles to face their movement direction
integer followVelocity = 0;
// Texture the particles will use ("" for default)
string texture = "smoke";
// Timing & Creation Variables Variables
// Lifetime of one particle (seconds)
float particleLife = 10;
// Lifetime of the system 0.0 for no time out (seconds)
float SystemLife = 0;
// Number of seconds between particle emissions
float emissionRate = .1;
// Number of particles to releast on each emission
integer partPerEmission = 5;
// Angular Variables
// The radius used to spawn angular particle patterns
float radius = 0;
// Inside angle for angular particle patterns
float innerAngle = 0;
// Outside angle for angular particle patterns
float outerAngle = 2;
// Rotational potential of the inner/outer angle
vector omega = <0,0,0>;
// Movement & Speed Variables
// The minimum speed a particle will be moving on creation
float minSpeed = 0;
// The maximum speed a particle will be moving on creation
float maxSpeed = .5;
// Global acceleration applied to all particles
vector acceleration = <0,0,0>;
// If true, particles will be blown by the current wind
integer windEffect = 1;
// if true, particles 'bounce' off of the object's Z height
integer bounceEffect = 0;
// If true, particles spawn at the container object center
integer followSource = 0;
// If true, particles will move to expire at the target
//integer followTarget = 1;
// Desired target for the particles (any valid object/av key)
// target Needs to be set at runtime
key target = "";
//As yet unimplemented particle system flags
integer randomAcceleration = 0;
integer randomVelocity = 0;
integer particleTrails = 0;
// Pattern Selection
// Uncomment the pattern call you would like to use
// Drop parcles at the container objects' center
//integer pattern = PSYS_SRC_PATTERN_DROP;
// Burst pattern originating at objects' center
//integer pattern = PSYS_SRC_PATTERN_EXPLODE;
// Uses 2D angle between innerAngle and outerAngle
integer pattern = PSYS_SRC_PATTERN_ANGLE;
// Uses 3D cone spread between innerAngle and outerAngle
//integer pattern = PSYS_SRC_PATTERN_ANGLE_CONE;
//
//integer pattern = PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY;
setParticles()
{
// Here is where to set the current target
// llGetKey() targets this script's container object
// llGetOwner() targets the owner of this script
// Feel free to insert any other valid key
target="";
// The following block of if statements is used to construct the mask
if (colorInterpolation) effectFlags = effectFlags|PSYS_PART_INTERP_COLOR_MASK;
if (sizeInterpolation) effectFlags = effectFlags|PSYS_PART_INTERP_SCALE_MASK;
if (windEffect) effectFlags = effectFlags|PSYS_PART_WIND_MASK;
if (bounceEffect) effectFlags = effectFlags|PSYS_PART_BOUNCE_MASK;
if (followSource) effectFlags = effectFlags|PSYS_PART_FOLLOW_SRC_MASK;
if (followVelocity) effectFlags = effectFlags|PSYS_PART_FOLLOW_VELOCITY_MASK;
if (target!="") effectFlags = effectFlags|PSYS_PART_TARGET_POS_MASK;
if (glowEffect) effectFlags = effectFlags|PSYS_PART_EMISSIVE_MASK;
//Uncomment the following selections once they've been implemented
// if (randomAcceleration) effectFlags = effectFlags|PSYS_PART_RANDOM_ACCEL_MASK;
// if (randomVelocity) effectFlags = effectFlags|PSYS_PART_RANDOM_VEL_MASK;
// if (particleTrails) effectFlags = effectFlags|PSYS_PART_TRAIL_MASK;
llParticleSystem([
PSYS_PART_FLAGS, effectFlags,
PSYS_SRC_PATTERN, pattern,
PSYS_PART_START_COLOR, startColor,
PSYS_PART_END_COLOR, endColor,
PSYS_PART_START_ALPHA, startAlpha,
PSYS_PART_END_ALPHA, endAlpha,
PSYS_PART_START_SCALE, startSize,
PSYS_PART_END_SCALE, endSize,
PSYS_PART_MAX_AGE, particleLife,
PSYS_SRC_ACCEL, acceleration,
PSYS_SRC_TEXTURE, texture,
PSYS_SRC_BURST_RATE, emissionRate,
PSYS_SRC_INNERANGLE, innerAngle,
PSYS_SRC_OUTERANGLE, outerAngle,
PSYS_SRC_BURST_PART_COUNT, partPerEmission,
PSYS_SRC_BURST_RADIUS, radius,
PSYS_SRC_BURST_SPEED_MIN, minSpeed,
PSYS_SRC_BURST_SPEED_MAX, maxSpeed,
PSYS_SRC_MAX_AGE, SystemLife,
PSYS_SRC_TARGET_KEY, target,
PSYS_SRC_OMEGA, omega ]);
}
// sample dust functions
duststart(integer is_running) {
// call dust particles
if(is_running) {
// agent is running
llLoopSound("98dc028e-c44b-b17d-4540-c0a7ba026908", 1);
setParticles();
dustIsOn = TRUE;
} else {
llLoopSound("e8a669ca-2400-69e3-693f-f87dd18fa9cd", 1);
}
}
duststop() {
// stop dust particles
llStopSound();
if(dustIsOn) {
llParticleSystem([]);
dustIsOn = FALSE;
}
}
// My own attach event because of bug with attach from inventory not calling attach event
doattach(key attachedAgent) {
// process the attach event
if (attachedAgent != NULL_KEY) {
// we are attached to an agent so set the attached state
is_attached = TRUE;
// Request permission to do stuff from agent
if(!have_permissions) llRequestPermissions(llGetOwner(), perm_list );
} else {
// we are not attached so set the state
is_attached = FALSE;
// if we HAVE permissions then assume we were animating an avatar
// (the avatar just detached us for example)
if (have_permissions) {
// stop animating the avatar
llStopAnimation(animation);
// reliquinsh our permissions (fake but good for state)
have_permissions = FALSE;
}
// turn off the push stuff
llSetTimerEvent(0.0);
// stop damping movement
llMoveToTarget(llGetPos(), 0);
// turn off locking
is_locked = FALSE;
}
}
// the meat of the script
default {
on_rez(integer initparm) {
// reset the script
llResetScript();
}
state_entry() {
// sit from original horse control box
llSitTarget(<0.3,0,0.6>, ZERO_ROTATION);
// set up the state tracking vars to their initial values
dustIsOn = FALSE;
have_permissions = FALSE;
is_attached = FALSE;
is_locked = FALSE;
perm_list = (PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
control_list = (CONTROL_FWD|
CONTROL_BACK|
CONTROL_RIGHT|
CONTROL_LEFT|
CONTROL_ROT_RIGHT|
CONTROL_ROT_LEFT|
CONTROL_UP|
CONTROL_DOWN);
// Fake the attached event because we are attached and attached didn't get called.
if(llGetAttached()>0) doattach(llGetOwner());
}
changed(integer change)
{
if(change & CHANGED_OWNER) // You'd better put the this changed() event when you use llGetOwner
{ // by way of precaution.
llResetScript();
}
}
run_time_permissions(integer permissions) {
// process the permissions requests
if (permissions == perm_list) {
// if we are attached then start the animation and attach to the
// correct point on avatar
if(is_attached) {
// start the animation
llStartAnimation(animation);
llTakeControls(control_list, TRUE, TRUE);
llTriggerSound("a2b85091-b0c8-f77e-2c85-d52624b3081c", 1.0);
}
// start the antipush timer if script calls for it
if(anti_push) llSetTimerEvent(1);
// let everything know we got the permissions we requested
have_permissions = TRUE;
}
}
control(key id, integer level, integer edge) {
// check anti_push state
if(anti_push) {
// if we are locked and this event (control) is called then avatar requested move
// so we have to unlock
if (is_locked) {
// undamp avatar
llMoveToTarget(llGetPos(), 0);
// set locked state to false
is_locked = FALSE;
}
// reset the timer
llResetTime();
}
// check to see if the agent is running
integer running = llGetAnimation(llGetPermissionsKey()) == "Running";
integer landing = llGetAgentInfo(llGetPermissionsKey()) & AGENT_FLYING;
integer jumping = llGetAnimation(llGetPermissionsKey()) == "Jumping";
// now we capture the various controls for any "effects hooks"
if(level>0 && edge>0) {
// these get called because the just got pressed
// they get called once
if(level & CONTROL_FWD) {
// avatar is starting to go forwards
}
if(level & CONTROL_BACK) {
// avatar is starting to go backwards
}
if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) {
// avatar is starting to go right
}
if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT)) {
// avatar is starting to go left
}
if(level & CONTROL_UP) {
// avatar is starting to go up
}
if(level & CONTROL_DOWN) {
// avatar is starting to go down
}
}else if(level>0) {
// these get called because the key is down!
// they get called repeatedly
if(level & CONTROL_FWD) {
// avatar is going forwards
if(!landing & !jumping) duststart(running);
else duststop();
}
if(level & CONTROL_BACK) {
// avatar is going backwards
if(!landing & !jumping) duststart(running);
else duststop();
}
if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) {
// avatar is going right
if(!landing & !jumping) duststart(running);
else duststop();
}
if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT)) {
// avatar is going left
if(!landing & !jumping) duststart(running);
else duststop();
}
if(level & CONTROL_UP) {
// avatar is going up
duststop();
}
if(level & CONTROL_DOWN) {
// avatar is going down
duststop();
}
}else{
// called once when key is up
if(edge & CONTROL_FWD) {
// avatar stopped going forwards
duststop();
}
if(edge & CONTROL_BACK) {
// avatar stopped going backwards
duststop();
}
if(edge & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) {
// avatar stopped going right
duststop();
}
if(edge & (CONTROL_LEFT|CONTROL_ROT_LEFT)) {
// avatar stopped going left
duststop();
}
if(edge & CONTROL_UP) {
// avatar stopped going up
duststop();
}
if(edge & CONTROL_DOWN) {
// avatar stopped going down
duststop();
}
}
}
attach(key attachedAgent) {
// we got attached so call the attach function (we swapped this because
// of a linden script bug where the attach event didn't get called
// when attached from inventory
doattach(attachedAgent);
}
timer() {
// if we are handling anti_push
if(anti_push) {
// check if we are not already locked and we haven't moved since our wait
if ((!is_locked) && (llGetTime() > lockwait)) {
// ok we aren't already locked and it's past the lock interval
// so damp movement on the avatar
llMoveToTarget(llGetPos(), 0.2);
// set the locked state to true
is_locked = TRUE;
}
}
}
}