Script.lsl 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // :CATEGORY:Particle
  2. // :NAME:Particle to Viictim
  3. // :AUTHOR:Ferd Frederix
  4. // :KEYWORDS:
  5. // :CREATED:2014-04-04 22:02:10
  6. // :EDITED:2014-04-04
  7. // :ID:1033
  8. // :NUM:1609
  9. // :REV:1
  10. // :WORLD:Second Life
  11. // :DESCRIPTION:
  12. // Makes particles nto a weapon. Shoots them at avatars you choose from a menu
  13. // :CODE:
  14. string texture;
  15. updateParticles(key target)
  16. {
  17. // MASK FLAGS: set to "TRUE" to enable
  18. integer glow = FALSE; // Makes the particles glow
  19. integer bounce = FALSE; // Make particles bounce on Z plane of objects
  20. integer interpColor = TRUE; // Color - from start value to end value
  21. integer interpSize = TRUE; // Size - from start value to end value
  22. integer wind = FALSE; // Particles effected by wind
  23. integer followSource = TRUE; // Particles follow the source
  24. integer followVel = TRUE; // Particles turn to velocity direction
  25. // Choose a pattern from the following:
  26. // PSYS_SRC_PATTERN_EXPLODE
  27. // PSYS_SRC_PATTERN_DROP
  28. // PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY
  29. // PSYS_SRC_PATTERN_ANGLE_CONE
  30. // PSYS_SRC_PATTERN_ANGLE
  31. integer pattern = PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY;
  32. // PSYS_SRC_PATTERN_EXPLODE;
  33. // PARTICLE PARAMETERS
  34. float age = 5; // Life of each particle
  35. float maxSpeed = 1.0; // Max speed each particle is spit out at
  36. float minSpeed = 1.0; // Min speed each particle is spit out at
  37. float startAlpha = 1.0; // Start alpha (transparency) value
  38. float endAlpha = 1.0; // End alpha (transparency) value
  39. vector startColor = <1.0,1.0,1.0>; // Start color of particles <R,G,B>
  40. vector endColor = <1.0,1.0,1.0>; // End color of particles <R,G,B> (if interpColor == TRUE)
  41. vector startSize = <1.0,1.0,1.0>; // Start size of particles
  42. vector endSize = <1.0,1.0,1.0>; // End size of particles (if interpSize == TRUE)
  43. vector push = <1.0,0.0,0.0>; // Force pushed on particles
  44. // SYSTEM PARAMETERS
  45. float rate = .1; // How fast (rate) to emit particles
  46. float radius = 0.75; // Radius to emit particles for BURST pattern
  47. integer count = 10; // How many particles to emit per BURST
  48. float outerAngle = TWO_PI; // Outer angle for all ANGLE patterns PI/4
  49. float innerAngle = 0.5; // Inner angle for all ANGLE patterns
  50. vector omega = <0,0,0>; // Rotation of ANGLE patterns around the source
  51. float life = 5; // Life in seconds for the system to make particles
  52. // SCRIPT VARIABLES
  53. integer flags;
  54. if (glow) flags = flags | PSYS_PART_EMISSIVE_MASK;
  55. if (bounce) flags = flags | PSYS_PART_BOUNCE_MASK;
  56. if (interpColor) flags = flags | PSYS_PART_INTERP_COLOR_MASK;
  57. if (interpSize) flags = flags | PSYS_PART_INTERP_SCALE_MASK;
  58. if (wind) flags = flags | PSYS_PART_WIND_MASK;
  59. if (followSource) flags = flags | PSYS_PART_FOLLOW_SRC_MASK;
  60. if (followVel) flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK;
  61. if (target != "") flags = flags | PSYS_PART_TARGET_POS_MASK;
  62. llParticleSystem([ PSYS_PART_MAX_AGE,age,
  63. PSYS_PART_FLAGS,flags,
  64. PSYS_PART_START_COLOR, startColor,
  65. PSYS_PART_END_COLOR, endColor,
  66. PSYS_PART_START_SCALE,startSize,
  67. PSYS_PART_END_SCALE,endSize,
  68. PSYS_SRC_PATTERN, pattern,
  69. PSYS_SRC_BURST_RATE,rate,
  70. PSYS_SRC_ACCEL, push,
  71. PSYS_SRC_BURST_PART_COUNT,count,
  72. PSYS_SRC_BURST_RADIUS,radius,
  73. PSYS_SRC_BURST_SPEED_MIN,minSpeed,
  74. PSYS_SRC_BURST_SPEED_MAX,maxSpeed,
  75. PSYS_SRC_TARGET_KEY,target,
  76. PSYS_SRC_INNERANGLE,innerAngle,
  77. PSYS_SRC_OUTERANGLE,outerAngle,
  78. PSYS_SRC_OMEGA, omega,
  79. PSYS_SRC_MAX_AGE, life,
  80. PSYS_SRC_TEXTURE, texture,
  81. PSYS_PART_START_ALPHA, startAlpha,
  82. PSYS_PART_END_ALPHA, endAlpha
  83. ]);
  84. }
  85. // Multi-Page Dialog Menu System
  86. // Omei Qunhua December 2013
  87. integer gActionsPerPage = 9; // Number of action choice buttons per menu page (must be 1 to 10, or 12)
  88. list gListActions ;
  89. list gListKeys;
  90. // ========================================================================================================
  91. integer gTotalActions;
  92. integer gPage; // Current dialog page number (counting from zero)
  93. integer gMaxPage; // Highest page number (counting from zero)
  94. integer gChan; // Channel used for dialog communications.
  95. key gUser; // Current user accessing the dialogs
  96. BuildDialogPage(key user)
  97. {
  98. // Build a dialog menu for current page for given user
  99. integer start = gActionsPerPage * gPage; // starting offset into action list for current page
  100. // set up scrolling buttons as needed
  101. list buttons = [ "<<", " ", ">>" ];
  102. if (gActionsPerPage == 10) buttons = [ "<<", ">>" ];
  103. else if (gActionsPerPage > 10) buttons = []; // No room for paging buttons
  104. // 'start + gActionsPerPage -1' might point beyond the end of the list -
  105. // - but LSL stops at the list end, without throwing a wobbly
  106. buttons += llList2List(gListActions, start, start + gActionsPerPage - 1);
  107. llDialog(user, "\nPage " + (string) (gPage+1) + " of " + (string) (gMaxPage + 1) + "\n\nChoose an action", buttons, gChan);
  108. llSetTimerEvent(60); // If no response in time, return to 'ready' state
  109. }
  110. default
  111. {
  112. state_entry()
  113. {
  114. texture = llGetInventoryName(INVENTORY_TEXTURE, 0);
  115. gTotalActions = llGetListLength(gListActions);
  116. // Validate 'ActionsPerPage' value
  117. if (gActionsPerPage < 1 || gActionsPerPage > 12)
  118. {
  119. llOwnerSay("Invalid 'gActionsPerPage' - must be 1 to 12");
  120. return;
  121. }
  122. // Compute number of menu pages that will be available
  123. gMaxPage = (gTotalActions - 1) / gActionsPerPage;
  124. if (gActionsPerPage > 10)
  125. {
  126. gMaxPage = 0;
  127. if (gTotalActions > gActionsPerPage)
  128. {
  129. llOwnerSay("Too many actions in total for this setting");
  130. return;
  131. }
  132. }
  133. // Compute a negative communications channel based on prim UUID
  134. gChan = 0x80000000 | (integer) ( "0x" + (string) llGetKey() );
  135. state ready;
  136. }
  137. }
  138. state ready
  139. {
  140. touch_start(integer total_number)
  141. {
  142. gUser = llDetectedKey(0);
  143. llSensor("","",AGENT,25.0,TWO_PI); // seek out a person
  144. }
  145. sensor(integer n)
  146. {
  147. integer i;
  148. gListKeys = [];
  149. gListActions = [];
  150. for ( i = 0; i < n; i++)
  151. {
  152. gListActions += llDetectedName(i);
  153. gListKeys += llDetectedKey(i);
  154. }
  155. state busy;
  156. // Changing state sets the application to a busy condition while one user is selecting from the dialogs
  157. // In the event of multiple 'simultaneous' touches, only one user will get a dialog
  158. }
  159. no_sensor()
  160. {
  161. llOwnerSay("No one is near you, range is set at max of 25 meters");
  162. }
  163. }
  164. state busy
  165. {
  166. state_entry()
  167. {
  168. llListen(gChan, "", gUser, ""); // This listener will be used throughout this state
  169. gPage = 0;
  170. BuildDialogPage(gUser); // Show Page 0 dialog to current user
  171. }
  172. listen (integer chan, string name, key id, string msg)
  173. {
  174. if (msg == "<<" || msg == ">>") // Page change ...
  175. {
  176. if (msg == "<<") --gPage; // Page back
  177. if (msg == ">>") ++gPage; // Page forward
  178. if (gPage < 0) gPage = gMaxPage; // cycle around pages
  179. if (gPage > gMaxPage) gPage = 0;
  180. BuildDialogPage(id);
  181. return;
  182. }
  183. if (msg != " ") // no action on blank menu button
  184. {
  185. // User has selected a person from the menu
  186. integer idx = llListFindList(gListActions,[msg]) ;
  187. if ( idx > -1)
  188. {
  189. key aviKey = llList2Key(gListKeys,idx); // get the corresponding key
  190. updateParticles(aviKey);
  191. llOwnerSay("Sending particles to " + msg + " key: " + (string) aviKey);
  192. }
  193. }
  194. state ready; // changing state will release ANY and ALL open listeners
  195. }
  196. timer()
  197. {
  198. llOwnerSay("Too slow, menu cancelled");
  199. state ready;
  200. }
  201. state_exit()
  202. {
  203. llSetTimerEvent(0); // would be dangerous to leave a dormant timer
  204. }
  205. }