http://opensimulator.org/api.php?action=feedcontributions&user=Dz&feedformat=atom
OpenSimulator - User contributions [en]
2024-03-29T14:10:56Z
User contributions
MediaWiki 1.19.9
http://opensimulator.org/wiki/Development_Team/fr
Development Team/fr
2022-07-01T17:10:26Z
<p>Dz: /* Autres développeurs/testers/contributeurs */</p>
<hr />
<div>__NOTOC__ {{Quicklinks|Development_Team}} <br />
<br />
== Core : Développeurs actifs ==<br />
<br />
Les développeurs qui ont un accès commit à notre serveur central, sont [http://www.ohloh.net/projects/4753/contributors des contributeurs réguliers] à la base de code, et ont des droits de vote sur le développement et les questions de processus du projet OpenSimulator. Voir [[Organization|Organisation]]. <br />
<br />
* '''Seuls les développeurs élus sont listés ici. Veuillez ne pas vous inscrire vous-même dans cette liste.'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Nom<br />
! Avatar SL <br />
! Autre grille<br />
! Fuseau horaire<br />(UTC) <br />
! Org <br />
! Centres d'intérêt<br />
|-<br />
| [[User:Diva|Diva]] <br />
| Crista Lopes <br />
| Diva Canto <br />
| Crista Lopes / Diva Canto <br />
| -8 <br />
| University of California, Irvine <br />
| Tout, sauf les bases de données<br />
|-<br />
| [[User:Melanie T|Melanie_T]] <br />
| Melanie <br />
| Melanie Milland <br />
| <br /> <br />
| +1 <br />
| Indépendante<br />
| Scripting, Prims/Scene, La vie, l'univers et tout le reste<br />
|-<br />
<br />
| misterblue<br />
| Robert Adams<br />
| misterblue waves<br />
| misterblue waves<br />
| -8 Oregon, USA<br />
| autonome<br />
| développement de simulateurs, physique (BulletSim), protocole, viewers alternatifs<br />
|-<br />
<br />
| Plugh<br />
| Kevin Cozens<br />
| Andrew Hellershanks<br />
| Andrew Hellershanks<br />
| -5<br />
| Virtual Highway<br />
| Construction, Scripting<br />
|-<br />
<br />
| Ubit<br />
| Leal Duarte<br />
| Ubit Umarov<br />
| Ubit Umarov<br />
| WET (UTC+00) / WEST (UTC+01) <br />
| Indépendant<br />
| <br />
|}<br />
<br />
<br /><br />
<br />
== Core : Développeurs au fil du temps qui suivent le lapin blanc ==<br />
<br />
Développeurs principaux qui sont temporairement (nous l'espérons) partis chasser le lapin blanc. Ils sont en tous points similaires aux développeurs actifs, sauf qu'ils n'ont pas été très actifs ces derniers temps, donc leurs droits de vote attendent leur retour. <br />
<br />
* '''Seuls les développeurs élus sont listés ici. Veuillez ne pas vous inscrire vous-même dans cette liste.'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Nom<br />
! Avatar SL <br />
! Autre grille<br />
! Fuseau horaire<br />(UTC) <br />
! Org <br />
! Centres d'intérêt<br />
|-<br />
<br />
| [[User:Lbsa71|lbsa71]] <br />
| Stefan Andersson <br />
| Tribal Skytower <br />
| OSG:Stefan Andersson<br />TN:Stefan Andersson <br />
| +1 <br />
| [http://tribalmedia.se/ Tribal Media AB] <br />
| Intégration web<br />
|-<br />
<br />
| [[User:MW|MW]] <br />
| Darren <br />
| Wright Juran <br />
| <br />
| 0 <br />
| <br />
| Tout<br />
|-<br />
<br />
| [[User:Adam Frisby|Adam Frisby]] <br />
| Adam Frisby <br />
| Adam Zaius <br />
| <br />
| +8 <br />
| DeepThink Pty Ltd <br />
| Terrain, performance<br />
|-<br />
<br />
| ckrinke <br />
| Charles&nbsp;Krinke <br />
| Charlesk&nbsp;Bing <br />
| <br />
| -8 <br />
| &nbsp; <br />
| Fiabilité/Serveurs de grille/toutes les fonctions<br />
|-<br />
<br />
| [[User:Mikem|mikem]] <br />
| Mike Mazur <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| Indépendant <br />
| Corrections, améliorations des scripts, compilateur LSL<br />
|-<br />
<br />
| [[User:HomerHorwitz|homerh]] <br />
| Homer Horwitz <br />
| Homer Horwitz <br />
| <br /> <br />
| +2 <br />
| Indépendant <br />
| Rev. ingénierie, problèmes de "maintenant, c'est drôle", mais toujours intéressé par toutes les parties du projet.<br />
|-<br />
<br />
| [[User:Nlin|nlin]] <br />
| N Lin <br />
| Standard Drucker <br />
| <br /> <br />
| +9 <br />
| [http://www.3di.jp/en/ 3Di Inc, Japan]<br />http://www.3di.jp/en/ <br />
| Physique, script, plus à venir<br />
|-<br />
<br />
| [[User:Arthursv|arthursv]] <br />
| Arthur Valadares <br />
| <br />
| NONE <br />
| -8 <br />
| University of California, Irvine <br />
| Tests unitaires, plugins de base de données, corrections de bugs, généralités<br />
|-<br />
<br />
| [[User:DrScofield|drscofld]] <br />
| Dirk Husemann <br />
| Dr Scofield <br />
| <br />
| +1 <br />
| [http://xyzzyxyzzy.net/ xyzzyxyzzy.net] <br />
| Fiabilité, protocoles de réseau, inventaire, assets, contrôle à distance, voix, et à peu près tout le reste&nbsp;:-) <br />
|-<br />
<br />
| [[User:Teravus|Teravus]] <br />
| Daniel Olivares <br />
| Teravus Ousley <br />
| <br />
| -5 <br />
| W3z <br />
| Physique &amp; Outils d'administration, Une simulation fonctionnelle.<br />
|-<br />
<br />
| [[User:Chi11ken|chi11ken]] <br />
| Jeff Ames <br />
| Chillken Proto <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
<br />
| [[User:Marck|Marck00]] <br />
| M. Kirsch <br />
| Marck Kjeller <br />
| <br />
| +1 <br />
| Indépendant <br />
| Tout ce qui attire mon attention et que je peux comprendre. <br />
|-<br />
<br />
| [[User:Snoopy2|Snoopy2]] <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
|<br />
| [http://www.dreamlandmetaverse.com/ http://www.dreamlandmetaverse.com/] <br />
| Hébergement de régions et de grilles OpenSim<br />
|-<br />
<br />
| [[User:Justincc|justincc]] <br />
| Justin Clark-Casey <br />
| Lulworth Beaumont <br />
| Justin Clark-Casey (all other grids) <br />
| 0 <br />
| OSVW Consulting<br />[http://justincc.org/blog justincc's OpenSimulator blog] <br />
| Grille, performances &amp; fiabilité, inventaire (avatar et objet), actifs, scènes, OARs, etc. D'une manière générale, mon principal intérêt est de créer une infrastructure sur laquelle d'autres personnes peuvent s'appuyer.<br />
|-<br />
<br />
| [[User:Dslake|dslake]] <br />
| Dan Lake <br />
| Dan Lake <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| Évolutivité, performance, pile réseau.<br />
|-<br />
<br />
| cmickeyb <br />
| Mic Bowman <br />
| Mic Bowman <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
|-<br />
| [[User:BlueWall|BlueWall]] <br />
| James Hughes <br />
| BlueWall Slade <br />
| BlueWall Slade <br />
| -5 <br />
| BlueWall Information Technologies, LLC <br />
| Diverses parties<br />
|-<br />
| [[User:Nebadon|Nebadon]] <br />
| Michael Emory Cerquoni <br />
| Nebadon Izumi <br />
| Nebadon Izumi <br />
| -5 New Jersey <br />
| Oni Kenkon Creations, Encitra, 4Dialog, Avacon<br />
| Construction, script, test<br />
|-<br />
| orenh<br />
| Oren Hurvitz<br />
|<br />
|<br />
| +2<br />
| Kitely<br />
|<br />
|-<br />
| AliciaRaven<br />
| Alicia Richardson <br />
| ClaudiaDLioncourt<br />
| <br />
| 0 GMT<br />
| <br />
|-<br />
<br />
|}<br />
<br />
== Core : Développeurs à la retraite ==<br />
<br />
Développeurs principaux qui ne sont plus directement engagés dans le projet. Merci à jamais pour vos contributions ! <br />
<br />
* '''Seuls les développeurs élus sont listés ici. Veuillez ne pas vous inscrire vous-même dans cette liste'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Nom <br />
! Avatar SL<br />
! Autre grille<br />
! Fuseau horaire <br />(UTC) <br />
! Org <br />
! Centres d'intérêt<br />
|-<br />
| [[User:Babblefrog|babblefrog]] <br />
| Brian McBee <br />
| Dogen Coldstream <br />
| Babblefrog Ballistic (osgrid) <br />
| -8 <br />
| Désorganisé <br />
| &nbsp;<br />
|-<br />
| [[User:Danx0r|danx0r]] <br />
| Dan Miller <br />
| Albert Pascal <br />
| <br />
| -8 <br />
| squiggle.com <br />
| PHEEZIKS; tout<br />
|-<br />
| Tleiades <br />
| &nbsp; <br />
| Tleiades&nbsp;Hax <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Serveurs de grille/base de données<br />
|-<br />
| [[User:Darok|Darok]] <br />
| &nbsp; <br />
| Darok Kaminski <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Moteurs physiques (notamment BulletX)<br />
|-<br />
| Gareth / Gwen <br />
| Gareth Nelson <br />
| Gareth Ellison <br />
| Gareth Nelson (on everywhere but SL) <br />
| BST (UTC+1) <br />
| Litesim Ltd <br />
| Serveurs de grille, passage de frontière de simulation, animations d'avatars<br />
|-<br />
| [[User:Dalien|dalien]] <br />
| Dalien Talbot <br />
| Dalien Talbot <br />
| <br />
| +1 <br />
| Mostly TCP-based <br />
| Petites corrections ; rév.eng./prototyping ; nightlies ; git-keeper<br />
|-<br />
| [[Alondria]] <br />
| <br />
| Alondria LeFay <br />
| Alondria LeFay (OSGrid) <br />
| -8 <br />
| Indépendant <br />
| Mise en œuvre de fonctions LSL et d'autres éléments de script.<br />
|-<br />
| [[User:SeanDague|sdague]] <br />
| Sean Dague <br />
| Neas Bade <br />
| <br />
| -5 <br />
| IBM <br />
| Base de données, Linux, Test, Divers<br />
|-<br />
| [[User:MingChen|MingChen]] <br />
| Mike/Michael Ortman <br />
| Ming Chen <br />
| <br />
| -6 (-5 in Summer) <br />
| DeepThink Pty Ltd <br />
| Estate/Parcel Support/Modules/Garder tout en ordre et clair<br />
|-<br />
| [[User:Tedd|Tedd]] <br />
| Tedd Hansen <br />
| Tedd Maa <br />
| <br />
| +1 <br />
| Tedd Hansen <br />
| Programmation/Scénario/Architecture<br />
|-<br />
| [[User:Adjohn|adjohn]] <br />
| Adam Johnson <br />
| Zeuz Zenovka <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Joha1|joha1]] <br />
| Johan Berntsson <br />
| Joppi Brandenburg <br />
| <br /> <br />
| +9 <br />
| &nbsp; <br />
| Performances, traitement des paquets/libSL<br />
|-<br />
| jhurliman <br />
| John Hurliman <br />
| John Hurliman <br />
|<br />
|<br />
|<br />
|<br />
|-<br />
| [[User:Dahlia|dahlia]] <br />
| T. Hoff <br />
| Dahlia Trimble <br />
| <br />
| -8 / -7 <br />
| Indépendant <br />
| Géométrie des collisions, divers problèmes mathématiques et physiques, corrections occasionnelles de bogues et améliorations diverses.<br />
|-<br />
| [[User:Fly-man-|Fly-Man-]] <br />
| Laurence <br />
| <br />
| OSGrid: Fly Man <br />
| GMT +1 <br />
| Société privée<br />
| Tests, OpenSimSearch, OpenSimProfile<br />
|-<br />
|}<br />
<br />
== Les administrateurs de wiki ==<br />
<br />
Avec les développeurs principaux, ces personnes aident à gérer le wiki d'OpenSimulator et apportent d'autres contributions (voir Domaines d'intérêt). <br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Nom <br />
! Avatar SL <br />
! Autre grille<br />
! Fuseau horaire<br />(UTC) <br />
! Org <br />
! Centres d'intérêt<br />
|-<br />
| [[User:Makopoppo|Makopoppo]] <br />
| Makiko Nomura <br />
| Mako Nozaki <br />
| Everywhere <br />
| +9 Tokyo, Japan <br />
| En tant que développeur individuel <br />
| Tout pour améliorer la convivialité et la connectabilité - gestion des wikis et des problèmes, documentation, localisation (japonais), modification de l'interface, principalement des modules de base.<br />
|-<br />
| [[User:Fritigern|Fritigern]] <br />
| S-E-C-R-E-T <br />
| Fritigern Gothly <br />
| SecondLife, OSGrid <br />
| +1 GMT <br />
| <br />
| Mes intérêts sont nombreux et extrêmement variés. Une chose qui m'intéresse beaucoup, c'est de voir OpenSimulator grandir, mûrir et se développer pour devenir quelque chose qui rivalise vraiment avec SL/LL.<br />
|}<br />
<br />
== Autres développeurs/testers/contributeurs ==<br />
<br />
Ces personnes ont contribué et/ou contribuent à des rapports de bogues, des correctifs, des tests, et toutes sortes d'autres goodies au projet. <br /> '''Les nouveaux arrivants sont priés de s'ajouter en bas de la liste sur la page en anglais en premier !''' <br /><br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
<br />
! IRC Nick <br />
! Nom<br />
! Avatar SL <br />
! Autres grilles <br />
! Fuseau horaire<br />(UTC) <br />
! Org <br />
! Centres d'intérêt<br />
|-<br />
| [[User:Jtclark48|jclark4]] <br />
| Jay Clark <br />
| Jay Clarke <br />
| <br />
| -5 <br />
| IBM <br />
| Physique, hébergeur de grille, IA, script, tests<br />
|-<br />
| [[User:AdamStevenson|BigFootAg]] <br />
| Adam Stevenson <br />
| Adamus Petrov <br />
| <br />
| -6 <br />
| Texas A&amp;M University <br />
| IA, Skynet, Systèmes évolutifs, Biologie<br />
|-<br />
| [[User:Jeff1564|Jeff1564]] <br />
| Jeff <br />
| Potter Taurog <br />
| Potter Taurog <br />
| -8 <br />
| http://myopengrid.com <br />
| Construction, script, test<br />
|-<br />
| Rock_Vacirca <br />
| Colin Withers <br />
| Rock Vacirca <br />
| &nbsp; <br />
| +1 <br />
| http://rock-vacirca.blogspot.com <br />
| Test, construction, script, maintenance d'un blog opensim.<br />
|-<br />
| simsim <br />
| caocao <br />
| &nbsp; <br />
| &nbsp; <br />
| +9 <br />
| &nbsp; <br />
| Tester toutes les fonctions du système OpenSimulator, travailler avec OpenSim-Engine, faire un rapport sur OpenSimulator.<br />
|-<br />
| [[User:Vicero Lambert|Vicero Lambert]] <br />
| &nbsp; <br />
| &nbsp; <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
| [[User:Magi|Magi]] <br />
| Andy Agnew <br />
| Magi Merlin <br />
| <br />
| +10 <br />
| Spun Pty Ltd <br />
| Intégration Web 3D, base de données et jeux (the odds and ends box.)<br />
|-<br />
| [[User:ClarkZone|ClarkZone]] <br />
| Troy Admin(@ClarkZone) <br />
| Troy Childs <br />
| Troy Admin (ClarkZone) <br />
| -5 <br />
| Http://clarkzone.dyndns.org <br />
| Testeur et hérgement de grille<br />
|-<br />
| [[User:Aiaustin|aiaustin]] <br />
| Ai Austin <br />
| Ai Austin <br />
| Ai Austin <br />
| +0 <br />
| AIAI, Virtual University of Edinburgh<br />http://www.aiai.ed.ac.uk/~ai/<br />http://vue.ed.ac.uk/openvue/ <br />
| Tests Windows<br />Tests de contenu<br />Utilisation de plusieurs VWs<br />
|-<br />
| Marc Manders <br />
| Marc Manders <br />
| &nbsp; <br />
| &nbsp; <br />
| +6 <br />
| marcmanders@gmail.com <br />
| Fonctionnalités créatives<br />
|-<br />
| [[User:Balthazar|balthazar]] <br />
| Trevor Brooks <br />
| Balthazar Sin <br />
| <br />
| -5 <br />
| None <br />
| Terrains, tests et quelques petites tâches de codage<br />
|-<br />
| [[User:Jimbo2120|jimbo2120]] <br />
| Michael Osias <br />
| Illuminous Beltran <br />
| <br />
| -5 <br />
| IBM <br />
| Grille, IA, Skynet, codage et tests<br />
|-<br />
| ZeroPoint <br />
| &nbsp; <br />
| Guilderoy&nbsp;Dench <br />
| <br />
| -5 <br />
| &nbsp; <br />
| Programmation/Base de données<br />
|-<br />
| [[User:DerekTang|DerekTang]] <br />
| Derek Tang <br />
| Derek Timeless <br />
| Derek Tang (ChineseGrid) <br />
| +8 <br />
| http://ChineseGrid.net <br />
| Exécution d'une simulation publique WINDOWS pour les tests, Docs, Aider les utilisateurs chinois à profiter d'OpenSim ; construire des communautés chinoises d'OpenSimulator. En construction...<br />
|-<br />
| [[User:TayB|TayB]] <br />
| Earl Balai <br />
| Taylor Dae <br />
| <br />
| -10 <br />
| WhynGrid <br />
| Grid Host, Networking, Contributions &amp ; Testing.<br />
|-<br />
| [[User:JamieDav|JamieDav]] <br />
| Jamie David <br />
| Jamie David <br />
| <br />
| +7 <br />
| Forum <br />
| Grille, Sim, Avatar, Fonctionnalité<br />
|-<br />
| [[User:Krtaylor|Krtaylor]] <br />
| Kurt Taylor <br />
| Kurt Stringer <br />
| <br />
| -6 <br />
| IBM <br />
| Grille, mise en réseau, monitoring, scripting, inventaire, tests<br />
|-<br />
| [[User:Nink|Nink]] <br />
| Peter Finn <br />
| Nink Noonan <br />
| <br />
| -5 <br />
| IBM <br />
| Influence perturbatrice.<br />
|-<br />
| [[User:Bruce|Bruce]] <br />
| Bruce Meerson <br />
| Bruce Meerson <br />
| <br />
| +8 <br />
| HiPiHi <br />
| Surveillance.<br />
|-<br />
| [[User:Darb|DarbD]] <br />
| Brian B. Quinn <br />
| Darb Dabney <br />
| regions<br />near Marin <br />
| PST/SLT (-7 or -8) <br />
| County of Marin, California<br /> http://blog.3dmap.me <br />
| Sculptures basées sur LiDAR, terrain réel, <br />poursuite des paraverses civiques, centres d'opérations d'urgence virtuels.<br />
|-<br />
| [[User:Charlie Omega|CharlieO]] <br />
| Dan <br />
| Charlie Omega <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| Codage léger/réglage/ajouts de fonctionnalités simples, tests de stress/rupture, test des limites du code existant. S'assurer que le [[Statut LSL]] est à jour.<br />
|-<br />
| oobscure <br />
| &nbsp; <br />
| Opensource Obscure <br />
| <br />
| +1 <br />
| http://www.opensim.it <br />
| Exécution d'une simulation Linux publique pour les tests, Docs, Aide aux utilisateurs italiens, Création de communautés opensim, Surveillance<br />
|-<br />
| pitman <br />
| Mike Pitman <br />
| Rez Tone <br />
| <br />
| &nbsp; <br />
| IBM <br />
| Schémas de visualisation scientifique, conception du produit virt world, espaces de travail persistants, big biz basé sur virt world<br />
|-<br />
| Shenlei <br />
| Shenlei Winkler <br />
| Shenlei Flasheart, Shenlei Winkler <br />
| <br />
| &nbsp; <br />
| Fashion Research Institute <br />
| Conception et développement de produits, industrie du vêtement, et o oui, j'ai écrit le livre&nbsp; ;)<br />
|-<br />
| cmu <br />
| Christopher Mumme <br />
| Snook Destiny <br />
| <br />
| +1 <br />
| http://www.cmu-develop.de/ and research group "Collaboration Systems and CSCW" at Clausthal University of Technology <br />
| Test d'OpenSim, travail avec OpenSim-Engine, rapport sur OpenSimulator<br />
|-<br />
| [[Silpol]] <br />
| Andriy Tymchenko <br />
| Andy Tir <br />
| <br />
| EET (+2/3) <br />
| http://silpol.blogspot.com/ (also visible at Nokia) <br />
| Une pagaille hautement désordonnée avec des éléments de jeux de palais, de diplomatie sous la table, de rébellion, de coup d'état et de mutinerie. pirate en option.<br />
|-<br />
| [[User:Grumly|Grumly]] <br />
| <br />
| Forest Klaar <br />
| Grumly TheBear <br />
| GMT+1 <br />
| .NET MCAD Dev/Arch/Trainer http://www.devoteam.com <br />
| J'essaie d'entrer dans le code d'OpenSimulator pour le moment. Je suis particulièrement intéressé par la persistance des données. blog (Hello, Avatar !): http://lslblog.free.fr<br />
|-<br />
| [[User:DaTwitch|DaTwitch]] <br />
| James G. Stallings II <br />
| <br />Lazarus Longstaff <br />
| Hiro Protagonist (OSGrid) <br />
| -5 <br />
| Homme au foyer<br />
| Propriétaire de la région OSGrid, opérateur OSGrid, administrateur du forum, éditeur du wiki à certains moments.<br />
|-<br />
| gryc <br />
| Gryc Ueusp <br />
| Gryc Uriza <br />
| Gryc Uriza(OSGrid) <br />
| -6 <br />
| <br />
| Scripting PHP, interfaces web, interconnectivité, multiplateforme.<br />
|-<br />
| [[User:Phrearch|Phrearch]] <br />
| Jeroen van Veen <br />
| Phrearch Miles <br />
| Phrearch Miles(OSGrid) <br />
| Amsterdam/Paris <br />
| <br />
| HWIOS, WiXTD, Wikidoc, Moo, Interfaces utilisateur<br />
|-<br />
| [[User:Burnman|Burnman]] <br />
| Allen <br />
| Burnman Bedlam <br />
| <br />
| Boston, USA <br />
| <br />
| Des tests, des tests et encore des tests ! Se familiariser avec la source, s'intéresser à tous les aspects du projet.<br />
|-<br />
| [[User:Krisbfunk|krisbfunk]] <br />
| Kris Bulman <br />
| Krisbfunk Vought <br />
| Krisbfunk Nocturnal(OSGrid) <br />
| PE, Canada (-4) <br />
| Edactive Technologies<br />NocturnalEye Productions<br />UPEI <br />
| Actuellement : Tests, rapports de bogues, mise à jour du wiki, construction d'OSGrid.<br />
|-<br />
| [[User:HashBox|HashBox]] <br />
| &nbsp; <br />
| Sibariel Darkstone <br />
| Sibariel Darkstone (OSGrid) <br />
| New Zealand (+12) <br />
| <br />
| Tests, rapports de bogues, et mise à jour du wiki.<br />
|-<br />
| [[User:Kinoc|Kinoc]] <br />
| Kino Coursey <br />
| Daxxon Jaxxon <br />
| Daxxon Kinoc (OSgrid) <br />
| -6 <br />
| Daxtron Laboratories <br /> http://www.daxtron.com<br /> University of North Texas <br />
| IA, Web sémantique, Ontologies, Traitement du langage naturel, Cyc, Bots, NPC<br />
|-<br />
| [[User:Trapuh|trapuh]] <br />
| Pedro Ribeiro <br />
| Vaiten Forder <br />
| <br />
| GMT <br />
| University Student, Escola Superior de Educação de Viseu, Portugal <br />
| Tests, rapports de bogues éventuels et wiki. Musique, web/arts numériques et php+sql.<br />
|-<br />
| [[User:SonicViz|SonicViz]] <br />
| Paul Cohen <br />
| Komuso Tokugawa <br />
| <br />
| +9 <br />
| Http://sonicviz.com <br />
| Audio/Musique, Musique interactive, Protocoles de contrôle, Interfaces, VisualFX, Animation procédurale/Systèmes génératifs + tests et développement général<br />
|-<br />
| [[User:Mokele|mokele]] <br />
| Scott Norman <br />
| Mokelembembe Mokeev <br />
| <br />
| -8 (Southern California) <br />
| Web Developer (PHP and MySQL) <br />
| Intéressé à voir fonctionner sur les Macs PowerPC, ce qui est le cas. Donc, quand je peux, je compilerai et testerai sur un Mac PowerPC (PowerBook G4) et soumettrai des rapports, puis mettrai à jour le wiki si nécessaire sur l'installation sur Mac. J'ai aussi un serveur Ubuntu 7.10 sur lequel je peux faire des tests.<br />
|-<br />
| [[User:Devalnor|devalnor]] <br />
| Devalnor <br />
| M. Watkin <br />
| <br />
| +1 (Belgium) <br />
| <br />
| Petit Patch, rapports de bogues, et mise à jour du wiki.<br />
|-<br />
| [[User:Ezekiel|Ezekiel]] <br />
| Ezekiel <br />
| Ezekiel Zabelin <br />
| <br />
| +1 <br />
| http://www.yosims.com <br />
| Concepts, aspects commerciaux des mondes virtuels - développeur web (PHP, MySQL, Javascript, LSL)<br />
|-<br />
| [[User:Buggmaster|Buggmaster]] <br />
| Mike D <br />
| Bug Master <br />
| None <br />
| -8 <br />
| http://www.adultmetaverse.com <br />
| Grille, données/web PHP/PERL/MySQL<br />
|-<br />
| [[User:Nixnerd|nixnerd]] <br />
| <br />
| Dangerously Moody <br />
| None <br />
| GMT <br />
| http://www.integratedtechnologies.eu <br />
| Tests multiplateformes, commentaires, rapports de bogue<br />
|-<br />
| [[User:MoHax|mohax]] <br />
| Mo Hax <br />
| Mo Hax <br />
| <br />
| -5 Eastern <br />
| IBM <br />
| Tests, retours d'information, contributions au contenu, rapports de bogue, documentation, développement.<br />
|-<br />
| [[User:Webmage|webmage]] <br />
| webmage <br />
| Leyla Masala <br />
| Web Mage <br />
| +1 <br />
| IBM <br />
| Test, terrain<br />
|-<br />
| [[User:NLStitch|NLStitch]] <br />
| Marijn Oosterveld <br />
| Stitch Seale <br />
| NYA <br />
| GMT +1 Amsterdam <br />
| Twingate Systems (http://www.twingate.nl)<br />HanzeHogeschool Groningen, Netherlands <br />
| Programmation, photographie, IA<br />
|-<br />
| [[User:Ideia Boa|Ideia Boa]] <br />
| Joao Lopes <br />
| Ideia Boa <br />
| Ideia Boa ou Boa Ideia sur certaines grilles <br />
| GTM+1 Stockholm/Sweden <br />
| WorldSimTERRA - Un monde virtuel qui parle aussi le portugais<br />http://www.worldsimterra.com <br />
| Des tests et encore des tests ! Mise à jour du wiki original et traduction du wiki OpenSimulator en portugais et rapport sur OpenSimulator<br />
|-<br />
| [[User:Lulurun|lulurun]] <br />
| liu <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| 3Di Inc, Japan <br />http://www.3di.jp <br />
| Correctifs, openid, performance des serveurs, UGAI<br />
|-<br />
| [[User:Carlosroundel|Carlosrounde]] <br />
| Carlosroundel <br />
| Carlos Roundel <br />
| <br /> <br />
| +1 <br />
| Cyberlandia Italy<br />http://www.cyberlandia.net <br />
| Grille, programmeur, base de données, testeur<br />
|-<br />
| [[User:Mikebert|Mikebert]] <br />
| Mike<br />
| Mikebert Miles <br />
| Mikebert<br />
| +1 <br />
| OpenSIM Wiki, Germany<br />https://www.mikebert.de/archiv/opensim<br />
| Wiki allemand, traducteur, performance du serveur (Linux/Windows), testeur, commentaires, rapports de bogues, hébergement de serveurs.<br />
|-<br />
| Taoki <br />
| Mircea Kitsune / Taoki Vixen <br />
| Mircea Kitsune (OSGrid) / Mircea Lobo (LL grid) <br />
| <br /> <br />
| GMT +2 <br />
| <br /> <br />
| En général, je fais des tests et signale les bogues, mais je fais aussi des correctifs plus petits lorsque je sais ce qu'il faut faire.<br />
|-<br />
| [[User:Patnad|Patnad]] <br />
| Patrick <br />
| Patnad Babii <br />
| Patnad Babii (OSGrid) <br />
| GMT -5 <br />
| RezzMe Technologies<br />http://www.rezzme.com <br />
| Test et rapport de bogues, je code C# et j'ai soumis quelques correctifs.<br />
|-<br />
| [[User:^DarkMan|^DarkMan]] <br />
| Brian Adair <br />
| Patrick Ouachita <br />
| Brian Adair &#124; Patrick Meta <br />
| -6 CST <br />
| RealMetaLife &#124; B&amp;H Networking <br />
| Construction, script, test, etc.<br />
|-<br />
| [[User:Tlaukkan|Tommi Laukkanen]] <br />
| Tommi Laukkanen <br />
| &nbsp; <br />
| Tommi Laukkanen <br />
| +2 GMT <br />
| http://www.bubblecloud.org <br />
| Protocoles ([http://www.bubblecloud.org MXP]), NHibernate, API Scrip, génération de cartes, corrections de bogues, hébergement de grilles<br />
|-<br />
| [[User:Mystical|Mystical]] <br />
| Kevin Tweedy <br />
| Mystical Demina <br />
| Mystical Demina <br />
| -5 <br />
| Extreme Reality Grid<br />http://www.XRGrid.com <br />
| Windows Communication Framework, Windows Workflow, Entity Framework, MSSQL<br />Améliorations, commerce, contenu, portail basé sur DotNetNuke, services de développement.<br />
|-<br />
| [[User:Godfrey|Godfrey]] <br />
| Jeff Lee <br />
| Warin Cascabel <br />
| <br />
| -5 (EST5EDT) <br />
| <br />
| Tests, corrections de bugs mineurs. Scripting, construction, animation<br />
|-<br />
| Jamenai <br />
| Christopher Händler <br />
| Jamenai Luik <br />
| Jamenai Luik <br />
| +1 <br />
| Playneko Grid &#124; XIMDEX Jamenai<br />http://www.playneko.de<br />http://www.ximdex.de <br />
| Performance, rapports de bogues, hébergement, Grid-Owner, (PHP, MySQL, Perl, JavaScript, LSL)<br />
|-<br />
| [[User:Bikcmp|bikcmp]] <br />
| Jason <br />
| Jake1500 Allen <br />
| Jason Helios (The Helios Grid) <br />
| EST <br />
| Blue Software <br />
| Recherche, groupes, terrains et monnaie<br />
|-<br />
| [[User:Mark.malewski|Slipaway]] <br />
| Mark Malewski <br />
| Chris Rock <br />
| <br />
| -6 (-5 during summer - CDT) <br />
| NexTECH / Joopla <br />
| Développement web &amp; intégration de systèmes, terrain, documentation WIKI, tutoriels, tests, rapports de bogues et feedback.<br />
|-<br />
| barakademi <br />
| Steve Topp <br />
| barakademi Barzane <br />
| same avi on baragrid OSgrid Grid4us sciencesim <br />
| utc+1 (CET) paris <br />
| http://xbot-sl.barakademi.org http://vps.barakademi.org/oswi http://vps.barakademi.org/oswi/loginscreen.php <br />
| Music LiveMusic MetaverseMusic Opensim Libomv Mono-2.4 Linux (suse,debian,ubuntu) Admin Scripting Automatisation Développement Intégration php mysql bash nant +++<br />
|-<br />
| [[User:Robert d|robert_d]] <br />
| Robert Dzikowski <br />
| <br />
| OSGrid: robert_d 13 <br />
| UTC+1 <br />
| [http://blog.rd-it.net http://blog.rd-it.net] <br />
| Modules régionaux, Tutoriels<br />
|-<br />
| john_ <br />
| John&nbsp;Moyer <br />
| VAJohn&nbsp;GeekSquad or&nbsp;Matthew&nbsp;Kendal <br />
| <br />
| -5 <br />
| Best&nbsp;Buy/Geek&nbsp;Squad <br />
| Testeur<br />
|-<br />
| [[User:W!cKeD|_WicKeD]] <br />
| Maik <br />
| Maik Galaxy <br />
| El Diablo <br />
| +1 Germany <br />
| Creatio Inc. / [http://www.OpenSimGerman.us/ OpenSimGerman.us] <br />
| Support allemand, Traducteur, Construction, Script, Test, Hébergement<br />
|-<br />
| [[User:Stevie Wakowski|Stevie Wakowksi]] <br />
| Steve Roberts <br />
| Stevie Wakowski <br />
| <br />
| +10 Australia <br />
| IBM <br />
| Constructions d'OpenSimulator, Linux, Modrex, rapports de bogues, évangéliste pour OpenSimulator dans les applications professionnelles.<br />
|-<br />
| Revolution <br />
| Matthew <br />
| Revolution Smythe <br />
| Revolution Smythe <br />
| -6 Central USA <br />
| None <br />
| Moteur de script, moteur physique, bugs généraux et bizarres, choses intéressantes et bizarres...<br />
|-<br />
| [[User:ClemsonGS|clemsonGS]] <br />
| Brian Cass <br />
| BC Sands <br />
| Brian Cass (VWC Grid) <br />
| -5 <br />
| http://www.cvwconline.org/ <br />
| Développer des mondes virtuels pour l'enseignement supérieur<br />
|-<br />
| <br />
| AlexRa <br />
| <br />
| <br />
| <br />
| Independent <br />
| <br />
|-<br />
| <br />
| <br />
| Mikko Pallari <br />
| <br />
| <br />
| Realxtend <br />
| <br />
|-<br />
| <br />
| StrawberryFride <br />
| Chris Hart <br />
| <br />
| <br />
| ReactionGrid <br />
| <br />
|-<br />
| [[User:RemedyTomm|RemedyTomm]] <br />
| Tom Grimshaw <br />
| Tomm Remedy <br />
| KGrid: Casper Warden OSGrid: Tomm Remedy <br />
| UTC+0 (BST) <br />
| Remedy Communications <br />
| Pipeline de textures, Groupes, ObjectUpdates<br />
|-<br />
| <br />
| <br />
| Rob Smart <br />
| <br />
| <br />
| IBM <br />
| <br />
|-<br />
| MicheilMerlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| -6 <br />
| Indépendant <br /> [http://www.iliveisl.com/ http://www.iliveisl.com/] <br />
| Scripting, correctifs et scénarios de test<br />
|-<br />
| Pato Donald <br />
| Pato Donald <br />
| Morgam Biedermann <br />
| Pato Donald <br />
| -3 <br />
| Indépendant [http://www.matheusmk3.co.cc/ http://www.matheusmk3.co.cc/ <br />
| Groupes, Scripts, Physique, Communication, Intégration<br />
|-<br />
| <br />
| Sera Marx <br />
| Darkfire Soulstar <br />
| <br />
| +12 <br />
| Radiance promotions <br />
| Grid Host<br />
|-<br />
|[[User:dz|dz]] <br />
| D Osborn <br />
| ydoo magic<br />
| delta zed @ OSGRID D Osborn @ ScienceSim & MOSES grids<br />
| PST/SLT (-7 or -8) <br />
| CEO OpenSimian <br />
| Tests de performance, scripts avancés, constructions à grand nombre de prim, bots côté client et côté serveur, remplacement d'animations, maintenance de MANTIS.<br />
|-<br />
| [[User:Hallow Palmer|Hallow Palmer]] <br />
| Markus <br />
| Hallow Palmer <br />
| <br /> <br />
| +1 <br />
| Grid4Us<br />http://www.grid4us.net <br />
| Performance des serveurs (Windows), Testeur, Feedback, Concepts d'affaires, Rapport de bogue, Hébergement de serveurs<br />
|-<br />
| [[User:LenaVanilli|LenaVanilli]] <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| +1 Germany <br />
| [http://www.hypergrid.org http://www.hypergrid.org] <br />
| Gestion du réseau, Test, Test, Test, Hébergement de régions<br />
|-<br />
| [[User:Aduffy70|aduffy70]] <br />
| Aaron Duffy <br />
| Aeran Stipe <br />
| Aaron Duffy @ScienceSim <br />
| -7 <br />
| USU <br />
| Visualisation scientifique et éducation, modules de régions, régions fortement scénarisées.<br />
|-<br />
| <br />
| Erich Bremer <br />
| Erich Bremer <br />
| <br />
Erich Bremer@OSGrid <br />
<br />
| -5 <br />
| http://www.ebremer.com <br />
| Web sémantique, visualisation de données<br />
|-<br />
| [[User:MarkIDCAS|MarkIDCAS]] <br />
| Mark Bannon <br />
| Mark IDCAS <br />
| 3D Grid Association, AtMeeting, Valhalla Virtual and IDCAS. <br />
| GMT <br />
| [http://www.valhallavirtual.com http://www.valhallavirtual.com] <br />
| Gestion des grilles et intégration des systèmes. Scripting. Documentation WIKI, didacticiels, rapports de bogues et commentaires.<br />
|-<br />
| [[User:Allquixotic|allquixotic]] <br />
| Sean McNamara <br />
| Tiyuk Quellmalz <br />
| OSG: Tiyuk Quellmalz <br />
| -5 <br />
| None <br />
| Correction de bogues ; mise en réseau ; performances ; intégrité des données ; LSL ; sauvegarde automatique ; BD nulle (cohérence éventuelle).<br />
|-<br />
| [[User:Orenh|orenh]] <br />
| Oren Hurvitz <br />
| <br />
| Oren Hurvitz (Kitely) <br />
| +2 <br />
| Kitely <br />
| <br />
|-<br />
<br />
| [[User:Randomhuman|randomhuman]] <br />
| Kevin Houlihan <br />
| random Radikal <br />
| random human (OSGrid) <br />
| WET/IST <br />
| CrimsonCookie <br />
| Module RemoteAdmin ; grilles à la demande ; intégration web.<br />
|-<br />
<br />
| [[User:Oddball Otoole|oddball otoole]]<br />
| J.v.Hogeloon<br />
| Oddball Otoole<br />
| Oddball Otoole (OSGrid<br />
| +1 (The Netherlands<br />
| None<br />
| Construction, script, test, activités sociales.<br />
|-<br />
| [[User:Pixel|Pixel Tomsen]]<br />
| Christian Kurzhals<br />
| Pixel Tomsen<br />
| Pixel Tomsen OSGrid<br />
| +1 (Germany<br />
| Voir mon profil<br />
| Dev, Building, scripting, sim-hosting, certains modules, patches, osgrid<br />
|-<br />
| [[User:kenearlg|kenearlg]]<br />
| Ken Grunke<br />
| Key Grau<br />
| Key Gruin (Osgrid)<br />
| -6 CST<br />
| http://www.osgrid.org/<br />
| test, modération, jeux et loisirs inworld, contrôle du spam wiki<br />
|-<br />
| [[User:CG4Life|CG4Life]]<br />
| CG Anderson<br />
| Cyn Hak<br />
| <br />
| -8 PST<br />
| Little Dogs Media<br />
| Mise en réseau, sécurité, performances (parallélisation, compression, cryptage), physique, manipulation 3D, correction de bugs, documentation. Je viens juste d'entrer dans la base de code, donc je commencerai par des idées de compression/parallélisation et la correction de bugs, puis d'autres choses plus tard.<br />
|-<br />
| [[User:vegaslon|vegaslon]]<br />
| Adam Ivie<br />
| vegaslon plutonian<br />
| <br />
| -5 EST<br />
| Independent <br />
| Physique, véhicules, scripts avancés, tests, utilisation avancée du terrain.<br />
|-<br />
<br />
| [[User:AliciaRaven|AliciaRaven]] <br />
| Alicia Richardson <br />
| ClaudiaDLioncourt<br />
| Alicia Raven (Spellscape) <br />
| 0 GMT<br />
| Spellscape Ltd<br />http://www.spellscape.co.uk<br />
|<br />
|-<br />
<br />
| [[User:Djphil|djphil]] <br />
| Philippe Lemaire <br />
| dj phil<br />
| dj phil<br />
| +2 GMT<br />
| Collab 3D Asbl<br />
| Tests, scripts, aide<br />
<br />
|-<br />
| [[User:Steevithak|Steevithak]]<br />
| Steve Rainwater<br />
| Steevithak<br />
| Steevithak x (OSgrid)<br />
| -6/-5 (CST/CDT)<br />
| Indépendant, [https://steevithak.com steevithak.com]<br />
| évolutivité, performances, protocoles, tout le reste. Aussi MediaWiki<br />
<br />
|}<br />
<br />
[[Category:Development]]<br />
[[Category:French Translations]]</div>
Dz
http://opensimulator.org/wiki/Development_Team
Development Team
2022-07-01T17:01:04Z
<p>Dz: /* Additional Developers/Testers/Contributors */</p>
<hr />
<div>__NOTOC__ {{Quicklinks}} <br />
<br />
== Active Core Developers ==<br />
<br />
Developers who have commit access to our central server, are [http://www.ohloh.net/projects/4753/contributors regular contributors] to the codebase, and have voting rights over development and process issues of the OpenSimulator project. See [[Organization]]. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Diva|Diva]] <br />
| Crista Lopes <br />
| Diva Canto <br />
| Crista Lopes / Diva Canto <br />
| -8 <br />
| University of California, Irvine <br />
| Everything, except databases<br />
|-<br />
| [[User:Melanie T|Melanie_T]] <br />
| Melanie <br />
| Melanie Milland <br />
| <br /> <br />
| +1 <br />
| Independent <br />
| Scripting, Prims/Scene, Life, The Universe, and Everything<br />
|-<br />
<br />
| misterblue<br />
| Robert Adams<br />
| misterblue waves<br />
| misterblue waves<br />
| -8 Oregon, USA<br />
| self <br />
| simulator devel, physics (BulletSim), protocol, alt viewers<br />
|-<br />
<br />
| Plugh<br />
| Kevin Cozens<br />
| Andrew Hellershanks<br />
| Andrew Hellershanks<br />
| -5<br />
| Virtual Highway<br />
| Building, Scripting<br />
|-<br />
<br />
| Ubit<br />
| Leal Duarte<br />
| Ubit Umarov<br />
| Ubit Umarov<br />
| WET (UTC+00) / WEST (UTC+01) <br />
| Independent<br />
| <br />
|}<br />
<br />
<br /><br />
<br />
== Core Developers Following the White Rabbit ==<br />
<br />
Core developers who have temporarily (we hope) gone chasing the white rabbit. They are in all similar to the active core developers, except that they haven't been that active lately, so their voting rights are awaiting their come back. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
<br />
| [[User:Lbsa71|lbsa71]] <br />
| Stefan Andersson <br />
| Tribal Skytower <br />
| OSG:Stefan Andersson<br />TN:Stefan Andersson <br />
| +1 <br />
| [http://tribalmedia.se/ Tribal Media AB] <br />
| Web Integration<br />
|-<br />
<br />
| [[User:MW|MW]] <br />
| Darren <br />
| Wright Juran <br />
| <br />
| 0 <br />
| <br />
| Everything<br />
|-<br />
<br />
| [[User:Adam Frisby|Adam Frisby]] <br />
| Adam Frisby <br />
| Adam Zaius <br />
| <br />
| +8 <br />
| DeepThink Pty Ltd <br />
| Terrain, Performance<br />
|-<br />
<br />
| ckrinke <br />
| Charles&nbsp;Krinke <br />
| Charlesk&nbsp;Bing <br />
| <br />
| -8 <br />
| &nbsp; <br />
| Reliability/Grid servers/ll-functions<br />
|-<br />
<br />
| [[User:Mikem|mikem]] <br />
| Mike Mazur <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| Independent <br />
| Patches, scripting improvements, LSL compiler<br />
|-<br />
<br />
| [[User:HomerHorwitz|homerh]] <br />
| Homer Horwitz <br />
| Homer Horwitz <br />
| <br /> <br />
| +2 <br />
| Independent <br />
| Rev. engineering, "now, that's funny" problems, but still interested in all parts of it<br />
|-<br />
<br />
| [[User:Nlin|nlin]] <br />
| N Lin <br />
| Standard Drucker <br />
| <br /> <br />
| +9 <br />
| [http://www.3di.jp/en/ 3Di Inc, Japan]<br />http://www.3di.jp/en/ <br />
| Physics, scripting, more to come<br />
|-<br />
<br />
| [[User:Arthursv|arthursv]] <br />
| Arthur Valadares <br />
| <br />
| NONE <br />
| -8 <br />
| University of California, Irvine <br />
| Unit testing, database plugins, bug fixes, general<br />
|-<br />
<br />
| [[User:DrScofield|drscofld]] <br />
| Dirk Husemann <br />
| Dr Scofield <br />
| <br />
| +1 <br />
| [http://xyzzyxyzzy.net/ xyzzyxyzzy.net] <br />
| Reliability, networking protocols, inventory, assets, remote control, voice, and pretty much everything else&nbsp;:-) <br />
|-<br />
<br />
| [[User:Teravus|Teravus]] <br />
| Daniel Olivares <br />
| Teravus Ousley <br />
| <br />
| -5 <br />
| W3z <br />
| Physics &amp; Admin tools, A working sim.<br />
|-<br />
<br />
| [[User:Chi11ken|chi11ken]] <br />
| Jeff Ames <br />
| Chillken Proto <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
<br />
| [[User:Marck|Marck00]] <br />
| M. Kirsch <br />
| Marck Kjeller <br />
| <br />
| +1 <br />
| Independent <br />
| Everything that catches my attention and that I can get my head around. <br />
|-<br />
<br />
| [[User:Snoopy2|Snoopy2]] <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
|<br />
| [http://www.dreamlandmetaverse.com/ http://www.dreamlandmetaverse.com/] <br />
| OpenSim region and grid hosting<br />
|-<br />
<br />
| [[User:Justincc|justincc]] <br />
| Justin Clark-Casey <br />
| Lulworth Beaumont <br />
| Justin Clark-Casey (all other grids) <br />
| 0 <br />
| OSVW Consulting<br />[http://justincc.org/blog justincc's OpenSimulator blog] <br />
| Grid, performance &amp; reliability, inventory (avatar and object), assets, scenes, OARs, etc. Generally speaking, my main interest is to create infrastructure that other people can build on top of.<br />
|-<br />
<br />
| [[User:Dslake|dslake]] <br />
| Dan Lake <br />
| Dan Lake <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| Scalability, Performance, Network stack<br />
|-<br />
<br />
| cmickeyb <br />
| Mic Bowman <br />
| Mic Bowman <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
|-<br />
| [[User:BlueWall|BlueWall]] <br />
| James Hughes <br />
| BlueWall Slade <br />
| BlueWall Slade <br />
| -5 <br />
| BlueWall Information Technologies, LLC <br />
| Various parts<br />
|-<br />
| [[User:Nebadon|Nebadon]] <br />
| Michael Emory Cerquoni <br />
| Nebadon Izumi <br />
| Nebadon Izumi <br />
| -5 New Jersey <br />
| Oni Kenkon Creations, Encitra, 4Dialog, Avacon<br />
| Building, Scripting, Testing<br />
|-<br />
| orenh<br />
| Oren Hurvitz<br />
|<br />
|<br />
| +2<br />
| Kitely<br />
|<br />
|-<br />
| AliciaRaven<br />
| Alicia Richardson <br />
| ClaudiaDLioncourt<br />
| <br />
| 0 GMT<br />
| <br />
|-<br />
<br />
|}<br />
<br />
== Retired Core Developers ==<br />
<br />
Core developers who have transcended our mortal plane, i.e. they are no longer directly engaged with the project. Thank you forever for your contributions! <br />
<br />
* '''Only formerly voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Babblefrog|babblefrog]] <br />
| Brian McBee <br />
| Dogen Coldstream <br />
| Babblefrog Ballistic (osgrid) <br />
| -8 <br />
| Disorganized <br />
| &nbsp;<br />
|-<br />
| [[User:Danx0r|danx0r]] <br />
| Dan Miller <br />
| Albert Pascal <br />
| <br />
| -8 <br />
| squiggle.com <br />
| PHEEZIKS; everything<br />
|-<br />
| Tleiades <br />
| &nbsp; <br />
| Tleiades&nbsp;Hax <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Grid servers/Database<br />
|-<br />
| [[User:Darok|Darok]] <br />
| &nbsp; <br />
| Darok Kaminski <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Physics engines (especially BulletX)<br />
|-<br />
| Gareth / Gwen <br />
| Gareth Nelson <br />
| Gareth Ellison <br />
| Gareth Nelson (on everywhere but SL) <br />
| BST (UTC+1) <br />
| Litesim Ltd <br />
| Grid servers, sim border crossing, avatar animations<br />
|-<br />
| [[User:Dalien|dalien]] <br />
| Dalien Talbot <br />
| Dalien Talbot <br />
| <br />
| +1 <br />
| Mostly TCP-based <br />
| Small fixes; rev.eng./prototyping; nightlies; git-keeper<br />
|-<br />
| [[Alondria]] <br />
| <br />
| Alondria LeFay <br />
| Alondria LeFay (OSGrid) <br />
| -8 <br />
| Independent <br />
| Implementation of LSL functions and other scripting tidbits.<br />
|-<br />
| [[User:SeanDague|sdague]] <br />
| Sean Dague <br />
| Neas Bade <br />
| <br />
| -5 <br />
| IBM <br />
| Database, Linux, Testing, Misc<br />
|-<br />
| [[User:MingChen|MingChen]] <br />
| Mike/Michael Ortman <br />
| Ming Chen <br />
| <br />
| -6 (-5 in Summer) <br />
| DeepThink Pty Ltd <br />
| Estate/Parcel Support/Modules/Keeping things all neat and tidy.<br />
|-<br />
| [[User:Tedd|Tedd]] <br />
| Tedd Hansen <br />
| Tedd Maa <br />
| <br />
| +1 <br />
| Tedd Hansen <br />
| Programming/Scripting/Architecture<br />
|-<br />
| [[User:Adjohn|adjohn]] <br />
| Adam Johnson <br />
| Zeuz Zenovka <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Joha1|joha1]] <br />
| Johan Berntsson <br />
| Joppi Brandenburg <br />
| <br /> <br />
| +9 <br />
| &nbsp; <br />
| Performance, packet handling/libSL<br />
|-<br />
| jhurliman <br />
| John Hurliman <br />
| John Hurliman <br />
|<br />
|<br />
|<br />
|<br />
|-<br />
| [[User:Dahlia|dahlia]] <br />
| T. Hoff <br />
| Dahlia Trimble <br />
| <br />
| -8 / -7 <br />
| Independent <br />
| Collision geometry, various math and physics issues, occasional bug fixes and random enhancements<br />
|-<br />
| [[User:Fly-man-|Fly-Man-]] <br />
| Laurence <br />
| <br />
| OSGrid: Fly Man <br />
| GMT +1 <br />
| Private Company<br />
| Testing, OpenSimSearch, OpenSimProfile<br />
|-<br />
|}<br />
<br />
== Wiki Sysops ==<br />
<br />
Along with the core developers, these people help manage the OpenSimulator wiki as well as make other contributions (see Areas of Interest). <br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Makopoppo|Makopoppo]] <br />
| Makiko Nomura <br />
| Mako Nozaki <br />
| Everywhere <br />
| +9 Tokyo, Japan <br />
| As an individual developer <br />
| Everything for improving usability and connectability - wiki/issue management, documentation, localization(Japanese), modifying the interface mainly of core modules<br />
|-<br />
| [[User:Fritigern|Fritigern]] <br />
| S-E-C-R-E-T <br />
| Fritigern Gothly <br />
| SecondLife, OSGrid <br />
| +1 GMT <br />
| <br />
| My interests are many, and extremely varied. One thing that i am very interested in, is seeing OpenSimulator grow, mature, and develop into something that really does rival SL/LL.<br />
|}<br />
<br />
== Additional Developers/Testers/Contributors ==<br />
<br />
These people have contributed and/or are contributing bug reports, patches, testing, and all sorts of other goodies to the project. <br /> '''Newcomers please add yourself to bottom of the list!''' <br /> <br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Jtclark48|jclark4]] <br />
| Jay Clark <br />
| Jay Clarke <br />
| <br />
| -5 <br />
| IBM <br />
| Physics, Grid Host, AI, Scripting, Testing<br />
|-<br />
| [[User:AdamStevenson|BigFootAg]] <br />
| Adam Stevenson <br />
| Adamus Petrov <br />
| <br />
| -6 <br />
| Texas A&amp;M University <br />
| AI, Skynet, Evolving Systems, Biology<br />
|-<br />
| [[User:Jeff1564|Jeff1564]] <br />
| Jeff <br />
| Potter Taurog <br />
| Potter Taurog <br />
| -8 <br />
| http://myopengrid.com <br />
| Building, Scripting, Testing<br />
|-<br />
| Rock_Vacirca <br />
| Colin Withers <br />
| Rock Vacirca <br />
| &nbsp; <br />
| +1 <br />
| http://rock-vacirca.blogspot.com <br />
| Testing, building, scripting, maintaining an opensim blog.<br />
|-<br />
| simsim <br />
| caocao <br />
| &nbsp; <br />
| &nbsp; <br />
| +9 <br />
| &nbsp; <br />
| Testing whole functions of OpenSimulator system,working with OpenSim-Engine,reporting on OpenSimulator<br />
|-<br />
| [[User:Vicero Lambert|Vicero Lambert]] <br />
| &nbsp; <br />
| &nbsp; <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
| [[User:Magi|Magi]] <br />
| Andy Agnew <br />
| Magi Merlin <br />
| <br />
| +10 <br />
| Spun Pty Ltd <br />
| 3D Web Integration, Database stuff and playing with the odds and ends box.<br />
|-<br />
| [[User:ClarkZone|ClarkZone]] <br />
| Troy Admin(@ClarkZone) <br />
| Troy Childs <br />
| Troy Admin (ClarkZone) <br />
| -5 <br />
| Http://clarkzone.dyndns.org <br />
| Tester and Grid Host<br />
|-<br />
| [[User:Aiaustin|aiaustin]] <br />
| Ai Austin <br />
| Ai Austin <br />
| Ai Austin <br />
| +0 <br />
| AIAI, Virtual University of Edinburgh<br />http://www.aiai.ed.ac.uk/~ai/<br />http://vue.ed.ac.uk/openvue/ <br />
| Windows tests<br />Content testing<br />Use of multiple VWs<br />
|-<br />
| Marc Manders <br />
| Marc Manders <br />
| &nbsp; <br />
| &nbsp; <br />
| +6 <br />
| marcmanders@gmail.com <br />
| Creative features<br />
|-<br />
| [[User:Balthazar|balthazar]] <br />
| Trevor Brooks <br />
| Balthazar Sin <br />
| <br />
| -5 <br />
| None <br />
| Terrains, testing and some small coding tasks<br />
|-<br />
| [[User:Jimbo2120|jimbo2120]] <br />
| Michael Osias <br />
| Illuminous Beltran <br />
| <br />
| -5 <br />
| IBM <br />
| Grid, AI, Skynet, coding and testing<br />
|-<br />
| ZeroPoint <br />
| &nbsp; <br />
| Guilderoy&nbsp;Dench <br />
| <br />
| -5 <br />
| &nbsp; <br />
| Programming/Database<br />
|-<br />
| [[User:DerekTang|DerekTang]] <br />
| Derek Tang <br />
| Derek Timeless <br />
| Derek Tang (ChineseGrid) <br />
| +8 <br />
| http://ChineseGrid.net <br />
| Running a public WINDOWS sim for testing, Docs, Helping Chinese users to enjoy OpenSim; building Chinese OpenSimulator communities. In construction...<br />
|-<br />
| [[User:TayB|TayB]] <br />
| Earl Balai <br />
| Taylor Dae <br />
| <br />
| -10 <br />
| WhynGrid <br />
| Grid Host,Networking,Contributions &amp; Testing.<br />
|-<br />
| [[User:JamieDav|JamieDav]] <br />
| Jamie David <br />
| Jamie David <br />
| <br />
| +7 <br />
| Forum <br />
| Grid, Sim, Avitar, Functionality<br />
|-<br />
| [[User:Krtaylor|Krtaylor]] <br />
| Kurt Taylor <br />
| Kurt Stringer <br />
| <br />
| -6 <br />
| IBM <br />
| Grid, Networking, Monitoring, Scripting, Inventory, Testing<br />
|-<br />
| [[User:Nink|Nink]] <br />
| Peter Finn <br />
| Nink Noonan <br />
| <br />
| -5 <br />
| IBM <br />
| Disruptive Influence.<br />
|-<br />
| [[User:Bruce|Bruce]] <br />
| Bruce Meerson <br />
| Bruce Meerson <br />
| <br />
| +8 <br />
| HiPiHi <br />
| Watching.<br />
|-<br />
| [[User:Darb|DarbD]] <br />
| Brian B. Quinn <br />
| Darb Dabney <br />
| regions<br />near Marin <br />
| PST/SLT (-7 or -8) <br />
| County of Marin, California<br /> http://blog.3dmap.me <br />
| LiDAR-based sculpties, real-world terrain, <br />pursuit of civic paraverses, virtual Emergency Operations Centers<br />
|-<br />
| [[User:Charlie Omega|CharlieO]] <br />
| Dan <br />
| Charlie Omega <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| Mild coding/tweaking/simple feature adds, Stress testing/break stuff, Testing limits of existing code. Making sure [[LSL Status]] is up to date<br />
|-<br />
| oobscure <br />
| &nbsp; <br />
| Opensource Obscure <br />
| <br />
| +1 <br />
| http://www.opensim.it <br />
| Running a public Linux sim for testing, Docs, Helping italian users, Building opensim communities, Watching<br />
|-<br />
| pitman <br />
| Mike Pitman <br />
| Rez Tone <br />
| <br />
| &nbsp; <br />
| IBM <br />
| Scientific visualization schemes, virt world product design, persistant workspaces, virt world based big biz<br />
|-<br />
| Shenlei <br />
| Shenlei Winkler <br />
| Shenlei Flasheart, Shenlei Winkler <br />
| <br />
| &nbsp; <br />
| Fashion Research Institute <br />
| Product Design and Development, Apparel industry, and o yes, I wrote the book&nbsp;;)<br />
|-<br />
| cmu <br />
| Christopher Mumme <br />
| Snook Destiny <br />
| <br />
| +1 <br />
| http://www.cmu-develop.de/ and research group "Collaboration Systems and CSCW" at Clausthal University of Technology <br />
| Testing OpenSim, working with OpenSim-Engine, reporting on OpenSimulator<br />
|-<br />
| [[Silpol]] <br />
| Andriy Tymchenko <br />
| Andy Tir <br />
| <br />
| EET (+2/3) <br />
| http://silpol.blogspot.com/ (also visible at Nokia) <br />
| Highly uncoordinated mess with elements of palace games, under-table diplomacy, rebellion, coup d'état and mutiny. optionally pirate<br />
|-<br />
| [[User:Grumly|Grumly]] <br />
| <br />
| Forest Klaar <br />
| Grumly TheBear <br />
| GMT+1 <br />
| .NET MCAD Dev/Arch/Trainer http://www.devoteam.com <br />
| Trying to get into OpenSimulator code for now. Particularly interrested in data persistence. blog (Hello, Avatar!): http://lslblog.free.fr<br />
|-<br />
| [[User:DaTwitch|DaTwitch]] <br />
| James G. Stallings II <br />
| <br />Lazarus Longstaff <br />
| Hiro Protagonist (OSGrid) <br />
| -5 <br />
| House Husband <br />
| OSGrid Region owner, OSGrid Operator,<br />Forum Admin, sometime wiki editor<br />
|-<br />
| gryc <br />
| Gryc Ueusp <br />
| Gryc Uriza <br />
| Gryc Uriza(OSGrid) <br />
| -6 <br />
| <br />
| PHP scripting, web interfaces, interconnectivity, cross-platformedness<br />
|-<br />
| [[User:Phrearch|Phrearch]] <br />
| Jeroen van Veen <br />
| Phrearch Miles <br />
| Phrearch Miles(OSGrid) <br />
| Amsterdam/Paris <br />
| <br />
| HWIOS, WiXTD, Wikidoc, Moo, User interfaces<br />
|-<br />
| [[User:Burnman|Burnman]] <br />
| Allen <br />
| Burnman Bedlam <br />
| <br />
| Boston, USA <br />
| <br />
| Testing, testing, and more testing! Getting familiar with the source, interested in all aspects of the project.<br />
|-<br />
| [[User:Krisbfunk|krisbfunk]] <br />
| Kris Bulman <br />
| Krisbfunk Vought <br />
| Krisbfunk Nocturnal(OSGrid) <br />
| PE, Canada (-4) <br />
| Edactive Technologies<br />NocturnalEye Productions<br />UPEI <br />
| Currently: Testing, bug reports, wiki updating, building on OSGrid<br />
|-<br />
| [[User:HashBox|HashBox]] <br />
| &nbsp; <br />
| Sibariel Darkstone <br />
| Sibariel Darkstone (OSGrid) <br />
| New Zealand (+12) <br />
| <br />
| Testing, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Kinoc|Kinoc]] <br />
| Kino Coursey <br />
| Daxxon Jaxxon <br />
| Daxxon Kinoc (OSgrid) <br />
| -6 <br />
| Daxtron Laboratories <br /> http://www.daxtron.com<br /> University of North Texas <br />
| AI, Semantic web, Ontologies, Natural Laanguage Processing, Cyc, Bots, NPC<br />
|-<br />
| [[User:Trapuh|trapuh]] <br />
| Pedro Ribeiro <br />
| Vaiten Forder <br />
| <br />
| GMT <br />
| University Student, Escola Superior de Educação de Viseu, Portugal <br />
| Testing, eventual bug reports and wiki. Music, web/digital arts and php+sql.<br />
|-<br />
| [[User:SonicViz|SonicViz]] <br />
| Paul Cohen <br />
| Komuso Tokugawa <br />
| <br />
| +9 <br />
| Http://sonicviz.com <br />
| Audio/Music, Interactive Music, Control Protocols, Interfaces, VisualFX, Procedural animation/Generative systems + testing and general dev<br />
|-<br />
| [[User:Mokele|mokele]] <br />
| Scott Norman <br />
| Mokelembembe Mokeev <br />
| <br />
| -8 (Southern California) <br />
| Web Developer (PHP and MySQL) <br />
| Interested in seeing running on PowerPC Macs which it is. So, when I can, I'll compile and test on PowerPC Mac (PowerBook G4) and submit reports and then update the wiki if need on installing on Mac. Also have a Ubuntu 7.10 server that I can do testing on too.<br />
|-<br />
| [[User:Devalnor|devalnor]] <br />
| Devalnor <br />
| M. Watkin <br />
| <br />
| +1 (Belgium) <br />
| <br />
| Small Patch code, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Ezekiel|Ezekiel]] <br />
| Ezekiel <br />
| Ezekiel Zabelin <br />
| <br />
| +1 <br />
| http://www.yosims.com <br />
| Concepts, business aspects of virtual worlds - web developer (PHP, MySQL, Javascript, LSL)<br />
|-<br />
| [[User:Buggmaster|Buggmaster]] <br />
| Mike D <br />
| Bug Master <br />
| None <br />
| -8 <br />
| http://www.adultmetaverse.com <br />
| Grid, Data/Web PHP/PERL/MySQL<br />
|-<br />
| [[User:Nixnerd|nixnerd]] <br />
| <br />
| Dangerously Moody <br />
| None <br />
| GMT <br />
| http://www.integratedtechnologies.eu <br />
| Cross Platform Testing, Feedback, Bug Reporting<br />
|-<br />
| [[User:MoHax|mohax]] <br />
| Mo Hax <br />
| Mo Hax <br />
| <br />
| -5 Eastern <br />
| IBM <br />
| Testing, Feedback, Content Contributions, Bug Reporting, Documenting, Development<br />
|-<br />
| [[User:Webmage|webmage]] <br />
| webmage <br />
| Leyla Masala <br />
| Web Mage <br />
| +1 <br />
| IBM <br />
| Testing, terrain<br />
|-<br />
| [[User:NLStitch|NLStitch]] <br />
| Marijn Oosterveld <br />
| Stitch Seale <br />
| NYA <br />
| GMT +1 Amsterdam <br />
| Twingate Systems (http://www.twingate.nl)<br />HanzeHogeschool Groningen, Netherlands <br />
| Programming, Photography, AI<br />
|-<br />
| [[User:Ideia Boa|Ideia Boa]] <br />
| Joao Lopes <br />
| Ideia Boa <br />
| Ideia Boa or Boa Ideia in some grids <br />
| GTM+1 Stockholm/Sweden <br />
| WorldSimTERRA - Virtual World that speaks Portuguese too<br />http://www.worldsimterra.com <br />
| Testing and more testing! Updating the original wiki and translating the OpenSimulator Wiki into Portuguese and reporting on OpenSimulator<br />
|-<br />
| [[User:Lulurun|lulurun]] <br />
| liu <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| 3Di Inc, Japan <br />http://www.3di.jp <br />
| Patches, openid, server performance, UGAI<br />
|-<br />
| [[User:Carlosroundel|Carlosrounde]] <br />
| Carlosroundel <br />
| Carlos Roundel <br />
| <br /> <br />
| +1 <br />
| Cyberlandia Italy<br />http://www.cyberlandia.net <br />
| Grid, programmer, database, tester<br />
|-<br />
| [[User:Mikebert|Mikebert]] <br />
| Mike<br />
| Mikebert Miles <br />
| Mikebert<br />
| +1 <br />
| OpenSIM Wiki, Germany<br />https://www.mikebert.de/archiv/opensim<br />
| German Wiki, Translater, Server Performance (Linux/Windows), Tester, Feedback, Bug Reporting, Server-Hosting<br />
|-<br />
| Taoki <br />
| Mircea Kitsune / Taoki Vixen <br />
| Mircea Kitsune (OSGrid) / Mircea Lobo (LL grid) <br />
| <br /> <br />
| GMT +2 <br />
| <br /> <br />
| Usually testing and bug reporting but I also make smaller patches where I know what to do.<br />
|-<br />
| [[User:Patnad|Patnad]] <br />
| Patrick <br />
| Patnad Babii <br />
| Patnad Babii (OSGrid) <br />
| GMT -5 <br />
| RezzMe Technologies<br />http://www.rezzme.com <br />
| Bug testing and reporting, I code C# and have submitted a few patches<br />
|-<br />
| [[User:^DarkMan|^DarkMan]] <br />
| Brian Adair <br />
| Patrick Ouachita <br />
| Brian Adair &#124; Patrick Meta <br />
| -6 CST <br />
| RealMetaLife &#124; B&amp;H Networking <br />
| Building, Scripting, Testing, etc.<br />
|-<br />
| [[User:Tlaukkan|Tommi Laukkanen]] <br />
| Tommi Laukkanen <br />
| &nbsp; <br />
| Tommi Laukkanen <br />
| +2 GMT <br />
| http://www.bubblecloud.org <br />
| Protocols ([http://www.bubblecloud.org MXP]), NHibernate, Scrip API, Map Generation, Bug Fixes, Grid Hosting<br />
|-<br />
| [[User:Mystical|Mystical]] <br />
| Kevin Tweedy <br />
| Mystical Demina <br />
| Mystical Demina <br />
| -5 <br />
| Extreme Reality Grid<br />http://www.XRGrid.com <br />
| Windows Communication Framework, Windows Workflow,Entity Framework, MSSQL<br />Enhancements,Commerce, Content,DotNetNuke based portal, development services<br />
|-<br />
| [[User:Godfrey|Godfrey]] <br />
| Jeff Lee <br />
| Warin Cascabel <br />
| <br />
| -5 (EST5EDT) <br />
| <br />
| Testing, minor bugfixes. Scripting, building, animating<br />
|-<br />
| Jamenai <br />
| Christopher Händler <br />
| Jamenai Luik <br />
| Jamenai Luik <br />
| +1 <br />
| Playneko Grid &#124; XIMDEX Jamenai<br />http://www.playneko.de<br />http://www.ximdex.de <br />
| Performance,Bug Reporting, Hosting, Grid-Owner,(PHP, MySQL, Perl, JavaScript, LSL)<br />
|-<br />
| [[User:Bikcmp|bikcmp]] <br />
| Jason <br />
| Jake1500 Allen <br />
| Jason Helios (The Helios Grid) <br />
| EST <br />
| Blue Software <br />
| Search, groups, land, and currency<br />
|-<br />
| [[User:Mark.malewski|Slipaway]] <br />
| Mark Malewski <br />
| Chris Rock <br />
| <br />
| -6 (-5 during summer - CDT) <br />
| NexTECH / Joopla <br />
| Web development &amp; systems integration, terrain, WIKI documentation, tutorials, testing, bug reporting and feedback.<br />
|-<br />
| barakademi <br />
| Steve Topp <br />
| barakademi Barzane <br />
| same avi on baragrid OSgrid Grid4us sciencesim <br />
| utc+1 (CET) paris <br />
| http://xbot-sl.barakademi.org http://vps.barakademi.org/oswi http://vps.barakademi.org/oswi/loginscreen.php <br />
| Music LiveMusic MetaverseMusic Opensim Libomv Mono-2.4 Linux (suse,debian,ubuntu) Admin Scripting Automating Development Intergration php mysql bash nant +++<br />
|-<br />
| [[User:Robert d|robert_d]] <br />
| Robert Dzikowski <br />
| <br />
| OSGrid: robert_d 13 <br />
| UTC+1 <br />
| [http://blog.rd-it.net http://blog.rd-it.net] <br />
| Region Modules, Tutorials<br />
|-<br />
| john_ <br />
| John&nbsp;Moyer <br />
| VAJohn&nbsp;GeekSquad or&nbsp;Matthew&nbsp;Kendal <br />
| <br />
| -5 <br />
| Best&nbsp;Buy/Geek&nbsp;Squad <br />
| Tester<br />
|-<br />
| [[User:W!cKeD|_WicKeD]] <br />
| Maik <br />
| Maik Galaxy <br />
| El Diablo <br />
| +1 Germany <br />
| Creatio Inc. / [http://www.OpenSimGerman.us/ OpenSimGerman.us] <br />
| German Support, Translator, Building, Scripting, Testing, Hosting<br />
|-<br />
| [[User:Stevie Wakowski|Stevie Wakowksi]] <br />
| Steve Roberts <br />
| Stevie Wakowski <br />
| <br />
| +10 Australia <br />
| IBM <br />
| OpenSimulator builds, Linux, Modrex, bug reporting, evangalist for OpenSimulator in business applications.<br />
|-<br />
| Revolution <br />
| Matthew <br />
| Revolution Smythe <br />
| Revolution Smythe <br />
| -6 Central USA <br />
| None <br />
| Script engine, physics engine, general odd bugs, interesting and odd things<br />
|-<br />
| [[User:ClemsonGS|clemsonGS]] <br />
| Brian Cass <br />
| BC Sands <br />
| Brian Cass (VWC Grid) <br />
| -5 <br />
| http://www.cvwconline.org/ <br />
| Developing virtual worlds for use in higher education<br />
|-<br />
| <br />
| AlexRa <br />
| <br />
| <br />
| <br />
| Independent <br />
| <br />
|-<br />
| <br />
| <br />
| Mikko Pallari <br />
| <br />
| <br />
| Realxtend <br />
| <br />
|-<br />
| <br />
| StrawberryFride <br />
| Chris Hart <br />
| <br />
| <br />
| ReactionGrid <br />
| <br />
|-<br />
| [[User:RemedyTomm|RemedyTomm]] <br />
| Tom Grimshaw <br />
| Tomm Remedy <br />
| KGrid: Casper Warden OSGrid: Tomm Remedy <br />
| UTC+0 (BST) <br />
| Remedy Communications <br />
| Texture pipeline, Groups, ObjectUpdates<br />
|-<br />
| <br />
| <br />
| Rob Smart <br />
| <br />
| <br />
| IBM <br />
| <br />
|-<br />
| MicheilMerlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| -6 <br />
| Independent <br /> [http://www.iliveisl.com/ http://www.iliveisl.com/] <br />
| Scripting, patches, and testcases<br />
|-<br />
| Pato Donald <br />
| Pato Donald <br />
| Morgam Biedermann <br />
| Pato Donald <br />
| -3 <br />
| Independent [http://www.matheusmk3.co.cc/ http://www.matheusmk3.co.cc/ <br />
| Groups, Scripts, Physics, Communication, Integration<br />
|-<br />
| <br />
| Sera Marx <br />
| Darkfire Soulstar <br />
| <br />
| +12 <br />
| Radiance promotions <br />
| Grid Host, Commissioner. ~ Anyone looking for work related to the development of Opensimulator or Viewers please contact me. Any work undertaken for me will be returned to Opensimulator unless made strictly for my Grid<br />
|-<br />
|[[User:dz|dz]] <br />
| D Osborn <br />
| ydoo magic<br />
| delta zed @ OSGRID D Osborn @ ScienceSim & MOSES grids<br />
| PST/SLT (-7 or -8) <br />
| CEO OpenSimian <br />
| Performance testing, advanced scripting, high prim count builds, Client and server side bots, Animation Overrides, MANTIS maintenance.<br />
|-<br />
| [[User:Hallow Palmer|Hallow Palmer]] <br />
| Markus <br />
| Hallow Palmer <br />
| <br /> <br />
| +1 <br />
| Grid4Us<br />http://www.grid4us.net <br />
| Server Performance (Windows), Tester, Feedback, Business concepts,Bug Reporting, Server-Hosting<br />
|-<br />
| [[User:LenaVanilli|LenaVanilli]] <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| +1 Germany <br />
| [http://www.hypergrid.org http://www.hypergrid.org] <br />
| Grid-Management, Testing Testing Testing, Region Hosting<br />
|-<br />
| [[User:Aduffy70|aduffy70]] <br />
| Aaron Duffy <br />
| Aeran Stipe <br />
| Aaron Duffy @ScienceSim <br />
| -7 <br />
| USU <br />
| Scientific visualization &amp; education, Region modules, Heavily scripted regions<br />
|-<br />
| <br />
| Erich Bremer <br />
| Erich Bremer <br />
| <br />
Erich Bremer@OSGrid <br />
<br />
| -5 <br />
| http://www.ebremer.com <br />
| Semantic Web, Data Visualization<br />
|-<br />
| [[User:MarkIDCAS|MarkIDCAS]] <br />
| Mark Bannon <br />
| Mark IDCAS <br />
| 3D Grid Association, AtMeeting, Valhalla Virtual and IDCAS. <br />
| GMT <br />
| [http://www.valhallavirtual.com http://www.valhallavirtual.com] <br />
| Grid Management &amp; systems integration. Scripting. WIKI documentation, tutorials, bug reporting and feedback.<br />
|-<br />
| [[User:Allquixotic|allquixotic]] <br />
| Sean McNamara <br />
| Tiyuk Quellmalz <br />
| OSG: Tiyuk Quellmalz <br />
| -5 <br />
| None <br />
| Bugfixing; networking; performance; data integrity; LSL; auto-backup; null DB (eventual consistency).<br />
|-<br />
| [[User:Orenh|orenh]] <br />
| Oren Hurvitz <br />
| <br />
| Oren Hurvitz (Kitely) <br />
| +2 <br />
| Kitely <br />
| <br />
|-<br />
<br />
| [[User:Randomhuman|randomhuman]] <br />
| Kevin Houlihan <br />
| random Radikal <br />
| random human (OSGrid) <br />
| WET/IST <br />
| CrimsonCookie <br />
| RemoteAdmin module; On-demand grids; web integration.<br />
|-<br />
<br />
| [[User:Oddball Otoole|oddball otoole]]<br />
| J.v.Hogeloon<br />
| Oddball Otoole<br />
| Oddball Otoole (OSGrid<br />
| +1 (The Netherlands<br />
| None<br />
| Building, scripting, testing, social stuff.<br />
|-<br />
| [[User:Pixel|Pixel Tomsen]]<br />
| Christian Kurzhals<br />
| Pixel Tomsen<br />
| Pixel Tomsen OSGrid<br />
| +1 (Germany<br />
| see my profil<br />
| Dev, Building, scripting, sim-hosting, some modules, patches, osgrid<br />
|-<br />
| [[User:kenearlg|kenearlg]]<br />
| Ken Grunke<br />
| Key Grau<br />
| Key Gruin (Osgrid)<br />
| -6 CST<br />
| http://www.osgrid.org/<br />
| testing, moderating, inworld games & recreation, wiki spam control<br />
|-<br />
| [[User:CG4Life|CG4Life]]<br />
| CG Anderson<br />
| Cyn Hak<br />
| <br />
| -8 PST<br />
| Little Dogs Media<br />
| Networking, Security, Performance (parallelization, compression, encryption), physics, 3D manipulation, bugfixing, documentation. Just getting into the code base, so will start with compression/parallelizatoin ideas and bugfixing, then other stuff later.<br />
|-<br />
| [[User:vegaslon|vegaslon]]<br />
| Adam Ivie<br />
| vegaslon plutonian<br />
| <br />
| -5 EST<br />
| Independent <br />
| Physics, Vehicles, Advanced Scripting, Testing, Advanced Land Usage.<br />
|-<br />
<br />
| [[User:AliciaRaven|AliciaRaven]] <br />
| Alicia Richardson <br />
| ClaudiaDLioncourt<br />
| Alicia Raven (Spellscape) <br />
| 0 GMT<br />
| Spellscape Ltd<br />http://www.spellscape.co.uk<br />
|<br />
|-<br />
<br />
| [[User:Djphil|djphil]] <br />
| Philippe Lemaire <br />
| dj phil<br />
| dj phil<br />
| +2 GMT<br />
| Collab 3D Asbl<br />
| Testing, Scripting, Helping<br />
<br />
|-<br />
| [[User:Steevithak|Steevithak]]<br />
| Steve Rainwater<br />
| Steevithak<br />
| Steevithak x (OSgrid)<br />
| -6/-5 (CST/CDT)<br />
| Independent, [https://steevithak.com steevithak.com]<br />
| scalability, performance, protocols, everything else. Also MediaWiki<br />
<br />
|}<br />
<br />
[[Category:Development]]</div>
Dz
http://opensimulator.org/wiki/Development_Team
Development Team
2022-07-01T17:00:20Z
<p>Dz: /* Additional Developers/Testers/Contributors */</p>
<hr />
<div>__NOTOC__ {{Quicklinks}} <br />
<br />
== Active Core Developers ==<br />
<br />
Developers who have commit access to our central server, are [http://www.ohloh.net/projects/4753/contributors regular contributors] to the codebase, and have voting rights over development and process issues of the OpenSimulator project. See [[Organization]]. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Diva|Diva]] <br />
| Crista Lopes <br />
| Diva Canto <br />
| Crista Lopes / Diva Canto <br />
| -8 <br />
| University of California, Irvine <br />
| Everything, except databases<br />
|-<br />
| [[User:Melanie T|Melanie_T]] <br />
| Melanie <br />
| Melanie Milland <br />
| <br /> <br />
| +1 <br />
| Independent <br />
| Scripting, Prims/Scene, Life, The Universe, and Everything<br />
|-<br />
<br />
| misterblue<br />
| Robert Adams<br />
| misterblue waves<br />
| misterblue waves<br />
| -8 Oregon, USA<br />
| self <br />
| simulator devel, physics (BulletSim), protocol, alt viewers<br />
|-<br />
<br />
| Plugh<br />
| Kevin Cozens<br />
| Andrew Hellershanks<br />
| Andrew Hellershanks<br />
| -5<br />
| Virtual Highway<br />
| Building, Scripting<br />
|-<br />
<br />
| Ubit<br />
| Leal Duarte<br />
| Ubit Umarov<br />
| Ubit Umarov<br />
| WET (UTC+00) / WEST (UTC+01) <br />
| Independent<br />
| <br />
|}<br />
<br />
<br /><br />
<br />
== Core Developers Following the White Rabbit ==<br />
<br />
Core developers who have temporarily (we hope) gone chasing the white rabbit. They are in all similar to the active core developers, except that they haven't been that active lately, so their voting rights are awaiting their come back. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
<br />
| [[User:Lbsa71|lbsa71]] <br />
| Stefan Andersson <br />
| Tribal Skytower <br />
| OSG:Stefan Andersson<br />TN:Stefan Andersson <br />
| +1 <br />
| [http://tribalmedia.se/ Tribal Media AB] <br />
| Web Integration<br />
|-<br />
<br />
| [[User:MW|MW]] <br />
| Darren <br />
| Wright Juran <br />
| <br />
| 0 <br />
| <br />
| Everything<br />
|-<br />
<br />
| [[User:Adam Frisby|Adam Frisby]] <br />
| Adam Frisby <br />
| Adam Zaius <br />
| <br />
| +8 <br />
| DeepThink Pty Ltd <br />
| Terrain, Performance<br />
|-<br />
<br />
| ckrinke <br />
| Charles&nbsp;Krinke <br />
| Charlesk&nbsp;Bing <br />
| <br />
| -8 <br />
| &nbsp; <br />
| Reliability/Grid servers/ll-functions<br />
|-<br />
<br />
| [[User:Mikem|mikem]] <br />
| Mike Mazur <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| Independent <br />
| Patches, scripting improvements, LSL compiler<br />
|-<br />
<br />
| [[User:HomerHorwitz|homerh]] <br />
| Homer Horwitz <br />
| Homer Horwitz <br />
| <br /> <br />
| +2 <br />
| Independent <br />
| Rev. engineering, "now, that's funny" problems, but still interested in all parts of it<br />
|-<br />
<br />
| [[User:Nlin|nlin]] <br />
| N Lin <br />
| Standard Drucker <br />
| <br /> <br />
| +9 <br />
| [http://www.3di.jp/en/ 3Di Inc, Japan]<br />http://www.3di.jp/en/ <br />
| Physics, scripting, more to come<br />
|-<br />
<br />
| [[User:Arthursv|arthursv]] <br />
| Arthur Valadares <br />
| <br />
| NONE <br />
| -8 <br />
| University of California, Irvine <br />
| Unit testing, database plugins, bug fixes, general<br />
|-<br />
<br />
| [[User:DrScofield|drscofld]] <br />
| Dirk Husemann <br />
| Dr Scofield <br />
| <br />
| +1 <br />
| [http://xyzzyxyzzy.net/ xyzzyxyzzy.net] <br />
| Reliability, networking protocols, inventory, assets, remote control, voice, and pretty much everything else&nbsp;:-) <br />
|-<br />
<br />
| [[User:Teravus|Teravus]] <br />
| Daniel Olivares <br />
| Teravus Ousley <br />
| <br />
| -5 <br />
| W3z <br />
| Physics &amp; Admin tools, A working sim.<br />
|-<br />
<br />
| [[User:Chi11ken|chi11ken]] <br />
| Jeff Ames <br />
| Chillken Proto <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
<br />
| [[User:Marck|Marck00]] <br />
| M. Kirsch <br />
| Marck Kjeller <br />
| <br />
| +1 <br />
| Independent <br />
| Everything that catches my attention and that I can get my head around. <br />
|-<br />
<br />
| [[User:Snoopy2|Snoopy2]] <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
|<br />
| [http://www.dreamlandmetaverse.com/ http://www.dreamlandmetaverse.com/] <br />
| OpenSim region and grid hosting<br />
|-<br />
<br />
| [[User:Justincc|justincc]] <br />
| Justin Clark-Casey <br />
| Lulworth Beaumont <br />
| Justin Clark-Casey (all other grids) <br />
| 0 <br />
| OSVW Consulting<br />[http://justincc.org/blog justincc's OpenSimulator blog] <br />
| Grid, performance &amp; reliability, inventory (avatar and object), assets, scenes, OARs, etc. Generally speaking, my main interest is to create infrastructure that other people can build on top of.<br />
|-<br />
<br />
| [[User:Dslake|dslake]] <br />
| Dan Lake <br />
| Dan Lake <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| Scalability, Performance, Network stack<br />
|-<br />
<br />
| cmickeyb <br />
| Mic Bowman <br />
| Mic Bowman <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
|-<br />
| [[User:BlueWall|BlueWall]] <br />
| James Hughes <br />
| BlueWall Slade <br />
| BlueWall Slade <br />
| -5 <br />
| BlueWall Information Technologies, LLC <br />
| Various parts<br />
|-<br />
| [[User:Nebadon|Nebadon]] <br />
| Michael Emory Cerquoni <br />
| Nebadon Izumi <br />
| Nebadon Izumi <br />
| -5 New Jersey <br />
| Oni Kenkon Creations, Encitra, 4Dialog, Avacon<br />
| Building, Scripting, Testing<br />
|-<br />
| orenh<br />
| Oren Hurvitz<br />
|<br />
|<br />
| +2<br />
| Kitely<br />
|<br />
|-<br />
| AliciaRaven<br />
| Alicia Richardson <br />
| ClaudiaDLioncourt<br />
| <br />
| 0 GMT<br />
| <br />
|-<br />
<br />
|}<br />
<br />
== Retired Core Developers ==<br />
<br />
Core developers who have transcended our mortal plane, i.e. they are no longer directly engaged with the project. Thank you forever for your contributions! <br />
<br />
* '''Only formerly voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Babblefrog|babblefrog]] <br />
| Brian McBee <br />
| Dogen Coldstream <br />
| Babblefrog Ballistic (osgrid) <br />
| -8 <br />
| Disorganized <br />
| &nbsp;<br />
|-<br />
| [[User:Danx0r|danx0r]] <br />
| Dan Miller <br />
| Albert Pascal <br />
| <br />
| -8 <br />
| squiggle.com <br />
| PHEEZIKS; everything<br />
|-<br />
| Tleiades <br />
| &nbsp; <br />
| Tleiades&nbsp;Hax <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Grid servers/Database<br />
|-<br />
| [[User:Darok|Darok]] <br />
| &nbsp; <br />
| Darok Kaminski <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Physics engines (especially BulletX)<br />
|-<br />
| Gareth / Gwen <br />
| Gareth Nelson <br />
| Gareth Ellison <br />
| Gareth Nelson (on everywhere but SL) <br />
| BST (UTC+1) <br />
| Litesim Ltd <br />
| Grid servers, sim border crossing, avatar animations<br />
|-<br />
| [[User:Dalien|dalien]] <br />
| Dalien Talbot <br />
| Dalien Talbot <br />
| <br />
| +1 <br />
| Mostly TCP-based <br />
| Small fixes; rev.eng./prototyping; nightlies; git-keeper<br />
|-<br />
| [[Alondria]] <br />
| <br />
| Alondria LeFay <br />
| Alondria LeFay (OSGrid) <br />
| -8 <br />
| Independent <br />
| Implementation of LSL functions and other scripting tidbits.<br />
|-<br />
| [[User:SeanDague|sdague]] <br />
| Sean Dague <br />
| Neas Bade <br />
| <br />
| -5 <br />
| IBM <br />
| Database, Linux, Testing, Misc<br />
|-<br />
| [[User:MingChen|MingChen]] <br />
| Mike/Michael Ortman <br />
| Ming Chen <br />
| <br />
| -6 (-5 in Summer) <br />
| DeepThink Pty Ltd <br />
| Estate/Parcel Support/Modules/Keeping things all neat and tidy.<br />
|-<br />
| [[User:Tedd|Tedd]] <br />
| Tedd Hansen <br />
| Tedd Maa <br />
| <br />
| +1 <br />
| Tedd Hansen <br />
| Programming/Scripting/Architecture<br />
|-<br />
| [[User:Adjohn|adjohn]] <br />
| Adam Johnson <br />
| Zeuz Zenovka <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Joha1|joha1]] <br />
| Johan Berntsson <br />
| Joppi Brandenburg <br />
| <br /> <br />
| +9 <br />
| &nbsp; <br />
| Performance, packet handling/libSL<br />
|-<br />
| jhurliman <br />
| John Hurliman <br />
| John Hurliman <br />
|<br />
|<br />
|<br />
|<br />
|-<br />
| [[User:Dahlia|dahlia]] <br />
| T. Hoff <br />
| Dahlia Trimble <br />
| <br />
| -8 / -7 <br />
| Independent <br />
| Collision geometry, various math and physics issues, occasional bug fixes and random enhancements<br />
|-<br />
| [[User:Fly-man-|Fly-Man-]] <br />
| Laurence <br />
| <br />
| OSGrid: Fly Man <br />
| GMT +1 <br />
| Private Company<br />
| Testing, OpenSimSearch, OpenSimProfile<br />
|-<br />
|}<br />
<br />
== Wiki Sysops ==<br />
<br />
Along with the core developers, these people help manage the OpenSimulator wiki as well as make other contributions (see Areas of Interest). <br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Makopoppo|Makopoppo]] <br />
| Makiko Nomura <br />
| Mako Nozaki <br />
| Everywhere <br />
| +9 Tokyo, Japan <br />
| As an individual developer <br />
| Everything for improving usability and connectability - wiki/issue management, documentation, localization(Japanese), modifying the interface mainly of core modules<br />
|-<br />
| [[User:Fritigern|Fritigern]] <br />
| S-E-C-R-E-T <br />
| Fritigern Gothly <br />
| SecondLife, OSGrid <br />
| +1 GMT <br />
| <br />
| My interests are many, and extremely varied. One thing that i am very interested in, is seeing OpenSimulator grow, mature, and develop into something that really does rival SL/LL.<br />
|}<br />
<br />
== Additional Developers/Testers/Contributors ==<br />
<br />
These people have contributed and/or are contributing bug reports, patches, testing, and all sorts of other goodies to the project. <br /> '''Newcomers please add yourself to bottom of the list!''' <br /> <br />
<br />
{| cellspacing="0" cellpadding="5" border="1" align="center" style="width: 100%;" class="sortable"<br />
|- style="background-color:#57C604;font-size:10pt;font-weight:bold;border-bottom:1px solid;" align="center" valign="bottom"<br />
<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Jtclark48|jclark4]] <br />
| Jay Clark <br />
| Jay Clarke <br />
| <br />
| -5 <br />
| IBM <br />
| Physics, Grid Host, AI, Scripting, Testing<br />
|-<br />
| [[User:AdamStevenson|BigFootAg]] <br />
| Adam Stevenson <br />
| Adamus Petrov <br />
| <br />
| -6 <br />
| Texas A&amp;M University <br />
| AI, Skynet, Evolving Systems, Biology<br />
|-<br />
| [[User:Jeff1564|Jeff1564]] <br />
| Jeff <br />
| Potter Taurog <br />
| Potter Taurog <br />
| -8 <br />
| http://myopengrid.com <br />
| Building, Scripting, Testing<br />
|-<br />
| Rock_Vacirca <br />
| Colin Withers <br />
| Rock Vacirca <br />
| &nbsp; <br />
| +1 <br />
| http://rock-vacirca.blogspot.com <br />
| Testing, building, scripting, maintaining an opensim blog.<br />
|-<br />
| simsim <br />
| caocao <br />
| &nbsp; <br />
| &nbsp; <br />
| +9 <br />
| &nbsp; <br />
| Testing whole functions of OpenSimulator system,working with OpenSim-Engine,reporting on OpenSimulator<br />
|-<br />
| [[User:Vicero Lambert|Vicero Lambert]] <br />
| &nbsp; <br />
| &nbsp; <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
| [[User:Magi|Magi]] <br />
| Andy Agnew <br />
| Magi Merlin <br />
| <br />
| +10 <br />
| Spun Pty Ltd <br />
| 3D Web Integration, Database stuff and playing with the odds and ends box.<br />
|-<br />
| [[User:ClarkZone|ClarkZone]] <br />
| Troy Admin(@ClarkZone) <br />
| Troy Childs <br />
| Troy Admin (ClarkZone) <br />
| -5 <br />
| Http://clarkzone.dyndns.org <br />
| Tester and Grid Host<br />
|-<br />
| [[User:Aiaustin|aiaustin]] <br />
| Ai Austin <br />
| Ai Austin <br />
| Ai Austin <br />
| +0 <br />
| AIAI, Virtual University of Edinburgh<br />http://www.aiai.ed.ac.uk/~ai/<br />http://vue.ed.ac.uk/openvue/ <br />
| Windows tests<br />Content testing<br />Use of multiple VWs<br />
|-<br />
| Marc Manders <br />
| Marc Manders <br />
| &nbsp; <br />
| &nbsp; <br />
| +6 <br />
| marcmanders@gmail.com <br />
| Creative features<br />
|-<br />
| [[User:Balthazar|balthazar]] <br />
| Trevor Brooks <br />
| Balthazar Sin <br />
| <br />
| -5 <br />
| None <br />
| Terrains, testing and some small coding tasks<br />
|-<br />
| [[User:Jimbo2120|jimbo2120]] <br />
| Michael Osias <br />
| Illuminous Beltran <br />
| <br />
| -5 <br />
| IBM <br />
| Grid, AI, Skynet, coding and testing<br />
|-<br />
| ZeroPoint <br />
| &nbsp; <br />
| Guilderoy&nbsp;Dench <br />
| <br />
| -5 <br />
| &nbsp; <br />
| Programming/Database<br />
|-<br />
| [[User:DerekTang|DerekTang]] <br />
| Derek Tang <br />
| Derek Timeless <br />
| Derek Tang (ChineseGrid) <br />
| +8 <br />
| http://ChineseGrid.net <br />
| Running a public WINDOWS sim for testing, Docs, Helping Chinese users to enjoy OpenSim; building Chinese OpenSimulator communities. In construction...<br />
|-<br />
| [[User:TayB|TayB]] <br />
| Earl Balai <br />
| Taylor Dae <br />
| <br />
| -10 <br />
| WhynGrid <br />
| Grid Host,Networking,Contributions &amp; Testing.<br />
|-<br />
| [[User:JamieDav|JamieDav]] <br />
| Jamie David <br />
| Jamie David <br />
| <br />
| +7 <br />
| Forum <br />
| Grid, Sim, Avitar, Functionality<br />
|-<br />
| [[User:Krtaylor|Krtaylor]] <br />
| Kurt Taylor <br />
| Kurt Stringer <br />
| <br />
| -6 <br />
| IBM <br />
| Grid, Networking, Monitoring, Scripting, Inventory, Testing<br />
|-<br />
| [[User:Nink|Nink]] <br />
| Peter Finn <br />
| Nink Noonan <br />
| <br />
| -5 <br />
| IBM <br />
| Disruptive Influence.<br />
|-<br />
| [[User:Bruce|Bruce]] <br />
| Bruce Meerson <br />
| Bruce Meerson <br />
| <br />
| +8 <br />
| HiPiHi <br />
| Watching.<br />
|-<br />
| [[User:Darb|DarbD]] <br />
| Brian B. Quinn <br />
| Darb Dabney <br />
| regions<br />near Marin <br />
| PST/SLT (-7 or -8) <br />
| County of Marin, California<br /> http://blog.3dmap.me <br />
| LiDAR-based sculpties, real-world terrain, <br />pursuit of civic paraverses, virtual Emergency Operations Centers<br />
|-<br />
| [[User:Charlie Omega|CharlieO]] <br />
| Dan <br />
| Charlie Omega <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| Mild coding/tweaking/simple feature adds, Stress testing/break stuff, Testing limits of existing code. Making sure [[LSL Status]] is up to date<br />
|-<br />
| oobscure <br />
| &nbsp; <br />
| Opensource Obscure <br />
| <br />
| +1 <br />
| http://www.opensim.it <br />
| Running a public Linux sim for testing, Docs, Helping italian users, Building opensim communities, Watching<br />
|-<br />
| pitman <br />
| Mike Pitman <br />
| Rez Tone <br />
| <br />
| &nbsp; <br />
| IBM <br />
| Scientific visualization schemes, virt world product design, persistant workspaces, virt world based big biz<br />
|-<br />
| Shenlei <br />
| Shenlei Winkler <br />
| Shenlei Flasheart, Shenlei Winkler <br />
| <br />
| &nbsp; <br />
| Fashion Research Institute <br />
| Product Design and Development, Apparel industry, and o yes, I wrote the book&nbsp;;)<br />
|-<br />
| cmu <br />
| Christopher Mumme <br />
| Snook Destiny <br />
| <br />
| +1 <br />
| http://www.cmu-develop.de/ and research group "Collaboration Systems and CSCW" at Clausthal University of Technology <br />
| Testing OpenSim, working with OpenSim-Engine, reporting on OpenSimulator<br />
|-<br />
| [[Silpol]] <br />
| Andriy Tymchenko <br />
| Andy Tir <br />
| <br />
| EET (+2/3) <br />
| http://silpol.blogspot.com/ (also visible at Nokia) <br />
| Highly uncoordinated mess with elements of palace games, under-table diplomacy, rebellion, coup d'état and mutiny. optionally pirate<br />
|-<br />
| [[User:Grumly|Grumly]] <br />
| <br />
| Forest Klaar <br />
| Grumly TheBear <br />
| GMT+1 <br />
| .NET MCAD Dev/Arch/Trainer http://www.devoteam.com <br />
| Trying to get into OpenSimulator code for now. Particularly interrested in data persistence. blog (Hello, Avatar!): http://lslblog.free.fr<br />
|-<br />
| [[User:DaTwitch|DaTwitch]] <br />
| James G. Stallings II <br />
| <br />Lazarus Longstaff <br />
| Hiro Protagonist (OSGrid) <br />
| -5 <br />
| House Husband <br />
| OSGrid Region owner, OSGrid Operator,<br />Forum Admin, sometime wiki editor<br />
|-<br />
| gryc <br />
| Gryc Ueusp <br />
| Gryc Uriza <br />
| Gryc Uriza(OSGrid) <br />
| -6 <br />
| <br />
| PHP scripting, web interfaces, interconnectivity, cross-platformedness<br />
|-<br />
| [[User:Phrearch|Phrearch]] <br />
| Jeroen van Veen <br />
| Phrearch Miles <br />
| Phrearch Miles(OSGrid) <br />
| Amsterdam/Paris <br />
| <br />
| HWIOS, WiXTD, Wikidoc, Moo, User interfaces<br />
|-<br />
| [[User:Burnman|Burnman]] <br />
| Allen <br />
| Burnman Bedlam <br />
| <br />
| Boston, USA <br />
| <br />
| Testing, testing, and more testing! Getting familiar with the source, interested in all aspects of the project.<br />
|-<br />
| [[User:Krisbfunk|krisbfunk]] <br />
| Kris Bulman <br />
| Krisbfunk Vought <br />
| Krisbfunk Nocturnal(OSGrid) <br />
| PE, Canada (-4) <br />
| Edactive Technologies<br />NocturnalEye Productions<br />UPEI <br />
| Currently: Testing, bug reports, wiki updating, building on OSGrid<br />
|-<br />
| [[User:HashBox|HashBox]] <br />
| &nbsp; <br />
| Sibariel Darkstone <br />
| Sibariel Darkstone (OSGrid) <br />
| New Zealand (+12) <br />
| <br />
| Testing, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Kinoc|Kinoc]] <br />
| Kino Coursey <br />
| Daxxon Jaxxon <br />
| Daxxon Kinoc (OSgrid) <br />
| -6 <br />
| Daxtron Laboratories <br /> http://www.daxtron.com<br /> University of North Texas <br />
| AI, Semantic web, Ontologies, Natural Laanguage Processing, Cyc, Bots, NPC<br />
|-<br />
| [[User:Trapuh|trapuh]] <br />
| Pedro Ribeiro <br />
| Vaiten Forder <br />
| <br />
| GMT <br />
| University Student, Escola Superior de Educação de Viseu, Portugal <br />
| Testing, eventual bug reports and wiki. Music, web/digital arts and php+sql.<br />
|-<br />
| [[User:SonicViz|SonicViz]] <br />
| Paul Cohen <br />
| Komuso Tokugawa <br />
| <br />
| +9 <br />
| Http://sonicviz.com <br />
| Audio/Music, Interactive Music, Control Protocols, Interfaces, VisualFX, Procedural animation/Generative systems + testing and general dev<br />
|-<br />
| [[User:Mokele|mokele]] <br />
| Scott Norman <br />
| Mokelembembe Mokeev <br />
| <br />
| -8 (Southern California) <br />
| Web Developer (PHP and MySQL) <br />
| Interested in seeing running on PowerPC Macs which it is. So, when I can, I'll compile and test on PowerPC Mac (PowerBook G4) and submit reports and then update the wiki if need on installing on Mac. Also have a Ubuntu 7.10 server that I can do testing on too.<br />
|-<br />
| [[User:Devalnor|devalnor]] <br />
| Devalnor <br />
| M. Watkin <br />
| <br />
| +1 (Belgium) <br />
| <br />
| Small Patch code, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Ezekiel|Ezekiel]] <br />
| Ezekiel <br />
| Ezekiel Zabelin <br />
| <br />
| +1 <br />
| http://www.yosims.com <br />
| Concepts, business aspects of virtual worlds - web developer (PHP, MySQL, Javascript, LSL)<br />
|-<br />
| [[User:Buggmaster|Buggmaster]] <br />
| Mike D <br />
| Bug Master <br />
| None <br />
| -8 <br />
| http://www.adultmetaverse.com <br />
| Grid, Data/Web PHP/PERL/MySQL<br />
|-<br />
| [[User:Nixnerd|nixnerd]] <br />
| <br />
| Dangerously Moody <br />
| None <br />
| GMT <br />
| http://www.integratedtechnologies.eu <br />
| Cross Platform Testing, Feedback, Bug Reporting<br />
|-<br />
| [[User:MoHax|mohax]] <br />
| Mo Hax <br />
| Mo Hax <br />
| <br />
| -5 Eastern <br />
| IBM <br />
| Testing, Feedback, Content Contributions, Bug Reporting, Documenting, Development<br />
|-<br />
| [[User:Webmage|webmage]] <br />
| webmage <br />
| Leyla Masala <br />
| Web Mage <br />
| +1 <br />
| IBM <br />
| Testing, terrain<br />
|-<br />
| [[User:NLStitch|NLStitch]] <br />
| Marijn Oosterveld <br />
| Stitch Seale <br />
| NYA <br />
| GMT +1 Amsterdam <br />
| Twingate Systems (http://www.twingate.nl)<br />HanzeHogeschool Groningen, Netherlands <br />
| Programming, Photography, AI<br />
|-<br />
| [[User:Ideia Boa|Ideia Boa]] <br />
| Joao Lopes <br />
| Ideia Boa <br />
| Ideia Boa or Boa Ideia in some grids <br />
| GTM+1 Stockholm/Sweden <br />
| WorldSimTERRA - Virtual World that speaks Portuguese too<br />http://www.worldsimterra.com <br />
| Testing and more testing! Updating the original wiki and translating the OpenSimulator Wiki into Portuguese and reporting on OpenSimulator<br />
|-<br />
| [[User:Lulurun|lulurun]] <br />
| liu <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| 3Di Inc, Japan <br />http://www.3di.jp <br />
| Patches, openid, server performance, UGAI<br />
|-<br />
| [[User:Carlosroundel|Carlosrounde]] <br />
| Carlosroundel <br />
| Carlos Roundel <br />
| <br /> <br />
| +1 <br />
| Cyberlandia Italy<br />http://www.cyberlandia.net <br />
| Grid, programmer, database, tester<br />
|-<br />
| [[User:Mikebert|Mikebert]] <br />
| Mike<br />
| Mikebert Miles <br />
| Mikebert<br />
| +1 <br />
| OpenSIM Wiki, Germany<br />https://www.mikebert.de/archiv/opensim<br />
| German Wiki, Translater, Server Performance (Linux/Windows), Tester, Feedback, Bug Reporting, Server-Hosting<br />
|-<br />
| Taoki <br />
| Mircea Kitsune / Taoki Vixen <br />
| Mircea Kitsune (OSGrid) / Mircea Lobo (LL grid) <br />
| <br /> <br />
| GMT +2 <br />
| <br /> <br />
| Usually testing and bug reporting but I also make smaller patches where I know what to do.<br />
|-<br />
| [[User:Patnad|Patnad]] <br />
| Patrick <br />
| Patnad Babii <br />
| Patnad Babii (OSGrid) <br />
| GMT -5 <br />
| RezzMe Technologies<br />http://www.rezzme.com <br />
| Bug testing and reporting, I code C# and have submitted a few patches<br />
|-<br />
| [[User:^DarkMan|^DarkMan]] <br />
| Brian Adair <br />
| Patrick Ouachita <br />
| Brian Adair &#124; Patrick Meta <br />
| -6 CST <br />
| RealMetaLife &#124; B&amp;H Networking <br />
| Building, Scripting, Testing, etc.<br />
|-<br />
| [[User:Tlaukkan|Tommi Laukkanen]] <br />
| Tommi Laukkanen <br />
| &nbsp; <br />
| Tommi Laukkanen <br />
| +2 GMT <br />
| http://www.bubblecloud.org <br />
| Protocols ([http://www.bubblecloud.org MXP]), NHibernate, Scrip API, Map Generation, Bug Fixes, Grid Hosting<br />
|-<br />
| [[User:Mystical|Mystical]] <br />
| Kevin Tweedy <br />
| Mystical Demina <br />
| Mystical Demina <br />
| -5 <br />
| Extreme Reality Grid<br />http://www.XRGrid.com <br />
| Windows Communication Framework, Windows Workflow,Entity Framework, MSSQL<br />Enhancements,Commerce, Content,DotNetNuke based portal, development services<br />
|-<br />
| [[User:Godfrey|Godfrey]] <br />
| Jeff Lee <br />
| Warin Cascabel <br />
| <br />
| -5 (EST5EDT) <br />
| <br />
| Testing, minor bugfixes. Scripting, building, animating<br />
|-<br />
| Jamenai <br />
| Christopher Händler <br />
| Jamenai Luik <br />
| Jamenai Luik <br />
| +1 <br />
| Playneko Grid &#124; XIMDEX Jamenai<br />http://www.playneko.de<br />http://www.ximdex.de <br />
| Performance,Bug Reporting, Hosting, Grid-Owner,(PHP, MySQL, Perl, JavaScript, LSL)<br />
|-<br />
| [[User:Bikcmp|bikcmp]] <br />
| Jason <br />
| Jake1500 Allen <br />
| Jason Helios (The Helios Grid) <br />
| EST <br />
| Blue Software <br />
| Search, groups, land, and currency<br />
|-<br />
| [[User:Mark.malewski|Slipaway]] <br />
| Mark Malewski <br />
| Chris Rock <br />
| <br />
| -6 (-5 during summer - CDT) <br />
| NexTECH / Joopla <br />
| Web development &amp; systems integration, terrain, WIKI documentation, tutorials, testing, bug reporting and feedback.<br />
|-<br />
| barakademi <br />
| Steve Topp <br />
| barakademi Barzane <br />
| same avi on baragrid OSgrid Grid4us sciencesim <br />
| utc+1 (CET) paris <br />
| http://xbot-sl.barakademi.org http://vps.barakademi.org/oswi http://vps.barakademi.org/oswi/loginscreen.php <br />
| Music LiveMusic MetaverseMusic Opensim Libomv Mono-2.4 Linux (suse,debian,ubuntu) Admin Scripting Automating Development Intergration php mysql bash nant +++<br />
|-<br />
| [[User:Robert d|robert_d]] <br />
| Robert Dzikowski <br />
| <br />
| OSGrid: robert_d 13 <br />
| UTC+1 <br />
| [http://blog.rd-it.net http://blog.rd-it.net] <br />
| Region Modules, Tutorials<br />
|-<br />
| john_ <br />
| John&nbsp;Moyer <br />
| VAJohn&nbsp;GeekSquad or&nbsp;Matthew&nbsp;Kendal <br />
| <br />
| -5 <br />
| Best&nbsp;Buy/Geek&nbsp;Squad <br />
| Tester<br />
|-<br />
| [[User:W!cKeD|_WicKeD]] <br />
| Maik <br />
| Maik Galaxy <br />
| El Diablo <br />
| +1 Germany <br />
| Creatio Inc. / [http://www.OpenSimGerman.us/ OpenSimGerman.us] <br />
| German Support, Translator, Building, Scripting, Testing, Hosting<br />
|-<br />
| [[User:Stevie Wakowski|Stevie Wakowksi]] <br />
| Steve Roberts <br />
| Stevie Wakowski <br />
| <br />
| +10 Australia <br />
| IBM <br />
| OpenSimulator builds, Linux, Modrex, bug reporting, evangalist for OpenSimulator in business applications.<br />
|-<br />
| Revolution <br />
| Matthew <br />
| Revolution Smythe <br />
| Revolution Smythe <br />
| -6 Central USA <br />
| None <br />
| Script engine, physics engine, general odd bugs, interesting and odd things<br />
|-<br />
| [[User:ClemsonGS|clemsonGS]] <br />
| Brian Cass <br />
| BC Sands <br />
| Brian Cass (VWC Grid) <br />
| -5 <br />
| http://www.cvwconline.org/ <br />
| Developing virtual worlds for use in higher education<br />
|-<br />
| <br />
| AlexRa <br />
| <br />
| <br />
| <br />
| Independent <br />
| <br />
|-<br />
| <br />
| <br />
| Mikko Pallari <br />
| <br />
| <br />
| Realxtend <br />
| <br />
|-<br />
| <br />
| StrawberryFride <br />
| Chris Hart <br />
| <br />
| <br />
| ReactionGrid <br />
| <br />
|-<br />
| [[User:RemedyTomm|RemedyTomm]] <br />
| Tom Grimshaw <br />
| Tomm Remedy <br />
| KGrid: Casper Warden OSGrid: Tomm Remedy <br />
| UTC+0 (BST) <br />
| Remedy Communications <br />
| Texture pipeline, Groups, ObjectUpdates<br />
|-<br />
| <br />
| <br />
| Rob Smart <br />
| <br />
| <br />
| IBM <br />
| <br />
|-<br />
| MicheilMerlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| -6 <br />
| Independent <br /> [http://www.iliveisl.com/ http://www.iliveisl.com/] <br />
| Scripting, patches, and testcases<br />
|-<br />
| Pato Donald <br />
| Pato Donald <br />
| Morgam Biedermann <br />
| Pato Donald <br />
| -3 <br />
| Independent [http://www.matheusmk3.co.cc/ http://www.matheusmk3.co.cc/ <br />
| Groups, Scripts, Physics, Communication, Integration<br />
|-<br />
| <br />
| Sera Marx <br />
| Darkfire Soulstar <br />
| <br />
| +12 <br />
| Radiance promotions <br />
| Grid Host, Commissioner. ~ Anyone looking for work related to the development of Opensimulator or Viewers please contact me. Any work undertaken for me will be returned to Opensimulator unless made strictly for my Grid<br />
|-<br />
|[[User:dz|dz]] <br />
| D Osborn <br />
| ydoo magic<br />
| delta zed @ OSGRID Doug Osborn @ ScienceSim & MOSES grids<br />
| PST/SLT (-7 or -8) <br />
| CEO OpenSimian <br />
| Performance testing, advanced scripting, high prim count builds, Client and server side bots, Animation Overrides, MANTIS maintenance.<br />
|-<br />
| [[User:Hallow Palmer|Hallow Palmer]] <br />
| Markus <br />
| Hallow Palmer <br />
| <br /> <br />
| +1 <br />
| Grid4Us<br />http://www.grid4us.net <br />
| Server Performance (Windows), Tester, Feedback, Business concepts,Bug Reporting, Server-Hosting<br />
|-<br />
| [[User:LenaVanilli|LenaVanilli]] <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| +1 Germany <br />
| [http://www.hypergrid.org http://www.hypergrid.org] <br />
| Grid-Management, Testing Testing Testing, Region Hosting<br />
|-<br />
| [[User:Aduffy70|aduffy70]] <br />
| Aaron Duffy <br />
| Aeran Stipe <br />
| Aaron Duffy @ScienceSim <br />
| -7 <br />
| USU <br />
| Scientific visualization &amp; education, Region modules, Heavily scripted regions<br />
|-<br />
| <br />
| Erich Bremer <br />
| Erich Bremer <br />
| <br />
Erich Bremer@OSGrid <br />
<br />
| -5 <br />
| http://www.ebremer.com <br />
| Semantic Web, Data Visualization<br />
|-<br />
| [[User:MarkIDCAS|MarkIDCAS]] <br />
| Mark Bannon <br />
| Mark IDCAS <br />
| 3D Grid Association, AtMeeting, Valhalla Virtual and IDCAS. <br />
| GMT <br />
| [http://www.valhallavirtual.com http://www.valhallavirtual.com] <br />
| Grid Management &amp; systems integration. Scripting. WIKI documentation, tutorials, bug reporting and feedback.<br />
|-<br />
| [[User:Allquixotic|allquixotic]] <br />
| Sean McNamara <br />
| Tiyuk Quellmalz <br />
| OSG: Tiyuk Quellmalz <br />
| -5 <br />
| None <br />
| Bugfixing; networking; performance; data integrity; LSL; auto-backup; null DB (eventual consistency).<br />
|-<br />
| [[User:Orenh|orenh]] <br />
| Oren Hurvitz <br />
| <br />
| Oren Hurvitz (Kitely) <br />
| +2 <br />
| Kitely <br />
| <br />
|-<br />
<br />
| [[User:Randomhuman|randomhuman]] <br />
| Kevin Houlihan <br />
| random Radikal <br />
| random human (OSGrid) <br />
| WET/IST <br />
| CrimsonCookie <br />
| RemoteAdmin module; On-demand grids; web integration.<br />
|-<br />
<br />
| [[User:Oddball Otoole|oddball otoole]]<br />
| J.v.Hogeloon<br />
| Oddball Otoole<br />
| Oddball Otoole (OSGrid<br />
| +1 (The Netherlands<br />
| None<br />
| Building, scripting, testing, social stuff.<br />
|-<br />
| [[User:Pixel|Pixel Tomsen]]<br />
| Christian Kurzhals<br />
| Pixel Tomsen<br />
| Pixel Tomsen OSGrid<br />
| +1 (Germany<br />
| see my profil<br />
| Dev, Building, scripting, sim-hosting, some modules, patches, osgrid<br />
|-<br />
| [[User:kenearlg|kenearlg]]<br />
| Ken Grunke<br />
| Key Grau<br />
| Key Gruin (Osgrid)<br />
| -6 CST<br />
| http://www.osgrid.org/<br />
| testing, moderating, inworld games & recreation, wiki spam control<br />
|-<br />
| [[User:CG4Life|CG4Life]]<br />
| CG Anderson<br />
| Cyn Hak<br />
| <br />
| -8 PST<br />
| Little Dogs Media<br />
| Networking, Security, Performance (parallelization, compression, encryption), physics, 3D manipulation, bugfixing, documentation. Just getting into the code base, so will start with compression/parallelizatoin ideas and bugfixing, then other stuff later.<br />
|-<br />
| [[User:vegaslon|vegaslon]]<br />
| Adam Ivie<br />
| vegaslon plutonian<br />
| <br />
| -5 EST<br />
| Independent <br />
| Physics, Vehicles, Advanced Scripting, Testing, Advanced Land Usage.<br />
|-<br />
<br />
| [[User:AliciaRaven|AliciaRaven]] <br />
| Alicia Richardson <br />
| ClaudiaDLioncourt<br />
| Alicia Raven (Spellscape) <br />
| 0 GMT<br />
| Spellscape Ltd<br />http://www.spellscape.co.uk<br />
|<br />
|-<br />
<br />
| [[User:Djphil|djphil]] <br />
| Philippe Lemaire <br />
| dj phil<br />
| dj phil<br />
| +2 GMT<br />
| Collab 3D Asbl<br />
| Testing, Scripting, Helping<br />
<br />
|-<br />
| [[User:Steevithak|Steevithak]]<br />
| Steve Rainwater<br />
| Steevithak<br />
| Steevithak x (OSgrid)<br />
| -6/-5 (CST/CDT)<br />
| Independent, [https://steevithak.com steevithak.com]<br />
| scalability, performance, protocols, everything else. Also MediaWiki<br />
<br />
|}<br />
<br />
[[Category:Development]]</div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2022-07-01T16:58:43Z
<p>Dz: /* Group Land add-on */</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
<br />
Configurable Access by owner, group, or individuals (DJs)<br />
<br />
Default Texture override.<br />
<br />
10 user defined GENRE Categories.<br />
<br />
Unlimited URLs per GENRE.<br />
<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
I recommend at least 2 prims to construct the board.<br />
<br />
First, a Display prim to hold the script and display the info.<br />
<br />
I like to size it 1H and 2W so 256x512 & 512x1024 textures display without distortion.<br />
So, rez a box and resize it X: 0.05 meter Y: 2 meter and Z: 1 meter.<br />
<br />
Create a note card named "Radio Control config", paste the example text from the section below, and put it in the prim.<br />
<br />
Create a new script in the prim. Paste a copy of the script from below over the default script and save it. <br />
<br />
When you touch the prim you will either trigger the MOAP display, or a menu to turn the radio on. You might notice that touching the MOAP surface again does NOT generate a menu. That is why we link the second prim, to act as a frame you can touch from the front of the board to get a menu.<br />
<br />
I like to texture all of the non-display sides of the Display prim black. <br />
<br />
Create a second prim , slightly larger than the first, color and texture as you prefer, and then position it so that it frames the display prim. Select the Display prim LAST , to make sure it is linked as root, and link the 2 prims. Now you should be able to touch the frame to get access to the menus.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable. When it was first posted it included SL specific addresses for returning profile images by UUID... these will be removed.... <br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) D Osborn 4/25/2011<br />
// version 3 (c) D Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// D Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 D Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
# New format Shoutcast - radio controller config notecard<br />
# The format is divided in 4 sections:<br />
# 1 - Access configuration<br />
# 2 - Ban list (keys)<br />
# 3 - Categories (same as genres)<br />
# 4 - Station info (category, name, desc, url)<br />
# The '#' character defines the start of a comment and can be anywhere on a line. <br />
# Everything after the '#' incuding the '#' itself is ignored.<br />
# Case is not important (but information on display will show as entered)<br />
# Spaces before and/or after fields are trimmed.<br />
# Empty lines are ignored.<br />
<br />
[ACCESS]<br />
dj=no # yes, true,1 means dj's has access. everything else not.<br />
group=no # ,, ,, ,, means group has acess. ,, ,, ,,<br />
public=yes # ,, ,, ,, means public has access. ,, ,, ,, <br />
#Avatar UUID with access <br />
12a18155-403d-496f-9dd1-a28a98b98342<br />
#Avatar UUID with access <br />
85fbed46-ba6e-4740-acdd-867dae792bf4<br />
<br />
<br />
[BANNED]<br />
# Avatar UUID BANNED from access <br />
014852ac-0260-4ecc-84fd-9f653b8b841c<br />
<br />
[GENRE]<br />
# genre name -- Use short genre names as the the length of menu buttons is short!<br />
Blues<br />
Classic Rock<br />
Country<br />
Dance<br />
DJ<br />
Jazz<br />
Live<br />
Reggae<br />
Romance<br />
# etc.<br />
[STATION]<br />
# Shoutcast radio stations<br />
# Use a '|' between each field - don't mind spaces before and after fields, they will be trimmed<br />
# field1:genre, field2:station name, field3: station description, field4: station http://<ip>:<port> or https://<ip>:<port>, field5 : dj UUID<br />
# Note that genre must match case-insensitive a value previously entered in section [GENRE]<br />
# Only DJ lines required a DJ ID.. if one is entered it will enable access to, and display the Profile picture of, the UUID provided.<br />
Classic Rock | Absolute | Absolute Radio | http://205.188.215.226:8018<br />
Classic Rock | 181fm | 181fm Classic | http://uplink.181.fm:8058<br />
Blues | KOQX | KOQX | http://69.94.112.216:8000<br />
Blues | One.FM | ONE.FM Stepchilds club | http://64.62.252.130:8030<br />
Blues | BU4B | Belly Up 4 Blues | http://64.62.252.134:5100<br />
Jazz | SwissGrv | Swiss Groove | http://82.197.165.135:80<br />
Jazz | Sky.fm | Smooth Jazz | http://scfire-dll-aa05.stream.aol.com:80/stream/1010<br />
Dance | Fox | Fox | http://87.98.169.191:11418<br />
Dance | Hitz | Hitz | http://scfire-mtc-aa04.stream.aol.com:80/stream/1014<br />
Romance | SlowDance | Slowdance | http://216.155.137.149:8006<br />
Reggae | Roots | BigUpRadio Roots | http://173.236.79.22:8005<br />
Reggae | Ska | BigUpRadio Ska | http://167.114.38.75:8017<br />
DJ | Autumn | DJ Autumn | http://srv8.karadio.biz:56303 | 6f666533-80ee-4d68-922b-6253ed50b973<br />
DJ | Dohran | DJ Dohran | http://dozo.primcast.com:8940 | aa61d79c-244b-4167-be70-a9a575b12c5c<br />
DJ | Jada1 | DJ Jada1 | http://85.214.250.196:8212 | 76f7f2e3-01bf-4ccd-b3b0-3083551e2c87<br />
DJ | P.Parks | DJ Parallel | http://srv3.karadio.biz:18705 | ce735cfe-43fd-45d6-9ba2-8e314c30af4a<br />
DJ | Sesha | Sesha | http://74.222.1.105:8962 | 788fc597-d7bb-4ef8-a27e-7e2ba564c40c<br />
DJ | Troi | Dj Troi | http://srv10.karadio.biz:17959 | 93c39f70-bfd3-4e5f-a4a0-be54bd9ce320<br />
<br />
# etc.<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2022-07-01T16:57:36Z
<p>Dz: /* The BETA script */</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
<br />
Configurable Access by owner, group, or individuals (DJs)<br />
<br />
Default Texture override.<br />
<br />
10 user defined GENRE Categories.<br />
<br />
Unlimited URLs per GENRE.<br />
<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
I recommend at least 2 prims to construct the board.<br />
<br />
First, a Display prim to hold the script and display the info.<br />
<br />
I like to size it 1H and 2W so 256x512 & 512x1024 textures display without distortion.<br />
So, rez a box and resize it X: 0.05 meter Y: 2 meter and Z: 1 meter.<br />
<br />
Create a note card named "Radio Control config", paste the example text from the section below, and put it in the prim.<br />
<br />
Create a new script in the prim. Paste a copy of the script from below over the default script and save it. <br />
<br />
When you touch the prim you will either trigger the MOAP display, or a menu to turn the radio on. You might notice that touching the MOAP surface again does NOT generate a menu. That is why we link the second prim, to act as a frame you can touch from the front of the board to get a menu.<br />
<br />
I like to texture all of the non-display sides of the Display prim black. <br />
<br />
Create a second prim , slightly larger than the first, color and texture as you prefer, and then position it so that it frames the display prim. Select the Display prim LAST , to make sure it is linked as root, and link the 2 prims. Now you should be able to touch the frame to get access to the menus.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable. When it was first posted it included SL specific addresses for returning profile images by UUID... these will be removed.... <br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) D Osborn 4/25/2011<br />
// version 3 (c) D Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
# New format Shoutcast - radio controller config notecard<br />
# The format is divided in 4 sections:<br />
# 1 - Access configuration<br />
# 2 - Ban list (keys)<br />
# 3 - Categories (same as genres)<br />
# 4 - Station info (category, name, desc, url)<br />
# The '#' character defines the start of a comment and can be anywhere on a line. <br />
# Everything after the '#' incuding the '#' itself is ignored.<br />
# Case is not important (but information on display will show as entered)<br />
# Spaces before and/or after fields are trimmed.<br />
# Empty lines are ignored.<br />
<br />
[ACCESS]<br />
dj=no # yes, true,1 means dj's has access. everything else not.<br />
group=no # ,, ,, ,, means group has acess. ,, ,, ,,<br />
public=yes # ,, ,, ,, means public has access. ,, ,, ,, <br />
#Avatar UUID with access <br />
12a18155-403d-496f-9dd1-a28a98b98342<br />
#Avatar UUID with access <br />
85fbed46-ba6e-4740-acdd-867dae792bf4<br />
<br />
<br />
[BANNED]<br />
# Avatar UUID BANNED from access <br />
014852ac-0260-4ecc-84fd-9f653b8b841c<br />
<br />
[GENRE]<br />
# genre name -- Use short genre names as the the length of menu buttons is short!<br />
Blues<br />
Classic Rock<br />
Country<br />
Dance<br />
DJ<br />
Jazz<br />
Live<br />
Reggae<br />
Romance<br />
# etc.<br />
[STATION]<br />
# Shoutcast radio stations<br />
# Use a '|' between each field - don't mind spaces before and after fields, they will be trimmed<br />
# field1:genre, field2:station name, field3: station description, field4: station http://<ip>:<port> or https://<ip>:<port>, field5 : dj UUID<br />
# Note that genre must match case-insensitive a value previously entered in section [GENRE]<br />
# Only DJ lines required a DJ ID.. if one is entered it will enable access to, and display the Profile picture of, the UUID provided.<br />
Classic Rock | Absolute | Absolute Radio | http://205.188.215.226:8018<br />
Classic Rock | 181fm | 181fm Classic | http://uplink.181.fm:8058<br />
Blues | KOQX | KOQX | http://69.94.112.216:8000<br />
Blues | One.FM | ONE.FM Stepchilds club | http://64.62.252.130:8030<br />
Blues | BU4B | Belly Up 4 Blues | http://64.62.252.134:5100<br />
Jazz | SwissGrv | Swiss Groove | http://82.197.165.135:80<br />
Jazz | Sky.fm | Smooth Jazz | http://scfire-dll-aa05.stream.aol.com:80/stream/1010<br />
Dance | Fox | Fox | http://87.98.169.191:11418<br />
Dance | Hitz | Hitz | http://scfire-mtc-aa04.stream.aol.com:80/stream/1014<br />
Romance | SlowDance | Slowdance | http://216.155.137.149:8006<br />
Reggae | Roots | BigUpRadio Roots | http://173.236.79.22:8005<br />
Reggae | Ska | BigUpRadio Ska | http://167.114.38.75:8017<br />
DJ | Autumn | DJ Autumn | http://srv8.karadio.biz:56303 | 6f666533-80ee-4d68-922b-6253ed50b973<br />
DJ | Dohran | DJ Dohran | http://dozo.primcast.com:8940 | aa61d79c-244b-4167-be70-a9a575b12c5c<br />
DJ | Jada1 | DJ Jada1 | http://85.214.250.196:8212 | 76f7f2e3-01bf-4ccd-b3b0-3083551e2c87<br />
DJ | P.Parks | DJ Parallel | http://srv3.karadio.biz:18705 | ce735cfe-43fd-45d6-9ba2-8e314c30af4a<br />
DJ | Sesha | Sesha | http://74.222.1.105:8962 | 788fc597-d7bb-4ef8-a27e-7e2ba564c40c<br />
DJ | Troi | Dj Troi | http://srv10.karadio.biz:17959 | 93c39f70-bfd3-4e5f-a4a0-be54bd9ce320<br />
<br />
# etc.<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/SimStats
User:Dz/SimStats
2022-07-01T16:55:41Z
<p>Dz: /* The script */</p>
<hr />
<div>== MOAP Region Statistics Display ==<br />
<br />
This script proved useful during sim performance tests on the MOSES grid. <br />
<br />
It uses a call to osGetRegionStats to build a small HTML page that it feeds to a MOAP Display. The HTML is designed to be displayed at a resolution of 1024x2048. Size your display board appropriately to avoid distorted text<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/SimStats]]<br />
<br />
<br />
=== The script ===<br />
<br />
The script currently includes a hard coded TextureUUID to load as the default image. You will need to replace that UUID with one local to your grid and appropriate to your purpose. <br />
<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// OpenSim Region Statistics display<br />
<br />
// D Osborn MOSES grid 9/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
<br />
integer displayface = 2;<br />
<br />
string Region = "";<br />
string Parcel = "";<br />
string TimeDate = "";<br />
string TextureUUID = "e0d6e6b8-0a40-3eab-08c2-97711a14d439";<br />
<br />
string FPS = "FPS - Sim: ";<br />
string PHYS = "Physics: ";<br />
string DIA= "Time Dilation: ";<br />
string AVIS= "Root Agents: ";<br />
string SCRPT = "Active Scripts: ";<br />
<br />
default<br />
{<br />
state_entry()<br />
{ <br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
<br />
Region = llGetRegionName(); <br />
Parcel = llList2String(details ,0);<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, TextureUUID, <1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]); <br />
<br />
llSetTimerEvent( 5.0 ); <br />
}<br />
<br />
timer()<br />
{<br />
list Stats = osGetRegionStats();<br />
<br />
string dFPS = FPS + (string) llList2Float( Stats, STATS_SIM_FPS ) ;<br />
string dPHYS = PHYS + (string) llList2Float( Stats, STATS_PHYSICS_FPS );<br />
string dDIA= DIA + (string) llList2Float( Stats, STATS_TIME_DILATION );<br />
string dAVIS= AVIS + (string) llList2Integer( Stats, STATS_ROOT_AGENTS );<br />
string dSCRPT = SCRPT + (string) llList2Integer( Stats, STATS_ACTIVE_SCRIPTS ); <br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='yellow'><i><h1>" + Region + " @ " + Parcel + "</h1><h3>( " + llGetTimestamp() + " )</h3></i><p><h2>"+ dFPS + " - " +dPHYS + "<p>" + dDIA + "<p>" + dAVIS + " - " + dSCRPT + "</h2></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
}<br />
}<br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/Avatar_Scale
User:Dz/Avatar Scale
2022-07-01T16:54:13Z
<p>Dz: /* The script */</p>
<hr />
<div>== Avatar Scale ==<br />
<br />
This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator.<br />
With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using<br />
the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even<br />
attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue<br />
experimenting and improving this important skill.<br />
<br />
Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results<br />
of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique<br />
I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic<br />
BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
The scale relies on the ability to move a seated avatar via script. <br />
This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release.<br />
It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/Avatar Scale]]<br />
<br />
<br />
=== The script ===<br />
<br />
I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it.<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// Avatar proportion scale BETA<br />
// based on an "8 head" (Natural) or "9 head" (Heroic) human shape<br />
<br />
// D Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
//<br />
// To create your own scale from scratch, <br />
// Make a cube to act as your base. Texture it as you like and turn it phantom.<br />
// Make 9 more cubes and stack them on top of each other. <br />
// Link the 9 cubes together and then link that stack to your "base" cube<br />
// Copy the [CheckPorportions] animation and the [Proportional Avatar Sizing} notecard into the base<br />
// Drop this script into your base cube. <br />
// Your stack of cubes should transform into a "Natural" scale for a 2 meter avatar<br />
//<br />
//<br />
<br />
vector MyLocation = <0,0,0>;<br />
rotation MyRotation = ZERO_ROTATION;<br />
<br />
list offsetMultiplier = [1,3,5,7,9,11,13,15,17];<br />
<br />
string ANIMATION = "CheckProportions";<br />
<br />
key avatar = NULL_KEY;<br />
list menuButtons = ["Heroic","Natural","Set Height"]; <br />
list heightButtons = [ "Move Up", "Move Down"];<br />
integer menuchannel = -13572468;<br />
integer heightchannel = -13572469;<br />
integer mListener = 0;<br />
integer cListener = 0;<br />
float sitTargetHeight = 0;<br />
integer NaturalMode = TRUE;<br />
string menuStatusInfo = "";<br />
float currentScaleSize = 2.0;<br />
float menuTimeout = 30.0;<br />
vector primColor = <0.0, 0.0, 0.0>;<br />
float panelDivisor = 4.0;<br />
float widthAdjust = 0.02;<br />
<br />
setScaleDimensions(float newSize)<br />
{<br />
integer numlinks = 11;<br />
panelDivisor = 4.5;<br />
widthAdjust = 0.05;<br />
<br />
if (NaturalMode)<br />
{<br />
numlinks = 10;<br />
panelDivisor = 4;<br />
widthAdjust = -0.025;<br />
}<br />
<br />
llSay(0, "Resizing scale for a " +(string) newSize + " meter avatar");<br />
<br />
currentScaleSize = newSize;<br />
<br />
sitTargetHeight = newSize/2.3;<br />
<br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
<br />
integer link = 2;<br />
while (link < numlinks)<br />
{<br />
float heightOffset = (llList2Integer(offsetMultiplier,link-2) * (newSize/(panelDivisor * 4)));<br />
if (link%2 == 0)<br />
{ <br />
primColor = <0.75, 0.75, 0.75>;<br />
}<br />
else<br />
{<br />
primColor = <0.0, 0.0, 0.0>;<br />
} <br />
<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, heightOffset>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE,<br />
PRIM_COLOR, ALL_SIDES, primColor, 0.5 ]);<br />
link ++;<br />
} <br />
<br />
if (NaturalMode)<br />
{<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, 0.0>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE, <br />
PRIM_COLOR, ALL_SIDES, primColor, 0.0]);<br />
} <br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "OpenSimian Avatar scale is ready to use");<br />
MyLocation = llGetRootPosition(); <br />
MyRotation = llGetRootRotation(); <br />
setScaleDimensions(currentScaleSize); <br />
}<br />
<br />
touch_start(integer numTouches)<br />
{<br />
string mode = "Heroic";<br />
if(NaturalMode)<br />
mode = "Natural";<br />
<br />
menuStatusInfo = "\nCurrent mode : " + mode + "\nAvatar height: " + llGetSubString((string) currentScaleSize, 0, 4) +"(meters)\n \nMake a selection"; <br />
<br />
if (avatar != NULL_KEY)<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, heightButtons, heightchannel);<br />
llSetTimerEvent(menuTimeout); <br />
} <br />
else<br />
{ <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, menuButtons, menuchannel);<br />
llSetTimerEvent(menuTimeout);<br />
} <br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(channel == menuchannel)<br />
{<br />
llListenRemove(mListener);<br />
llSetTimerEvent(0);<br />
<br />
if (message == "Heroic")<br />
{<br />
if ( NaturalMode )<br />
{<br />
NaturalMode = FALSE;<br />
llSay(0,"Resetting to Heroic Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
else<br />
{<br />
llSay(0,"Already in Heroic Mode");<br />
}<br />
}<br />
<br />
if (message == "Natural")<br />
{<br />
if ( NaturalMode )<br />
{<br />
llSay(0,"Already in Natural Mode");<br />
}<br />
else<br />
{<br />
NaturalMode = TRUE;<br />
llSay(0,"Resetting to Natural Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
} <br />
<br />
if (message == "Set Height")<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llTextBox(id, "Enter the total Height of the avatar in METERS", heightchannel);<br />
}<br />
if (message == "Move Up")<br />
{<br />
sitTargetHeight += .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
if (message == "Move Down")<br />
{<br />
sitTargetHeight -= .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
} <br />
if(channel== heightchannel)<br />
{<br />
llListenRemove(cListener);<br />
setScaleDimensions((float) message); <br />
}<br />
}<br />
<br />
changed(integer change) <br />
{<br />
if(change & CHANGED_LINK) <br />
{<br />
avatar = llAvatarOnSitTarget();<br />
if(avatar != NULL_KEY)<br />
{<br />
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);<br />
}<br />
else<br />
{<br />
if (llGetPermissionsKey() != NULL_KEY)<br />
{ <br />
llStopAnimation(ANIMATION); <br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
avatar = NULL_KEY;<br />
}<br />
}<br />
}<br />
if(change & CHANGED_INVENTORY) { llResetScript(); }<br />
if(change & CHANGED_OWNER) { llResetScript(); }<br />
}<br />
<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION) {<br />
llStopAnimation("sit");<br />
llStartAnimation(ANIMATION);<br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(avatar, "Select an Option", heightButtons, menuchannel); <br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSay(0, "Menu selection time limit ( 30 seconds ) exceeded, please touch the scale again for a new menu");<br />
llListenRemove(mListener); <br />
llSetTimerEvent(0);<br />
}<br />
}<br />
</source ><br />
<br />
=== CheckProportions BVH file ===<br />
<br />
This is a very basic animation that stands the avatar upright with feet together and hands hanging down. <br />
It is a close enough match to the references included in the note card. <br />
You should be able to upload this file as an animation file and use it with most avatar models that the scale is appropriate for.<br />
The script expects the uploaded animation to be named "CheckProportions". Feel free to change it, but then you will also need to change the script.<br />
<br />
I recommend that you set the animation priority to 4 and set the animation to LOOP when uploaded. <br />
This will help insure it remains active while the avatar is on the scale.<br />
<br />
<source lang = "lsl"><br />
HIERARCHY<br />
ROOT hip<br />
{<br />
OFFSET 0.00 0.00 0.00 <br />
CHANNELS 6 Xposition Yposition Zposition Xrotation Zrotation Yrotation<br />
JOINT abdomen<br />
{<br />
OFFSET 0.000000 3.422050 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT chest<br />
{<br />
OFFSET 0.000000 8.486693 -0.684411<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT neck<br />
{<br />
OFFSET 0.000000 10.266162 -0.273764<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT head<br />
{<br />
OFFSET 0.000000 3.148285 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 3.148289 0.000000<br />
}<br />
}<br />
}<br />
JOINT lCollar<br />
{<br />
OFFSET 3.422053 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lShldr<br />
{<br />
OFFSET 3.285171 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT lForeArm<br />
{<br />
OFFSET 10.129278 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lHand<br />
{<br />
OFFSET 8.486692 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET 4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT rCollar<br />
{<br />
OFFSET -3.558935 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rShldr<br />
{<br />
OFFSET -3.148289 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT rForeArm<br />
{<br />
OFFSET -10.266159 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rHand<br />
{<br />
OFFSET -8.349810 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET -4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT lThigh<br />
{<br />
OFFSET 5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lShin<br />
{<br />
OFFSET -2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
JOINT rThigh<br />
{<br />
OFFSET -5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rShin<br />
{<br />
OFFSET 2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
}<br />
MOTION<br />
Frames: 1<br />
Frame Time: 0.5<br />
0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0<br />
<br />
<br />
<br />
</source ><br />
<br />
=== Information Notecard ===<br />
<br />
This is an optional add-on. It is not required, but I have included it to help explain the use to a novice user.<br />
I recommend that you at least READ through the note card before you attempt to use the scale for yourself.<br />
If you intend to re-distribute the scale, Please Please Please include this or something like it to minimize the support questions that may result.<br />
<br />
<source lang = "lsl"><br />
This is a BETA implementation of an avatar sizing scale<br />
It is designed to provide a simple scale with which you can measure the proportions of your avatar.<br />
<br />
There are 2 scale modes enabled. <br />
The default "Natural" mode is based on a 8 head scale. <br />
Realistic human avatars should be approximately 8 heads tall, and just under 2 heads wide.<br />
<br />
It also supports a "Heroic" mode based on a 9 head scale. <br />
Heroic avatars will have longer legs and should be wider at both the shoulders and hips. <br />
There are some studies that show this is considered more attractive in many western cultures.<br />
<br />
The scale has alternating Dark and Light "bars" in it to help you see the important locations..<br />
<br />
To use the scale, place it on a flat surface so that the base of the scale is close to the surface but not beneath it.<br />
Touch the scale and use the menu buttons to set the mode you desire (Default is Natural) , or select the [SET Height] button.<br />
Enter the desired avatar height ( in METERS) in the text box ( without hitting return, Use the submit button...). <br />
<br />
The scale should adjust its configuration or size and give you a message as it does so.<br />
<br />
DO NOT SIT ON THE SCALE UNTIL YOU HAVE SET THE PROPER MODE AND SIZE<br />
The scale will attempt to "guess" at, and set, a proper sit location. This will NOT work if you are already sitting..<br />
<br />
Once the scale has reset you can sit on the scale. There is an animation provided to pose you appropriately. <br />
You should be positioned in the middle of the base with the scale running up the middle of your avatar.<br />
Your feet should be close to the ground. <br />
<br />
Touch the scale again and use the {Move Up] or {Move Down] buttons to adjust your position until your feet are on the base.<br />
( Note) this BETA version of the scale has issues and you may see your avatar JUMP the first time you try to adjust.<br />
<br />
*********************************************<br />
<br />
What you SHOULD see if your "Natural" avatar is correctly proportioned<br />
<br />
The first (top) bar should go from the top of your head to the bottom of your chin.<br />
Your shoulders should be approximately the same width as the scale.<br />
Male nipples should be slightly above or at the bottom of the second bar.<br />
Female nipples should be slightly below the bottom of the second bar.<br />
Your "belly button" should be just under the third bar.<br />
Your crotch should be at the bottom of the fourth bar, 1/2 way down.<br />
Your wrists should also be in approximately the same place, 1/2 way down.<br />
Your knees should be above the 6th bar, at least 2 bars above the ground.<br />
Your Feet should be on the base.<br />
<br />
When using "Heroic" mode the following adjustments should be made..<br />
Both Male and Females nipples should appear just under the bottom of the second bar.<br />
Male crotch should be 1/4 - 1/3 of the way down from the top of the 5th bar.<br />
Knees should be under, instead of above, the bottom of the 6th bar.<br />
<br />
*******************************************<br />
Unfortunately, you will not be able to make avatar size adjustments while sitting on the scale.<br />
To adjust body size, you must stand, use [edit appearance] to make changes, and sit on the scale again to check.<br />
The scale is supposed to remember the adjustments you made, but you may have to adjust it again ( its BETA)<br />
********************************************<br />
<br />
As a rough guide, the following appearance parameters can be modified to achieve the best "fit"<br />
<br />
In the BODY section, use the HEIGHT slider.<br />
<br />
In the HEAD section, first use the HEAD SIZE slider, and then the HEAD STRETCH<br />
( you may want to play with the CHIN section sliders, but I recommend you come back to those later)<br />
<br />
In the TORSO section, Use SHOULDERS to set the shoulder width. <br />
(Muscular torsos will extend beyond the scale slightly)<br />
Use the ARM LENGTH slider to position your wrists<br />
Use the TORSO LENGTH slider to move your belly<br />
<br />
In the LEGS section, use LEG LENGTH to adjust the position of your knees and get your feet on the ground.<br />
Adjust HIP LENGTH to modify your belly button and crotch locations. <br />
<br />
<br />
************************************************<br />
<br />
Here are some web references to help you visualize the "landmarks" provided by the scale...<br />
<br />
http://www.idrawdigital.com/2009/01/drawing-tutorial-anatomy-and-proportion-1/<br />
<br />
http://www.3dhaze.com/tutorials/char_model/proportions.html<br />
<br />
http://www.pinterest.com/lillegerd/human-proportions/<br />
<br />
http://hpc.anatomy4sculptors.com/<br />
<br />
<br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/NPC_Scripts
User:Dz/NPC Scripts
2022-07-01T16:53:32Z
<p>Dz: /* Basic NPC AO (Animation Override) */</p>
<hr />
<div><br />
== NPC Utility Scripts ==<br />
<br />
These are useful utilites I have developed over time to help me use NPCs in OpenSimulator.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
Remember, you will need to enable NPC functions, and may need to set the severity level of allowed osNPC function calls for these scripts to work.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/NPC_Scripts]]<br />
<br />
=== NPC BotKiller ===<br />
Sometimes..things go wrong...and you have a region full of wandering NPC's. Drop this code in a prim and touch it... <br />
It can take a while to remove them all. <br />
<br />
PLEASE DON'T NUKE other peoples NPC's. <br />
<br />
<source lang = "lsl"><br />
<br />
// OpenSimian BotKiller<br />
// Kills all the NPC's in the region.. Please use with discretion.<br />
// Iterate over a list of avatar keys, using them as an arguments to osNpcRemove<br />
// Add a delay to the timer if sim performance starts to drag during logouts<br />
// Feel free to use/distribute/modify to suit your needs<br />
// Prepared for transfer to MOSES grid - D Osborn 5.3.2013<br />
<br />
integer who2kill = 0;<br />
integer howmany = 0;<br />
list avatars = [];<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSetText("waiting ", <1.0, 0.0, 0.0>, 1.0);<br />
}<br />
<br />
touch_end(integer total_number) // should not change state in touch_start events....<br />
{<br />
avatars = osGetAvatarList();<br />
howmany = llGetListLength(avatars)/3;<br />
state KillThem;<br />
}<br />
<br />
changed(integer change) // Reset on region restart<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
<br />
state KillThem<br />
<br />
{<br />
state_entry()<br />
{<br />
llSetText("Processing ", <1.0, 0.0, 0.0>, 1.0);<br />
llSetTimerEvent(3.0); // remove 1 every 3 seconds to minimize performance impact<br />
}<br />
<br />
timer()<br />
{<br />
osNpcRemove(llList2Key(avatars,who2kill*3)); <br />
llSetText("Removed so far : " + (string) (who2kill + 1), <1.0, 0.0, 0.0>, 1.0);<br />
<br />
who2kill++; <br />
if(who2kill>=howmany)<br />
state default; <br />
<br />
llSetTimerEvent(3.0/ llGetRegionTimeDilation()); // Use timedilation to add to the delay if lagging<br />
}<br />
<br />
<br />
touch_end(integer interrupt) // abort by touching the object while it is processing<br />
{<br />
llResetScript();<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
<br />
</source ><br />
<br />
=== NPC Router ===<br />
This script re-directs any NPC that collides with the object to a random destination selected from an internal list.<br />
<br />
Once the routers are placed, a text label display can be toggled by touching it. This makes it easy to collect locations<br />
<br />
Routers should be placed to facilitate collisions with the avatar capsules. <br />
<br />
The real trick of this router design is the rotate calculations. These prevents the NPCs from walking backwards when assigned new targets "behind" them.<br />
<br />
<source lang = "lsl"><br />
<br />
// OpenSimian NPC router<br />
// D Osborn MOSES version 2013May06<br />
<br />
// Assign random destination to a NPC that collides with volume detect object<br />
// Drop the script in a prim, resize and position the prim to facilitate collision with NPC av capsules<br />
<br />
// Modify the list of destination vectors to reflect your layout. <br />
// Router position text labels can be toggled by touching the prim. This also triggers the setpos()<br />
<br />
// This design imlements rotation calculations to prevent NPC avatars from walking backwards<br />
// Permissions and information about the rotation functions was here..<br />
// http://wiki.secondlife.com/wiki/User:Pedro_Oval/Calculate_rotation_for_pointing_in_a_direction<br />
// Due credit is here ... Written by Pedro Oval, 2011-01-11<br />
<br />
rotation PointAtHoriz2Rot(vector target)<br />
{<br />
return llRotBetween(<1., 0., 0.>, <target.x, target.y, 0.>);<br />
}<br />
<br />
rotation PointAt2Rot(vector target)<br />
{<br />
rotation r = PointAtHoriz2Rot(target);<br />
return llRotBetween(<1., 0., 0.>, target/r) * r;<br />
}<br />
// end of Pedros' rotation magic<br />
<br />
list DestinationList = [<70.0,70.0,30.0>,<97.0,100.0,37.0>,<70.0,190.0,33.0>];<br />
<br />
// Modify DestinationList.. Keep the list of vectors small to minimize processing<br />
// Be VERY careful about assigning destinations outside of the region.<br />
// NPC's will move in a direct line, design your "paths" to be as free of obstacles as possible<br />
<br />
integer numDests = 0;<br />
integer showPos = 0;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llVolumeDetect(TRUE); // Starts llVolumeDetect<br />
numDests = llGetListLength(DestinationList);<br />
<br />
}<br />
<br />
touch_start (integer numtouches)<br />
{<br />
while (numtouches)<br />
{<br />
if(showPos)<br />
{<br />
llSetText("", ZERO_VECTOR, 0.0);<br />
showPos=0;<br />
<br />
// Comment out the following 2 lines if you do NOT want your targets to "snap" to integer value locations<br />
vector newpos = llGetPos();<br />
llSetPos(<llFloor(newpos.x),llFloor(newpos.y), llFloor(newpos.z)>);<br />
}<br />
else<br />
{<br />
showPos = 1;<br />
llSetText((string) llGetPos(), ZERO_VECTOR, 1.0);<br />
llSay(0,(string) llGetPos());<br />
}<br />
numtouches--;<br />
}<br />
} <br />
<br />
collision_start(integer num)<br />
{<br />
integer i = 0;<br />
do<br />
{<br />
integer DestOffset = llFloor(llFrand(numDests));<br />
vector NewDest = llList2Vector(DestinationList,DestOffset) ;<br />
osNpcSetRot(llDetectedKey(i), PointAt2Rot(NewDest - llGetPos()));<br />
osNpcMoveToTarget(llDetectedKey(i), NewDest, OS_NPC_NO_FLY);<br />
}<br />
while(num > ++i);<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
</source ><br />
<br />
== NPC Creation Scripts ==<br />
<br />
While NPC's provide a very low overhead way to populate regions, there is still overhead involved. Logging in and out, generating note cards with serialized appearances, and trying to figure out if they are at a destination while moving all consume server resources. Some simple planning can remove/reduce the impact of these operations during "normal" conditions. <br />
<br />
Generate and check your NPC appearance WAY ahead of time. Sometimes you will find that you have to rebake your appearance AND remove and re-wear all your attachments before they will "clone" properly. <br />
<br />
Log your NPC's in and out during times when there are few in the region. Allow time between each login.. NPCs wearing scripted attachments might require 5 seconds between each login/logout to minimize the impact of starting/stopping scripts.<br />
<br />
Build error correction into your movement plans. If your NPC absolutely positively has to get to <X,Y,z>, You better have a alternative plan to sending that as a destination to a MOVETO function call once and hoping it arrives.... <br />
<br />
Animate instead of move. Take advantage of the fact that the siton function can sit an NPC on any prim in the region. Seated NPC's are easy to animate, and they aren't generating avatar capsule collisions.<br />
<br />
While the simple generator can be fun to show off, it is also a useful tool to verify that the NPC appearance is what you expect before you place it in your region. Once you start collecting the note cards of different appearances, you will begin to understand the logistics of introducing variety to your sim through NPCs. <br />
<br />
=== Basic Clone Generator ===<br />
<br />
This script generates a clone of the avatar that touches it. <br />
The NPC will sit on the generator prim and say hello. <br />
Touching the generator again kills the NPC.<br />
<br />
<source lang = "lsl"><br />
<br />
// drop this script in a small box. (0.25, 0.25, 0.15)<br />
// touch to create a NPC clone of your current appearance.<br />
// NPC will sit on the prim, then greet you. <br />
// Touch again to remove the NPC<br />
<br />
// This code is adapted from the wiki with the following modifications<br />
// State entry for llSitTarget added<br />
// touch start replaced by touch end... lsl wiki sez " state changes in touch start may trigger extra events<br />
// Used overloaded version of NPCCreate to illustrate use of OWNED and SENSE_AS_AGENT parameters<br />
// added restart on_rez to default and region reboot events to both states<br />
// Changed NPC Moveto to Sit on for initial NPC target. I find this useful for examining the NPC generated.<br />
// It also eliminates the issues of NPC's "never arriving" when moveto or movetotarget calls are used.<br />
<br />
key npc;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSitTarget(<0.30, 0.0, 0.35>, ZERO_ROTATION);<br />
}<br />
<br />
touch_end(integer number)<br />
{<br />
vector npcPos = llGetPos() + <1,0,0>;<br />
<br />
osAgentSaveAppearance(llDetectedKey(0), "appearance");<br />
<br />
npc = osNpcCreate("Ima", "Clone", npcPos, "appearance", OS_NPC_NOT_OWNED | OS_NPC_SENSE_AS_AGENT );<br />
<br />
state hasNPC;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
llResetScript(); <br />
} <br />
<br />
}<br />
<br />
state hasNPC<br />
{<br />
state_entry()<br />
{<br />
osNpcSit(npc, llGetKey(), OS_NPC_SIT_NOW);<br />
<br />
osNpcSay(npc, "Hi there! My name is " + llKey2Name(npc));<br />
}<br />
<br />
touch_end(integer number)<br />
{<br />
osNpcSay(npc, "Goodbye!");<br />
<br />
osNpcRemove(npc);<br />
<br />
npc = NULL_KEY;<br />
<br />
state default;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
<br />
}<br />
</source><br />
<br />
=== Advanced Clone Generator ===<br />
<br />
This script supports the deployment of large numbers of NPC bots. It maintains an internal library of appearance Notecards.<br />
Notecards are generated by touching the object and selecting the [Clone Me] button. The user will be required to provide a unique name to store an appearance.<br />
<br />
Selecting the [Choose One] menu option will present the user with a menu to select the appearance notecard used to generate the NPC's. <br />
<br />
Select [Create Bots] to generate the NPC's. They are created slowly to minimize impact on sim performance. <br />
Touching the generator before all NPC's are generated will stop the process.<br />
<br />
<source lang = "lsl"><br />
</source><br />
<br />
== NPC Animation Scripts ==<br />
<br />
My experience with NPC animation is a combination of a very simple animation override with in-word scripted objects designed to detect collisions, proximity, or seated avatars can provide exceptional results. Limiting the AO tasks to movement animation types (Walk/Run/Fly) reduces the complexity and size of the script. <br />
<br />
Using the inworld NPC Routers as targets, we can set up a network of paths between the NPC generators and the region destinations. For instance, in a city simulation, we could place a generator in a subway station, with routers at the intersections on the streets, to drive traffic around the city buildings. Routers at the building entrance can dirent NPC's inside to seating locations. Using scripted poseballs to provide places for the NPC's to interact, also allows non-NPC participation. <br />
<br />
<br />
=== Basic NPC AO (Animation Override) ===<br />
The intent is to provide an efficient way to give NPC's unique combinations of movement ONLY animations. These are simple scripts, easy to duplicate and modify the animations to use. Attach the AO to your HUD before you clone your appearance and generate the NPC. Touch the HUD to toggle it off and back on to make sure it is working. While designed for use with NPC's, these AO's will work just as well with other bot types or regular avatars.<br />
<br />
This script monitors change events for a CHANGED_ANIMATION flag. This is vastly more efficient than parsing the list of current animations 3 or 4 times a second to see if you are still walking/standing/flying. There are other reasons NOT to try and use AOs ported from SL on NPC's. Most will fail to work at all, and some will actually animate the avatar that was cloned instead of the NPC.<br />
<br />
An AO script is not much use with the animations to go with it. There are a number of good AO animation sets available in some of the public domain OAR and IAR files.<br />
I had the pleasure once to meet the creator of the animations contained in the Linda Kellie OAR files. The following scripts are adapted to those animation names so that you can drop them, and the animations (after you DL them) into a single prim and attach it to your HUD. <br />
<br />
Rememeber, You must place the HUD on the ground to add animations, and you should take it back into inventory before wearing it to make sure the contents update properly.<br />
<br />
<br />
<br />
<source lang = "lsl"><br />
// A basic OpenSimulator Walk and Stand animation override<br />
// All Modifications are Copyright 2010 by D Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
// This work uses content from the Second Life® Wiki article llGetAnimation. (http://wiki.secondlife.com/wiki/LlGetAnimation)<br />
// Copyright © 2007-2009 Linden Research, Inc. Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
<br />
// This AO is optimized for OpenSimulator and DOES NOT POLL the animation list multiple times a second<br />
// It relies instead on the CHANGED ANIMATION event. The timer is ONLY active when your avatar is swapping between stands.<br />
<br />
// It is NOT optimized code. Yes it could be smaller and probably faster. This is simple, and is intended to provide a working object<br />
// instead of a lasting tribute to anyones programming prowess. Feel free to Optimize and re-distribute to your hearts content.<br />
<br />
// To use: Place this script in an object that will be attached to your avatar<br />
// Place the animations in the same prim<br />
// Change the CUSTOMIZATION section to reflect the names of YOUR animations.<br />
// Attach to your avatar or a HUD position<br />
<br />
// To Reset Detach and re-attach the object or Edit the object and Reset the script<br />
<br />
// All of the overrides available via the traditional ZHAO can be controlled via this script. <br />
// The following Animation Types can be used by expanding the StartAnimation function to include the animation type<br />
//<br />
// [ Standing ]<br />
// [ Walking ]<br />
// [ Sitting ]<br />
// [ Sitting On Ground ]<br />
// [ Crouching ]<br />
// [ Crouch Walking ]<br />
// [ Landing ]<br />
// [ Standing Up ]<br />
// [ Falling ]<br />
// [ Flying Down ]<br />
// [ Flying Up ]<br />
// [ Flying ]<br />
// [ Flying Slow ]<br />
// [ Hovering ]<br />
// [ Jumping ]<br />
// [ Pre Jumping ]<br />
// [ Running ]<br />
// [ Turning Right ]<br />
// [ Turning Left ]<br />
// [ Floating ]<br />
// [ Swimming Forward ]<br />
// [ Swimming Up ]<br />
// [ Swimming Down ]<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
// Change the folling lines to reflect the animation names you want to use<br />
<br />
list StandNames = ["ao-sweetness-stand1", "ao-sweetness-stand2", "ao-sweetness-stand3", "ao-sweetness-stand4", "ao-sweetness-stand5"];<br />
<br />
integer StandTime = 12; // change this number to the number of seconds between stands<br />
<br />
string WalkAnimation = "sweetness walk"; // Change this string to the name of the Walk animation you want to use<br />
<br />
string RunAnimation = "AO-Run-Female"; // Change this string to the name of the Run animation you want to use<br />
<br />
string SitAnimation = "sweetness-sit-1"; // Change this string to the name of the sit animation you want to use <br />
// For NPC AO, it is best to leave this blank. Expect SIT objects to provide the proper animation<br />
<br />
string CrouchAnimation = "AO-Crouch-Female"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string FlyAnimation = "sweetness-fly-1"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "sweetness-hover4"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softland1-Female"; // Change this string to the name of the softland animation you want to use<br />
<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Female"; // Change this string to the name of the Jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
// ***** Below there be dragons <wink> not really! ******* <br />
<br />
// You should not need to change anything below these lines<br />
// You are welcome to. If you break it, you get to keep all the parts!<br />
// <br />
<br />
key Owner; // the wearer's key<br />
<br />
string LastAnimation = ""; // last llGetAnimation value seen<br />
<br />
string LastAnimName = "";<br />
<br />
string newAnimation = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
integer PowerStatus = 1;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
// User functions<br />
<br />
Initialize(key id) <br />
{<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn<br />
{ <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);<br />
Owner = id;<br />
StandCount = (float) llGetListLength(StandNames);<br />
}<br />
}<br />
<br />
OnOff()<br />
{<br />
vector color;<br />
<br />
if (PowerStatus == 0) <br />
{<br />
PowerStatus = 1;<br />
newAnimation = llGetAnimation(Owner);<br />
StartAnimation();<br />
llOwnerSay("Over-ride active");<br />
color = onColor;<br />
}<br />
else<br />
{<br />
PowerStatus = 0;<br />
llStopAnimation(LastAnimName);<br />
llOwnerSay("Over-ride off");<br />
color = offColor;<br />
}<br />
<br />
llSetColor(color/255.0, ALL_SIDES);<br />
}<br />
<br />
StartAnimation()<br />
{<br />
if (LastAnimation != newAnimation) <br />
{ <br />
if (newAnimation == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimation != "")<br />
{ <br />
LastAnimName = WalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (newAnimation == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (newAnimation == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
if(StandCount > 1.0) <br />
llSetTimerEvent(StandTime);<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (newAnimation == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "")<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0); <br />
} <br />
<br />
if (newAnimation == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (newAnimation == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (newAnimation == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (newAnimation == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (newAnimation == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
}<br />
} <br />
<br />
<br />
// Event handlers<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
// script was reset while already attached<br />
if (llGetAttached() != 0) {<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
attach(key id) {<br />
Initialize(id);<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) {<br />
llOwnerSay("Over-ride active"); <br />
}<br />
}<br />
<br />
touch_start(integer whodunit)<br />
{<br />
OnOff();<br />
}<br />
<br />
timer()<br />
{<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
} <br />
<br />
changed (integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{<br />
<br />
newAnimation = llGetAnimation(Owner);<br />
<br />
StartAnimation();<br />
<br />
LastAnimation = newAnimation; // so we can check for changes<br />
<br />
// llOwnerSay("started " + newAnimation); // uncomment this to see the event types you can respond to <br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which animations are being used<br />
<br />
<br />
}<br />
}<br />
}<br />
</source><br />
<br />
=== Advanced NPC AO ===<br />
<br />
<source lang = "lsl"><br />
</source></div>
Dz
http://opensimulator.org/wiki/User:Dz/NPC_Scripts
User:Dz/NPC Scripts
2022-07-01T16:52:38Z
<p>Dz: /* NPC Router */</p>
<hr />
<div><br />
== NPC Utility Scripts ==<br />
<br />
These are useful utilites I have developed over time to help me use NPCs in OpenSimulator.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
Remember, you will need to enable NPC functions, and may need to set the severity level of allowed osNPC function calls for these scripts to work.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/NPC_Scripts]]<br />
<br />
=== NPC BotKiller ===<br />
Sometimes..things go wrong...and you have a region full of wandering NPC's. Drop this code in a prim and touch it... <br />
It can take a while to remove them all. <br />
<br />
PLEASE DON'T NUKE other peoples NPC's. <br />
<br />
<source lang = "lsl"><br />
<br />
// OpenSimian BotKiller<br />
// Kills all the NPC's in the region.. Please use with discretion.<br />
// Iterate over a list of avatar keys, using them as an arguments to osNpcRemove<br />
// Add a delay to the timer if sim performance starts to drag during logouts<br />
// Feel free to use/distribute/modify to suit your needs<br />
// Prepared for transfer to MOSES grid - D Osborn 5.3.2013<br />
<br />
integer who2kill = 0;<br />
integer howmany = 0;<br />
list avatars = [];<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSetText("waiting ", <1.0, 0.0, 0.0>, 1.0);<br />
}<br />
<br />
touch_end(integer total_number) // should not change state in touch_start events....<br />
{<br />
avatars = osGetAvatarList();<br />
howmany = llGetListLength(avatars)/3;<br />
state KillThem;<br />
}<br />
<br />
changed(integer change) // Reset on region restart<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
<br />
state KillThem<br />
<br />
{<br />
state_entry()<br />
{<br />
llSetText("Processing ", <1.0, 0.0, 0.0>, 1.0);<br />
llSetTimerEvent(3.0); // remove 1 every 3 seconds to minimize performance impact<br />
}<br />
<br />
timer()<br />
{<br />
osNpcRemove(llList2Key(avatars,who2kill*3)); <br />
llSetText("Removed so far : " + (string) (who2kill + 1), <1.0, 0.0, 0.0>, 1.0);<br />
<br />
who2kill++; <br />
if(who2kill>=howmany)<br />
state default; <br />
<br />
llSetTimerEvent(3.0/ llGetRegionTimeDilation()); // Use timedilation to add to the delay if lagging<br />
}<br />
<br />
<br />
touch_end(integer interrupt) // abort by touching the object while it is processing<br />
{<br />
llResetScript();<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
<br />
</source ><br />
<br />
=== NPC Router ===<br />
This script re-directs any NPC that collides with the object to a random destination selected from an internal list.<br />
<br />
Once the routers are placed, a text label display can be toggled by touching it. This makes it easy to collect locations<br />
<br />
Routers should be placed to facilitate collisions with the avatar capsules. <br />
<br />
The real trick of this router design is the rotate calculations. These prevents the NPCs from walking backwards when assigned new targets "behind" them.<br />
<br />
<source lang = "lsl"><br />
<br />
// OpenSimian NPC router<br />
// D Osborn MOSES version 2013May06<br />
<br />
// Assign random destination to a NPC that collides with volume detect object<br />
// Drop the script in a prim, resize and position the prim to facilitate collision with NPC av capsules<br />
<br />
// Modify the list of destination vectors to reflect your layout. <br />
// Router position text labels can be toggled by touching the prim. This also triggers the setpos()<br />
<br />
// This design imlements rotation calculations to prevent NPC avatars from walking backwards<br />
// Permissions and information about the rotation functions was here..<br />
// http://wiki.secondlife.com/wiki/User:Pedro_Oval/Calculate_rotation_for_pointing_in_a_direction<br />
// Due credit is here ... Written by Pedro Oval, 2011-01-11<br />
<br />
rotation PointAtHoriz2Rot(vector target)<br />
{<br />
return llRotBetween(<1., 0., 0.>, <target.x, target.y, 0.>);<br />
}<br />
<br />
rotation PointAt2Rot(vector target)<br />
{<br />
rotation r = PointAtHoriz2Rot(target);<br />
return llRotBetween(<1., 0., 0.>, target/r) * r;<br />
}<br />
// end of Pedros' rotation magic<br />
<br />
list DestinationList = [<70.0,70.0,30.0>,<97.0,100.0,37.0>,<70.0,190.0,33.0>];<br />
<br />
// Modify DestinationList.. Keep the list of vectors small to minimize processing<br />
// Be VERY careful about assigning destinations outside of the region.<br />
// NPC's will move in a direct line, design your "paths" to be as free of obstacles as possible<br />
<br />
integer numDests = 0;<br />
integer showPos = 0;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llVolumeDetect(TRUE); // Starts llVolumeDetect<br />
numDests = llGetListLength(DestinationList);<br />
<br />
}<br />
<br />
touch_start (integer numtouches)<br />
{<br />
while (numtouches)<br />
{<br />
if(showPos)<br />
{<br />
llSetText("", ZERO_VECTOR, 0.0);<br />
showPos=0;<br />
<br />
// Comment out the following 2 lines if you do NOT want your targets to "snap" to integer value locations<br />
vector newpos = llGetPos();<br />
llSetPos(<llFloor(newpos.x),llFloor(newpos.y), llFloor(newpos.z)>);<br />
}<br />
else<br />
{<br />
showPos = 1;<br />
llSetText((string) llGetPos(), ZERO_VECTOR, 1.0);<br />
llSay(0,(string) llGetPos());<br />
}<br />
numtouches--;<br />
}<br />
} <br />
<br />
collision_start(integer num)<br />
{<br />
integer i = 0;<br />
do<br />
{<br />
integer DestOffset = llFloor(llFrand(numDests));<br />
vector NewDest = llList2Vector(DestinationList,DestOffset) ;<br />
osNpcSetRot(llDetectedKey(i), PointAt2Rot(NewDest - llGetPos()));<br />
osNpcMoveToTarget(llDetectedKey(i), NewDest, OS_NPC_NO_FLY);<br />
}<br />
while(num > ++i);<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
}<br />
</source ><br />
<br />
== NPC Creation Scripts ==<br />
<br />
While NPC's provide a very low overhead way to populate regions, there is still overhead involved. Logging in and out, generating note cards with serialized appearances, and trying to figure out if they are at a destination while moving all consume server resources. Some simple planning can remove/reduce the impact of these operations during "normal" conditions. <br />
<br />
Generate and check your NPC appearance WAY ahead of time. Sometimes you will find that you have to rebake your appearance AND remove and re-wear all your attachments before they will "clone" properly. <br />
<br />
Log your NPC's in and out during times when there are few in the region. Allow time between each login.. NPCs wearing scripted attachments might require 5 seconds between each login/logout to minimize the impact of starting/stopping scripts.<br />
<br />
Build error correction into your movement plans. If your NPC absolutely positively has to get to <X,Y,z>, You better have a alternative plan to sending that as a destination to a MOVETO function call once and hoping it arrives.... <br />
<br />
Animate instead of move. Take advantage of the fact that the siton function can sit an NPC on any prim in the region. Seated NPC's are easy to animate, and they aren't generating avatar capsule collisions.<br />
<br />
While the simple generator can be fun to show off, it is also a useful tool to verify that the NPC appearance is what you expect before you place it in your region. Once you start collecting the note cards of different appearances, you will begin to understand the logistics of introducing variety to your sim through NPCs. <br />
<br />
=== Basic Clone Generator ===<br />
<br />
This script generates a clone of the avatar that touches it. <br />
The NPC will sit on the generator prim and say hello. <br />
Touching the generator again kills the NPC.<br />
<br />
<source lang = "lsl"><br />
<br />
// drop this script in a small box. (0.25, 0.25, 0.15)<br />
// touch to create a NPC clone of your current appearance.<br />
// NPC will sit on the prim, then greet you. <br />
// Touch again to remove the NPC<br />
<br />
// This code is adapted from the wiki with the following modifications<br />
// State entry for llSitTarget added<br />
// touch start replaced by touch end... lsl wiki sez " state changes in touch start may trigger extra events<br />
// Used overloaded version of NPCCreate to illustrate use of OWNED and SENSE_AS_AGENT parameters<br />
// added restart on_rez to default and region reboot events to both states<br />
// Changed NPC Moveto to Sit on for initial NPC target. I find this useful for examining the NPC generated.<br />
// It also eliminates the issues of NPC's "never arriving" when moveto or movetotarget calls are used.<br />
<br />
key npc;<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSitTarget(<0.30, 0.0, 0.35>, ZERO_ROTATION);<br />
}<br />
<br />
touch_end(integer number)<br />
{<br />
vector npcPos = llGetPos() + <1,0,0>;<br />
<br />
osAgentSaveAppearance(llDetectedKey(0), "appearance");<br />
<br />
npc = osNpcCreate("Ima", "Clone", npcPos, "appearance", OS_NPC_NOT_OWNED | OS_NPC_SENSE_AS_AGENT );<br />
<br />
state hasNPC;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
llResetScript(); <br />
} <br />
<br />
}<br />
<br />
state hasNPC<br />
{<br />
state_entry()<br />
{<br />
osNpcSit(npc, llGetKey(), OS_NPC_SIT_NOW);<br />
<br />
osNpcSay(npc, "Hi there! My name is " + llKey2Name(npc));<br />
}<br />
<br />
touch_end(integer number)<br />
{<br />
osNpcSay(npc, "Goodbye!");<br />
<br />
osNpcRemove(npc);<br />
<br />
npc = NULL_KEY;<br />
<br />
state default;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
}<br />
}<br />
<br />
}<br />
</source><br />
<br />
=== Advanced Clone Generator ===<br />
<br />
This script supports the deployment of large numbers of NPC bots. It maintains an internal library of appearance Notecards.<br />
Notecards are generated by touching the object and selecting the [Clone Me] button. The user will be required to provide a unique name to store an appearance.<br />
<br />
Selecting the [Choose One] menu option will present the user with a menu to select the appearance notecard used to generate the NPC's. <br />
<br />
Select [Create Bots] to generate the NPC's. They are created slowly to minimize impact on sim performance. <br />
Touching the generator before all NPC's are generated will stop the process.<br />
<br />
<source lang = "lsl"><br />
</source><br />
<br />
== NPC Animation Scripts ==<br />
<br />
My experience with NPC animation is a combination of a very simple animation override with in-word scripted objects designed to detect collisions, proximity, or seated avatars can provide exceptional results. Limiting the AO tasks to movement animation types (Walk/Run/Fly) reduces the complexity and size of the script. <br />
<br />
Using the inworld NPC Routers as targets, we can set up a network of paths between the NPC generators and the region destinations. For instance, in a city simulation, we could place a generator in a subway station, with routers at the intersections on the streets, to drive traffic around the city buildings. Routers at the building entrance can dirent NPC's inside to seating locations. Using scripted poseballs to provide places for the NPC's to interact, also allows non-NPC participation. <br />
<br />
<br />
=== Basic NPC AO (Animation Override) ===<br />
The intent is to provide an efficient way to give NPC's unique combinations of movement ONLY animations. These are simple scripts, easy to duplicate and modify the animations to use. Attach the AO to your HUD before you clone your appearance and generate the NPC. Touch the HUD to toggle it off and back on to make sure it is working. While designed for use with NPC's, these AO's will work just as well with other bot types or regular avatars.<br />
<br />
This script monitors change events for a CHANGED_ANIMATION flag. This is vastly more efficient than parsing the list of current animations 3 or 4 times a second to see if you are still walking/standing/flying. There are other reasons NOT to try and use AOs ported from SL on NPC's. Most will fail to work at all, and some will actually animate the avatar that was cloned instead of the NPC.<br />
<br />
An AO script is not much use with the animations to go with it. There are a number of good AO animation sets available in some of the public domain OAR and IAR files.<br />
I had the pleasure once to meet the creator of the animations contained in the Linda Kellie OAR files. The following scripts are adapted to those animation names so that you can drop them, and the animations (after you DL them) into a single prim and attach it to your HUD. <br />
<br />
Rememeber, You must place the HUD on the ground to add animations, and you should take it back into inventory before wearing it to make sure the contents update properly.<br />
<br />
<br />
<br />
<source lang = "lsl"><br />
// A basic OpenSimulator Walk and Stand animation override<br />
// All Modifications are Copyright 2010 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
// This work uses content from the Second Life® Wiki article llGetAnimation. (http://wiki.secondlife.com/wiki/LlGetAnimation)<br />
// Copyright © 2007-2009 Linden Research, Inc. Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
<br />
// This AO is optimized for OpenSimulator and DOES NOT POLL the animation list multiple times a second<br />
// It relies instead on the CHANGED ANIMATION event. The timer is ONLY active when your avatar is swapping between stands.<br />
<br />
// It is NOT optimized code. Yes it could be smaller and probably faster. This is simple, and is intended to provide a working object<br />
// instead of a lasting tribute to anyones programming prowess. Feel free to Optimize and re-distribute to your hearts content.<br />
<br />
// To use: Place this script in an object that will be attached to your avatar<br />
// Place the animations in the same prim<br />
// Change the CUSTOMIZATION section to reflect the names of YOUR animations.<br />
// Attach to your avatar or a HUD position<br />
<br />
// To Reset Detach and re-attach the object or Edit the object and Reset the script<br />
<br />
// All of the overrides available via the traditional ZHAO can be controlled via this script. <br />
// The following Animation Types can be used by expanding the StartAnimation function to include the animation type<br />
//<br />
// [ Standing ]<br />
// [ Walking ]<br />
// [ Sitting ]<br />
// [ Sitting On Ground ]<br />
// [ Crouching ]<br />
// [ Crouch Walking ]<br />
// [ Landing ]<br />
// [ Standing Up ]<br />
// [ Falling ]<br />
// [ Flying Down ]<br />
// [ Flying Up ]<br />
// [ Flying ]<br />
// [ Flying Slow ]<br />
// [ Hovering ]<br />
// [ Jumping ]<br />
// [ Pre Jumping ]<br />
// [ Running ]<br />
// [ Turning Right ]<br />
// [ Turning Left ]<br />
// [ Floating ]<br />
// [ Swimming Forward ]<br />
// [ Swimming Up ]<br />
// [ Swimming Down ]<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
// Change the folling lines to reflect the animation names you want to use<br />
<br />
list StandNames = ["ao-sweetness-stand1", "ao-sweetness-stand2", "ao-sweetness-stand3", "ao-sweetness-stand4", "ao-sweetness-stand5"];<br />
<br />
integer StandTime = 12; // change this number to the number of seconds between stands<br />
<br />
string WalkAnimation = "sweetness walk"; // Change this string to the name of the Walk animation you want to use<br />
<br />
string RunAnimation = "AO-Run-Female"; // Change this string to the name of the Run animation you want to use<br />
<br />
string SitAnimation = "sweetness-sit-1"; // Change this string to the name of the sit animation you want to use <br />
// For NPC AO, it is best to leave this blank. Expect SIT objects to provide the proper animation<br />
<br />
string CrouchAnimation = "AO-Crouch-Female"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string FlyAnimation = "sweetness-fly-1"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "sweetness-hover4"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softland1-Female"; // Change this string to the name of the softland animation you want to use<br />
<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Female"; // Change this string to the name of the Jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
// ***** Below there be dragons <wink> not really! ******* <br />
<br />
// You should not need to change anything below these lines<br />
// You are welcome to. If you break it, you get to keep all the parts!<br />
// <br />
<br />
key Owner; // the wearer's key<br />
<br />
string LastAnimation = ""; // last llGetAnimation value seen<br />
<br />
string LastAnimName = "";<br />
<br />
string newAnimation = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
integer PowerStatus = 1;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
// User functions<br />
<br />
Initialize(key id) <br />
{<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn<br />
{ <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);<br />
Owner = id;<br />
StandCount = (float) llGetListLength(StandNames);<br />
}<br />
}<br />
<br />
OnOff()<br />
{<br />
vector color;<br />
<br />
if (PowerStatus == 0) <br />
{<br />
PowerStatus = 1;<br />
newAnimation = llGetAnimation(Owner);<br />
StartAnimation();<br />
llOwnerSay("Over-ride active");<br />
color = onColor;<br />
}<br />
else<br />
{<br />
PowerStatus = 0;<br />
llStopAnimation(LastAnimName);<br />
llOwnerSay("Over-ride off");<br />
color = offColor;<br />
}<br />
<br />
llSetColor(color/255.0, ALL_SIDES);<br />
}<br />
<br />
StartAnimation()<br />
{<br />
if (LastAnimation != newAnimation) <br />
{ <br />
if (newAnimation == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimation != "")<br />
{ <br />
LastAnimName = WalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (newAnimation == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (newAnimation == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
if(StandCount > 1.0) <br />
llSetTimerEvent(StandTime);<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (newAnimation == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "")<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0); <br />
} <br />
<br />
if (newAnimation == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (newAnimation == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (newAnimation == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (newAnimation == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (newAnimation == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
}<br />
} <br />
<br />
<br />
// Event handlers<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
// script was reset while already attached<br />
if (llGetAttached() != 0) {<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
attach(key id) {<br />
Initialize(id);<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) {<br />
llOwnerSay("Over-ride active"); <br />
}<br />
}<br />
<br />
touch_start(integer whodunit)<br />
{<br />
OnOff();<br />
}<br />
<br />
timer()<br />
{<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
} <br />
<br />
changed (integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{<br />
<br />
newAnimation = llGetAnimation(Owner);<br />
<br />
StartAnimation();<br />
<br />
LastAnimation = newAnimation; // so we can check for changes<br />
<br />
// llOwnerSay("started " + newAnimation); // uncomment this to see the event types you can respond to <br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which animations are being used<br />
<br />
<br />
}<br />
}<br />
}<br />
</source><br />
<br />
=== Advanced NPC AO ===<br />
<br />
<source lang = "lsl"><br />
</source></div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2022-07-01T16:51:41Z
<p>Dz: /* Simple Click on/off Variable speed AO demo */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This is an example of an AO script designed for use in OpenSimulator. These instructions describe how to make your own AO from scratch.<br />
<br />
For this example, I use animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. <br />
<br />
The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Step 1. Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Step 2. Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Step 3. Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by D Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Step 5. Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Step 6. Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Step 7. Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Step 8. Attach it to one of your HUD positions ... <br />
<br />
Step 9. Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour versus 6000 events using the modified script...<br />
<br />
In OpenSimulator, the design can be much more efficient. The developers have added a CHANGED_ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the script with the one you saved in step 2 above.</div>
Dz
http://opensimulator.org/wiki/User:Dz/SimStats
User:Dz/SimStats
2015-09-02T02:13:41Z
<p>Dz: /* MOAP Region Statistics Display */</p>
<hr />
<div>== MOAP Region Statistics Display ==<br />
<br />
This script proved useful during sim performance tests on the MOSES grid. <br />
<br />
It uses a call to osGetRegionStats to build a small HTML page that it feeds to a MOAP Display. The HTML is designed to be displayed at a resolution of 1024x2048. Size your display board appropriately to avoid distorted text<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/SimStats]]<br />
<br />
<br />
=== The script ===<br />
<br />
The script currently includes a hard coded TextureUUID to load as the default image. You will need to replace that UUID with one local to your grid and appropriate to your purpose. <br />
<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// OpenSim Region Statistics display<br />
<br />
// Doug Osborn MOSES grid 9/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
<br />
integer displayface = 2;<br />
<br />
string Region = "";<br />
string Parcel = "";<br />
string TimeDate = "";<br />
string TextureUUID = "e0d6e6b8-0a40-3eab-08c2-97711a14d439";<br />
<br />
string FPS = "FPS - Sim: ";<br />
string PHYS = "Physics: ";<br />
string DIA= "Time Dilation: ";<br />
string AVIS= "Root Agents: ";<br />
string SCRPT = "Active Scripts: ";<br />
<br />
default<br />
{<br />
state_entry()<br />
{ <br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
<br />
Region = llGetRegionName(); <br />
Parcel = llList2String(details ,0);<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, TextureUUID, <1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]); <br />
<br />
llSetTimerEvent( 5.0 ); <br />
}<br />
<br />
timer()<br />
{<br />
list Stats = osGetRegionStats();<br />
<br />
string dFPS = FPS + (string) llList2Float( Stats, STATS_SIM_FPS ) ;<br />
string dPHYS = PHYS + (string) llList2Float( Stats, STATS_PHYSICS_FPS );<br />
string dDIA= DIA + (string) llList2Float( Stats, STATS_TIME_DILATION );<br />
string dAVIS= AVIS + (string) llList2Integer( Stats, STATS_ROOT_AGENTS );<br />
string dSCRPT = SCRPT + (string) llList2Integer( Stats, STATS_ACTIVE_SCRIPTS ); <br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='yellow'><i><h1>" + Region + " @ " + Parcel + "</h1><h3>( " + llGetTimestamp() + " )</h3></i><p><h2>"+ dFPS + " - " +dPHYS + "<p>" + dDIA + "<p>" + dAVIS + " - " + dSCRPT + "</h2></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
}<br />
}<br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/SimStats
User:Dz/SimStats
2015-09-02T02:10:14Z
<p>Dz: Created page with "== MOAP Region Statistics Display == This script proved useful during sim performance tests on the MOSES grid. It uses a call to osGetRegionStats to build a small HTML pag..."</p>
<hr />
<div>== MOAP Region Statistics Display ==<br />
<br />
This script proved useful during sim performance tests on the MOSES grid. <br />
<br />
It uses a call to osGetRegionStats to build a small HTML page that it feeds to a MOAP Display.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/SimStats]]<br />
<br />
<br />
=== The script ===<br />
<br />
The script currently includes a hard coded TextureUUID to load as the default image. You will need to replace that UUID with one local to your grid and appropriate to your purpose. <br />
<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// OpenSim Region Statistics display<br />
<br />
// Doug Osborn MOSES grid 9/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
<br />
integer displayface = 2;<br />
<br />
string Region = "";<br />
string Parcel = "";<br />
string TimeDate = "";<br />
string TextureUUID = "e0d6e6b8-0a40-3eab-08c2-97711a14d439";<br />
<br />
string FPS = "FPS - Sim: ";<br />
string PHYS = "Physics: ";<br />
string DIA= "Time Dilation: ";<br />
string AVIS= "Root Agents: ";<br />
string SCRPT = "Active Scripts: ";<br />
<br />
default<br />
{<br />
state_entry()<br />
{ <br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
<br />
Region = llGetRegionName(); <br />
Parcel = llList2String(details ,0);<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, TextureUUID, <1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]); <br />
<br />
llSetTimerEvent( 5.0 ); <br />
}<br />
<br />
timer()<br />
{<br />
list Stats = osGetRegionStats();<br />
<br />
string dFPS = FPS + (string) llList2Float( Stats, STATS_SIM_FPS ) ;<br />
string dPHYS = PHYS + (string) llList2Float( Stats, STATS_PHYSICS_FPS );<br />
string dDIA= DIA + (string) llList2Float( Stats, STATS_TIME_DILATION );<br />
string dAVIS= AVIS + (string) llList2Integer( Stats, STATS_ROOT_AGENTS );<br />
string dSCRPT = SCRPT + (string) llList2Integer( Stats, STATS_ACTIVE_SCRIPTS ); <br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='yellow'><i><h1>" + Region + " @ " + Parcel + "</h1><h3>( " + llGetTimestamp() + " )</h3></i><p><h2>"+ dFPS + " - " +dPHYS + "<p>" + dDIA + "<p>" + dAVIS + " - " + dSCRPT + "</h2></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
}<br />
}<br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz
User:Dz
2015-09-02T01:59:18Z
<p>Dz: added Sim Stats board</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Welcome to the OpenSimulator Space of dz ==<br />
<br />
I am generally involved in running OpenSim instances for fun, but I have been induced to try it for profit and the pursuit of scholarly credits.<br />
<br />
I am an incessant lurker...It took me 2 years to add these 3 lines to my profile here.<br />
<br />
I monitor the following OpenSimulator mailing-lists Opensim-Users, OpenSim-devs, libomv-dev. <br />
I can also be found lurking in the SL opensim group chat.<br />
<br />
I have been administering Linux based OpenSim servers since release 6.1, mostly on Ubuntu.<br />
I have active avatars on OSGrid, ScienceSim, Inworldz, and that "SL" place.<br />
<br />
<br />
<br />
----<br />
<br />
== NPC Utilities ==<br />
<br />
[[User:Dz/NPC Scripts]] Has the Latest NPC utilities<br />
<br />
<br />
== Animation overrides ==<br />
<br />
[[User:Dz/AO]] Has the Latest Animation Overrides designed for OpenSimulator<br />
<br />
<br />
== Avatar Proportion Scale ==<br />
<br />
[[User:Dz/Avatar Scale]] A simple scale to help you create more realistic avatar shapes<br />
<br />
<br />
== Media On a Prim Sim Statistics Board ==<br />
<br />
[[User:Dz/SimStats]] A MOAP HTML hack to display Sim Statistics.<br />
<br />
<br />
== Media On a Prim Shoutcast Board ==<br />
<br />
[[User:Dz/ShoutCast]] A note card controlled ShoutCast board using MOAP to display stream info.</div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T23:50:27Z
<p>Dz: /* Configuration Notecard */</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
<br />
Configurable Access by owner, group, or individuals (DJs)<br />
<br />
Default Texture override.<br />
<br />
10 user defined GENRE Categories.<br />
<br />
Unlimited URLs per GENRE.<br />
<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
I recommend at least 2 prims to construct the board.<br />
<br />
First, a Display prim to hold the script and display the info.<br />
<br />
I like to size it 1H and 2W so 256x512 & 512x1024 textures display without distortion.<br />
So, rez a box and resize it X: 0.05 meter Y: 2 meter and Z: 1 meter.<br />
<br />
Create a note card named "Radio Control config", paste the example text from the section below, and put it in the prim.<br />
<br />
Create a new script in the prim. Paste a copy of the script from below over the default script and save it. <br />
<br />
When you touch the prim you will either trigger the MOAP display, or a menu to turn the radio on. You might notice that touching the MOAP surface again does NOT generate a menu. That is why we link the second prim, to act as a frame you can touch from the front of the board to get a menu.<br />
<br />
I like to texture all of the non-display sides of the Display prim black. <br />
<br />
Create a second prim , slightly larger than the first, color and texture as you prefer, and then position it so that it frames the display prim. Select the Display prim LAST , to make sure it is linked as root, and link the 2 prims. Now you should be able to touch the frame to get access to the menus.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable. When it was first posted it included SL specific addresses for returning profile images by UUID... these will be removed.... <br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) Doug Osborn 4/25/2011<br />
// version 3 (c) Doug Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
# New format Shoutcast - radio controller config notecard<br />
# The format is divided in 4 sections:<br />
# 1 - Access configuration<br />
# 2 - Ban list (keys)<br />
# 3 - Categories (same as genres)<br />
# 4 - Station info (category, name, desc, url)<br />
# The '#' character defines the start of a comment and can be anywhere on a line. <br />
# Everything after the '#' incuding the '#' itself is ignored.<br />
# Case is not important (but information on display will show as entered)<br />
# Spaces before and/or after fields are trimmed.<br />
# Empty lines are ignored.<br />
<br />
[ACCESS]<br />
dj=no # yes, true,1 means dj's has access. everything else not.<br />
group=no # ,, ,, ,, means group has acess. ,, ,, ,,<br />
public=yes # ,, ,, ,, means public has access. ,, ,, ,, <br />
#Avatar UUID with access <br />
12a18155-403d-496f-9dd1-a28a98b98342<br />
#Avatar UUID with access <br />
85fbed46-ba6e-4740-acdd-867dae792bf4<br />
<br />
<br />
[BANNED]<br />
# Avatar UUID BANNED from access <br />
014852ac-0260-4ecc-84fd-9f653b8b841c<br />
<br />
[GENRE]<br />
# genre name -- Use short genre names as the the length of menu buttons is short!<br />
Blues<br />
Classic Rock<br />
Country<br />
Dance<br />
DJ<br />
Jazz<br />
Live<br />
Reggae<br />
Romance<br />
# etc.<br />
[STATION]<br />
# Shoutcast radio stations<br />
# Use a '|' between each field - don't mind spaces before and after fields, they will be trimmed<br />
# field1:genre, field2:station name, field3: station description, field4: station http://<ip>:<port> or https://<ip>:<port>, field5 : dj UUID<br />
# Note that genre must match case-insensitive a value previously entered in section [GENRE]<br />
# Only DJ lines required a DJ ID.. if one is entered it will enable access to, and display the Profile picture of, the UUID provided.<br />
Classic Rock | Absolute | Absolute Radio | http://205.188.215.226:8018<br />
Classic Rock | 181fm | 181fm Classic | http://uplink.181.fm:8058<br />
Blues | KOQX | KOQX | http://69.94.112.216:8000<br />
Blues | One.FM | ONE.FM Stepchilds club | http://64.62.252.130:8030<br />
Blues | BU4B | Belly Up 4 Blues | http://64.62.252.134:5100<br />
Jazz | SwissGrv | Swiss Groove | http://82.197.165.135:80<br />
Jazz | Sky.fm | Smooth Jazz | http://scfire-dll-aa05.stream.aol.com:80/stream/1010<br />
Dance | Fox | Fox | http://87.98.169.191:11418<br />
Dance | Hitz | Hitz | http://scfire-mtc-aa04.stream.aol.com:80/stream/1014<br />
Romance | SlowDance | Slowdance | http://216.155.137.149:8006<br />
Reggae | Roots | BigUpRadio Roots | http://173.236.79.22:8005<br />
Reggae | Ska | BigUpRadio Ska | http://167.114.38.75:8017<br />
DJ | Autumn | DJ Autumn | http://srv8.karadio.biz:56303 | 6f666533-80ee-4d68-922b-6253ed50b973<br />
DJ | Dohran | DJ Dohran | http://dozo.primcast.com:8940 | aa61d79c-244b-4167-be70-a9a575b12c5c<br />
DJ | Jada1 | DJ Jada1 | http://85.214.250.196:8212 | 76f7f2e3-01bf-4ccd-b3b0-3083551e2c87<br />
DJ | P.Parks | DJ Parallel | http://srv3.karadio.biz:18705 | ce735cfe-43fd-45d6-9ba2-8e314c30af4a<br />
DJ | Sesha | Sesha | http://74.222.1.105:8962 | 788fc597-d7bb-4ef8-a27e-7e2ba564c40c<br />
DJ | Troi | Dj Troi | http://srv10.karadio.biz:17959 | 93c39f70-bfd3-4e5f-a4a0-be54bd9ce320<br />
<br />
# etc.<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T23:43:48Z
<p>Dz: /* Configuration Notecard */</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
<br />
Configurable Access by owner, group, or individuals (DJs)<br />
<br />
Default Texture override.<br />
<br />
10 user defined GENRE Categories.<br />
<br />
Unlimited URLs per GENRE.<br />
<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
I recommend at least 2 prims to construct the board.<br />
<br />
First, a Display prim to hold the script and display the info.<br />
<br />
I like to size it 1H and 2W so 256x512 & 512x1024 textures display without distortion.<br />
So, rez a box and resize it X: 0.05 meter Y: 2 meter and Z: 1 meter.<br />
<br />
Create a note card named "Radio Control config", paste the example text from the section below, and put it in the prim.<br />
<br />
Create a new script in the prim. Paste a copy of the script from below over the default script and save it. <br />
<br />
When you touch the prim you will either trigger the MOAP display, or a menu to turn the radio on. You might notice that touching the MOAP surface again does NOT generate a menu. That is why we link the second prim, to act as a frame you can touch from the front of the board to get a menu.<br />
<br />
I like to texture all of the non-display sides of the Display prim black. <br />
<br />
Create a second prim , slightly larger than the first, color and texture as you prefer, and then position it so that it frames the display prim. Select the Display prim LAST , to make sure it is linked as root, and link the 2 prims. Now you should be able to touch the frame to get access to the menus.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable. When it was first posted it included SL specific addresses for returning profile images by UUID... these will be removed.... <br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) Doug Osborn 4/25/2011<br />
// version 3 (c) Doug Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
# New format Shoutcast - radio controller config notecard<br />
# The format is divided in 4 sections:<br />
# 1 - Access configuration<br />
# 2 - Ban list (keys)<br />
# 3 - Categories (same as genres)<br />
# 4 - Station info (category, name, desc, url)<br />
# The '#' character defines the start of a comment and can be anywhere on a line. <br />
# Everything after the '#' incuding the '#' itself is ignored.<br />
# Case is not important (but information on display will show as entered)<br />
# Spaces before and/or after fields are trimmed.<br />
# Empty lines are ignored.<br />
<br />
[ACCESS]<br />
dj=no # yes, true,1 means dj's has access. everything else not.<br />
group=no # ,, ,, ,, means group has acess. ,, ,, ,,<br />
public=yes # ,, ,, ,, means public has access. ,, ,, ,, <br />
#Avatar UUID with access <br />
12a18155-403d-496f-9dd1-a28a98b98342<br />
#Avatar UUID with access <br />
85fbed46-ba6e-4740-acdd-867dae792bf4<br />
<br />
<br />
[BANNED]<br />
# Avatar UUID BANNED from access <br />
014852ac-0260-4ecc-84fd-9f653b8b841c<br />
<br />
[GENRE]<br />
# genre name -- Use short genre names as the the length of menu buttons is short!<br />
Blues<br />
Classic Rock<br />
Country<br />
Dance<br />
DJ<br />
Jazz<br />
Live<br />
Reggae<br />
Romance<br />
# etc.<br />
[STATION]<br />
# Shoutcast radio stations<br />
# Use a '|' between each field - don't mind spaces before and after fields, they will be trimmed<br />
# field1:genre, field2:station name, field3: station description, field4: station http://<ip>:<port> or https://<ip>:<port>, field5 : dj UUID<br />
# Note that genre must match case-insensitive a value previously entered in section [GENRE]<br />
# Only DJ lines required a DJ ID.. if one is entered it will enable access to, and display the Profile picture of, the UUID provided.<br />
Classic Rock | Absolute | Absolute Radio | http://205.188.215.226:8018<br />
Classic Rock | 181fm | 181fm Classic | http://uplink.181.fm:8058<br />
Blues | KOQX | KOQX from Fogbound | http://69.94.112.216:8000<br />
Blues | Hotlanta | Hotlanta club | http://blue.neostreams.info:8006<br />
Blues | melodies | melodies club | http://94.23.7.16:80<br />
Blues | One.FM | ONE.FM Stepchilds club | http://64.62.252.130:8030<br />
Blues | BU4B | Belly Up 4 Blues | http://64.62.252.134:5100<br />
Blues | muddys | muddys club | http://94.127.17.95:8210<br />
Jazz | SwissGrv | Swiss Groove | http://82.197.165.135:80<br />
Jazz | Sky.fm | Smooth Jazz | http://scfire-dll-aa05.stream.aol.com:80/stream/1010<br />
Dance | Fox | Fox | http://87.98.169.191:11418<br />
Dance | Hitz | Hitz | http://scfire-mtc-aa04.stream.aol.com:80/stream/1014<br />
Romance | SlowDance | Slowdance | http://216.155.137.149:8006<br />
Reggae | Roots | BigUpRadio Roots | http://173.236.79.22:8005<br />
Reggae | DanceHall | BigUpRadio DanceHall | http://167.114.38.71:8000<br />
Reggae | Reggaeton | BigUpRadio Reggaeton | http://173.236.79.27:8029<br />
Reggae | Dub | BigUpRadio Dub | http://66.90.104.65:8013<br />
Reggae | Ska | BigUpRadio Ska | http://167.114.38.75:8017<br />
DJ | Autumn | DJ Autumn | http://srv8.karadio.biz:56303 | 6f666533-80ee-4d68-922b-6253ed50b973<br />
DJ | Dohran | DJ Dohran | http://dozo.primcast.com:8940 | aa61d79c-244b-4167-be70-a9a575b12c5c<br />
DJ | Jada1 | DJ Jada1 | http://85.214.250.196:8212 | 76f7f2e3-01bf-4ccd-b3b0-3083551e2c87<br />
DJ | P.Parks | DJ Parallel | http://srv3.karadio.biz:18705 | ce735cfe-43fd-45d6-9ba2-8e314c30af4a<br />
DJ | Sesha | Sesha | http://74.222.1.105:8962 | 788fc597-d7bb-4ef8-a27e-7e2ba564c40c<br />
DJ | Troi | Dj Troi | http://srv10.karadio.biz:17959 | 93c39f70-bfd3-4e5f-a4a0-be54bd9ce320<br />
<br />
# etc.<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T23:35:14Z
<p>Dz: /* The BETA script */</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
<br />
Configurable Access by owner, group, or individuals (DJs)<br />
<br />
Default Texture override.<br />
<br />
10 user defined GENRE Categories.<br />
<br />
Unlimited URLs per GENRE.<br />
<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
I recommend at least 2 prims to construct the board.<br />
<br />
First, a Display prim to hold the script and display the info.<br />
<br />
I like to size it 1H and 2W so 256x512 & 512x1024 textures display without distortion.<br />
So, rez a box and resize it X: 0.05 meter Y: 2 meter and Z: 1 meter.<br />
<br />
Create a note card named "Radio Control config", paste the example text from the section below, and put it in the prim.<br />
<br />
Create a new script in the prim. Paste a copy of the script from below over the default script and save it. <br />
<br />
When you touch the prim you will either trigger the MOAP display, or a menu to turn the radio on. You might notice that touching the MOAP surface again does NOT generate a menu. That is why we link the second prim, to act as a frame you can touch from the front of the board to get a menu.<br />
<br />
I like to texture all of the non-display sides of the Display prim black. <br />
<br />
Create a second prim , slightly larger than the first, color and texture as you prefer, and then position it so that it frames the display prim. Select the Display prim LAST , to make sure it is linked as root, and link the 2 prims. Now you should be able to touch the frame to get access to the menus.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable. When it was first posted it included SL specific addresses for returning profile images by UUID... these will be removed.... <br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) Doug Osborn 4/25/2011<br />
// version 3 (c) Doug Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T23:32:36Z
<p>Dz: /* Building the Board */ simple walkthrough added</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
<br />
Configurable Access by owner, group, or individuals (DJs)<br />
<br />
Default Texture override.<br />
<br />
10 user defined GENRE Categories.<br />
<br />
Unlimited URLs per GENRE.<br />
<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
I recommend at least 2 prims to construct the board.<br />
<br />
First, a Display prim to hold the script and display the info.<br />
<br />
I like to size it 1H and 2W so 256x512 & 512x1024 textures display without distortion.<br />
So, rez a box and resize it X: 0.05 meter Y: 2 meter and Z: 1 meter.<br />
<br />
Create a note card named "Radio Control config", paste the example text from the section below, and put it in the prim.<br />
<br />
Create a new script in the prim. Paste a copy of the script from below over the default script and save it. <br />
<br />
When you touch the prim you will either trigger the MOAP display, or a menu to turn the radio on. You might notice that touching the MOAP surface again does NOT generate a menu. That is why we link the second prim, to act as a frame you can touch from the front of the board to get a menu.<br />
<br />
I like to texture all of the non-display sides of the Display prim black. <br />
<br />
Create a second prim , slightly larger than the first, color and texture as you prefer, and then position it so that it frames the display prim. Select the Display prim LAST , to make sure it is linked as root, and link the 2 prims. Now you should be able to touch the frame to get access to the menus.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable.<br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) Doug Osborn 4/25/2011<br />
// version 3 (c) Doug Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T22:51:53Z
<p>Dz: /* Building the Board */</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
<br />
Configurable Access by owner, group, or individuals (DJs)<br />
<br />
Default Texture override.<br />
<br />
10 user defined GENRE Categories.<br />
<br />
Unlimited URLs per GENRE.<br />
<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
I recommend at least 2 prims to construct the board.<br />
<br />
First, a Display prim to hold the script and display the info. <br />
I like to size it 1H and 2W so 256x512 & 512x1024 textures display without distortion.<br />
so, rez a box and resize it X: 2 meters Y: 1 meter and Z: .05 meters deep.<br />
<br />
I use a 2 prim object for my display boards. the display itself I size in a 1:2 (Height : Width) size. This allows <br />
The other thing to remember is that one face of your base prim is going to be turned into a web display, this will disable the ability to click on the display to generate a touch event to trigger a menu.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable.<br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) Doug Osborn 4/25/2011<br />
// version 3 (c) Doug Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User_talk:Dz/ShoutCast
User talk:Dz/ShoutCast
2015-08-31T21:38:32Z
<p>Dz: new page for script feedback</p>
<hr />
<div>This page is for '''CONSTRUCTIVE''' comments related to the use and operation of the dzShoutcast scripts.</div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T21:27:32Z
<p>Dz: spacing</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
<br />
Configurable Access by owner, group, or individuals (DJs)<br />
<br />
Default Texture override.<br />
<br />
10 user defined GENRE Categories.<br />
<br />
Unlimited URLs per GENRE.<br />
<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
You are free to design your own container for this script but there are implications of using M.O.A.P. as a display driver.<br />
Obviously.. if you expect users who do not have MOAP enabled viewers ( really?? still???) this may be less than useful.<br />
<br />
I use a 2 prim object for my display boards. the display itself I size in a 1:2 (Height : Width) size. This allows <br />
The other thing to remember is that one face of your base prim is going to be turned into a web display, this will disable the ability to click on the display to generate a touch event to trigger a menu.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable.<br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) Doug Osborn 4/25/2011<br />
// version 3 (c) Doug Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T21:26:49Z
<p>Dz: verified copyright dates</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
Configurable Access by owner, group, or individuals (DJs)<br />
Default Texture override.<br />
10 user defined GENRE Categories.<br />
Unlimited URLs per GENRE.<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
You are free to design your own container for this script but there are implications of using M.O.A.P. as a display driver.<br />
Obviously.. if you expect users who do not have MOAP enabled viewers ( really?? still???) this may be less than useful.<br />
<br />
I use a 2 prim object for my display boards. the display itself I size in a 1:2 (Height : Width) size. This allows <br />
The other thing to remember is that one face of your base prim is going to be turned into a web display, this will disable the ability to click on the display to generate a touch event to trigger a menu.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable.<br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 3 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) Doug Osborn 4/25/2011<br />
// version 3 (c) Doug Osborn 2015<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// Tested for Opensim release<br />
<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T21:23:25Z
<p>Dz: Added Useful section titles and filled in some of the details.... Beta script added and checked copyright notices</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== Feature List ===<br />
<br />
Note card configuration.<br />
MOAP style information display with Texture slide show option for non MOAP viewers.<br />
Configurable Access by owner, group, or individuals (DJs)<br />
Default Texture override.<br />
10 user defined GENRE Categories.<br />
Unlimited URLs per GENRE.<br />
Usable on Group owned land.<br />
<br />
=== Building the Board ===<br />
<br />
You are free to design your own container for this script but there are implications of using M.O.A.P. as a display driver.<br />
Obviously.. if you expect users who do not have MOAP enabled viewers ( really?? still???) this may be less than useful.<br />
<br />
I use a 2 prim object for my display boards. the display itself I size in a 1:2 (Height : Width) size. This allows <br />
The other thing to remember is that one face of your base prim is going to be turned into a web display, this will disable the ability to click on the display to generate a touch event to trigger a menu.<br />
<br />
=== The BETA script ===<br />
<br />
I will attempt to document the changes to the script as I upgrade from BETA release status. This is a copy of a board i have been using in SL for a couple years... it is not bug free but it has been useful and reliable.<br />
<br />
<source lang = "lsl"><br />
<br />
// Viewer 2 Dynamic HTML Shoutcast stream controller<br />
<br />
// version 2.5 (c) dz questi 4/25/2011<br />
<br />
// Converted existing script to use Floating Text and dynamic HTML display<br />
// Corrected multiple menu display feature<br />
// Added UUID access list feature<br />
// This script is a modification of the script described below<br />
// It is released in accordance to the license granted, and is released under the same license<br />
<br />
// Script: Shoutcast - radio controller<br />
// Version: 0.3 - released 10-2-2011<br />
// Logic Scripts (Flennan Roffo)<br />
// (c) 2010 - Flennan Roffo (Logic Scripts)<br />
<br />
// LICENCE INFO<br />
//<br />
// This program is free software: you can redistribute it and/or modify<br />
// it under the terms of the GNU General Public License as published by<br />
// the Free Software Foundation, either version 3 of the License, or<br />
// (at your option) any later version.<br />
//<br />
// This program is distributed in the hope that it will be useful,<br />
// but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
// GNU General Public License for more details.<br />
//<br />
// You should have received a copy of the GNU General Public License<br />
// along with this program. If not, see <http://www.gnu.org/licenses/>.<br />
///////////////////////////////////////////////////////////////////////////////////////////<br />
<br />
float update_time=30.0; /////// EDITABLE \\\\\\<br />
<br />
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\<br />
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\<br />
string comment_char="#"; /////// EDITABLE \\\\\\<br />
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\<br />
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\<br />
<br />
// Buttons<br />
<br />
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\<br />
string button_HELP = "HELP"; /////// EDITABLE \\\\\\<br />
string button_NEXT = ">>"; /////// EDITABLE \\\\\\<br />
string button_PREV = "<<"; /////// EDITABLE \\\\\\<br />
string button_ON = "ON"; /////// EDITABLE \\\\\\ <br />
string button_OFF = "OFF"; /////// EDITABLE \\\\\\<br />
<br />
// Profile picture particle parameters<br />
float PictSize = 1.0;<br />
<br />
key ppReqID = NULL_KEY;<br />
key ProfilePic = NULL_KEY;<br />
key lastWho = NULL_KEY;<br />
<br />
key MyOwner = NULL_KEY;<br />
<br />
// List of categories (=genres)<br />
<br />
list category_list=[];<br />
<br />
// List of stations. KEEP THESE LISTS IN SYNCH!<br />
<br />
list station_category=[];<br />
list station_name=[];<br />
list station_desc=[];<br />
list station_url=[];<br />
list dj_UUID = [];<br />
list UUID_access = [];<br />
<br />
<br />
string StationId = "";<br />
string GenreType = "";<br />
string ThisTitle = "";<br />
string LastTitle = "";<br />
<br />
integer radio_status=0; // 0 - OFF 1 - ON<br />
string parcel_url="";<br />
integer lineno=0;<br />
key reqid=NULL_KEY;<br />
key httpreq_id=NULL_KEY;<br />
integer config_error=FALSE;<br />
integer flag;<br />
integer section=0;<br />
<br />
integer displayface = 4;<br />
integer imagesfound = 0;<br />
integer whichimage = 0;<br />
<br />
// Access values. Note that users who are banned can not access the device even when access is public<br />
integer dj_access=TRUE;<br />
integer group_access=TRUE;<br />
integer public_access=FALSE;<br />
list banned_keys=[];<br />
<br />
// Channels for menu and user input<br />
integer menu_channel;<br />
integer listen_handle;<br />
<br />
// Channel for deeded object<br />
integer DeedChannel = -142356;<br />
<br />
string ParcelName = "";<br />
<br />
// Menu<br />
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)<br />
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.<br />
<br />
// Genres and stations<br />
<br />
integer category_index=0; // Current index in category_list (genre)<br />
integer station_index=0; // Current index in station_* (station)<br />
<br />
integer num_categories=0;<br />
integer num_stations=0;<br />
<br />
///// DEFINE the script Functions /////////<br />
<br />
// Make request for title info using HTTP request<br />
retrieve_titelinfo()<br />
{<br />
string url=llList2String(station_url,station_index);<br />
// httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// llSay(0," send to : " + url + "/7.html");<br />
httpreq_id=llHTTPRequest(url + "/7.html HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n",[],"");<br />
// httpreq_id=llHTTPRequest(url + "/7.html",[],"");<br />
}<br />
<br />
// Make request for profile picture using metatag info<br />
getProfilePic(key AvatarKey)<br />
{<br />
ppReqID = llHTTPRequest( "http://world.secondlife.com/resident/" + (string)AvatarKey,[HTTP_METHOD,"GET"],"");<br />
}<br />
<br />
// Set particle system<br />
setProfilePic(key Texture)<br />
{<br />
if (Texture != NULL_KEY)<br />
{<br />
vector resizer = llGetScale();<br />
PictSize = resizer.z / 0.75;<br />
<br />
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK,<br />
PSYS_SRC_PATTERN, 4,<br />
PSYS_PART_START_ALPHA, 0.5,<br />
PSYS_PART_END_ALPHA, 0.5,<br />
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,<br />
PSYS_PART_START_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_END_SCALE, <PictSize, PictSize, 0.0>,<br />
PSYS_PART_MAX_AGE, 1.2,<br />
PSYS_SRC_MAX_AGE, 0.0,<br />
PSYS_SRC_ACCEL, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_ANGLE_BEGIN, 0.0,<br />
PSYS_SRC_ANGLE_END, 0.0,<br />
PSYS_SRC_BURST_PART_COUNT, 8,<br />
PSYS_SRC_BURST_RADIUS, PictSize,<br />
PSYS_SRC_BURST_RATE, 0.1,<br />
PSYS_SRC_BURST_SPEED_MIN, 0.0,<br />
PSYS_SRC_BURST_SPEED_MAX, 0.0,<br />
PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,<br />
PSYS_SRC_TEXTURE, Texture]);<br />
}<br />
<br />
}<br />
<br />
<br />
// Update text displays with new info<br />
updateText(string line, string message)<br />
{<br />
<br />
if(line == "1")<br />
StationId = message;<br />
<br />
if (line == "2")<br />
GenreType = message;<br />
<br />
if (line == "3")<br />
{<br />
ThisTitle = message;<br />
<br />
// llSay(0," height " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS] ));<br />
// llSay(0," width " + (string) llGetPrimMediaParams(displayface,[PRIM_MEDIA_WIDTH_PIXELS] ));<br />
<br />
llSetText( StationId + " \n(" + GenreType + ") \nNow Playing :" + ThisTitle + "\n \nLast Song: " + LastTitle, <0.0, 1.0, 0.0>, 1.0);<br />
<br />
string WebText = "<body bgcolor='black'><div style='text-align: center;'><font size='7'><font color ='blue'><i><h1>" + StationId +"</i> ( " + GenreType + " )</h1><p><i><h3>On NOW</h3></i><p><h1>"+ ThisTitle + "<p><p></h1><h3><i>Last</i></h3><p><h1>" + LastTitle + "</h1></div></body>";<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_CURRENT_URL, "data:text/html," + WebText]);<br />
<br />
<br />
LastTitle = ThisTitle;<br />
} <br />
<br />
}<br />
<br />
// Display a line<br />
display_line(string line, string message)<br />
{<br />
<br />
// llSay(0,message);<br />
updateText(line, message);<br />
}<br />
<br />
// Set the text display to default<br />
clear_display()<br />
{<br />
// Clears the display<br />
display_line("1","Radio Station ID");<br />
display_line("2","Music Genre....");<br />
display_line("3","Now Playing....");<br />
}<br />
<br />
// Make a menu / dialog<br />
make_menu(key id)<br />
{<br />
menu_channel=random_channel();<br />
<br />
if (radio_status == 0)<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);<br />
}<br />
else<br />
{<br />
if (menu_type ==0)<br />
{<br />
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);<br />
}<br />
else<br />
{<br />
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);<br />
}<br />
}<br />
<br />
if (listen_handle != 0) llListenRemove(listen_handle);<br />
listen_handle=llListen(menu_channel,"",id,"");<br />
}<br />
<br />
// Make the menu option list for menu: catagories (genres)<br />
list category_menu(integer num)<br />
{<br />
integer len=llGetListLength(category_list);<br />
list menu=[];<br />
<br />
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)<br />
{<br />
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
if (num == 0)<br />
menu+=(list)button_HELP;<br />
else<br />
menu+=(list)button_MAIN;<br />
<br />
if (num == 0)<br />
menu+=(list)button_OFF;<br />
else<br />
menu+=(list)button_PREV;<br />
<br />
if (num != last_sub)<br />
menu+=(list)button_NEXT; <br />
} <br />
}<br />
else<br />
{<br />
while (--len >= 0)<br />
menu+=(list)llList2String(category_list,len);<br />
<br />
menu+=(list)button_OFF;<br />
menu+=(list)button_HELP;<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns the number of stations in a certain category<br />
integer stations_in_category(integer cat)<br />
{<br />
integer count=0;<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
string category=llList2String(category_list,cat);<br />
<br />
for (i=0; i < len; i++)<br />
if (category == llList2String(category_list,i))<br />
count++;<br />
<br />
return count;<br />
}<br />
<br />
<br />
// Returns a list of station names in a certain category (genre)<br />
list station_list(integer category)<br />
{<br />
list s=[];<br />
integer i;<br />
integer catcnt = llGetListLength(station_name);<br />
string cname=llList2String(category_list,category_index);<br />
<br />
for (i = 0; i < catcnt; i++)<br />
if (llList2String(station_category,i) == cname)<br />
s+=(list)llList2String(station_name,i);<br />
<br />
return s;<br />
<br />
}<br />
<br />
// Returns the list of stations for the station menu, depending on the submenu number<br />
list station_menu(integer num)<br />
{<br />
list stations=station_list(category_index);<br />
integer len=llGetListLength(stations);<br />
list menu=[];<br />
<br />
if (len > 11) // 12 - 1 for MAIN menu<br />
{<br />
integer last_sub=(len-1)/9;<br />
<br />
if (num > last_sub)<br />
{<br />
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");<br />
return [ "MAIN" ];<br />
}<br />
else<br />
{<br />
integer first=9*num;<br />
integer last=9*num+8;<br />
<br />
// llSay(0,"delivering menu for stations" + (string) first + " to " + (string) last);<br />
<br />
menu+=(list)button_MAIN;<br />
<br />
if (num > 0)<br />
menu+=(list)button_PREV;<br />
<br />
if (num < last_sub)<br />
menu+=(list)button_NEXT; <br />
<br />
if (len > last)<br />
len =last;<br />
<br />
while (--len >= first)<br />
menu+=(list)llList2String(stations,len);<br />
}<br />
} <br />
else<br />
{<br />
menu+=(list)button_MAIN;<br />
<br />
while (--len >= 0)<br />
menu+=(list)llList2String(stations,len);<br />
} <br />
<br />
return menu; // order_buttons(menu);<br />
}<br />
<br />
// Returns whether av with key id has access<br />
integer has_access(key id)<br />
{<br />
if (id == MyOwner)<br />
return TRUE; <br />
<br />
if (llListFindList(banned_keys,(list)id) != -1)<br />
return FALSE;<br />
<br />
if (llListFindList(UUID_access,(list)id) != -1)<br />
return TRUE; <br />
<br />
if (dj_access && llListFindList(dj_UUID,(list)id) != -1)<br />
return TRUE;<br />
<br />
if (group_access && llSameGroup(id))<br />
return TRUE;<br />
<br />
if (public_access)<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used<br />
integer random_channel()<br />
{<br />
integer min=-2147483647;<br />
integer max=-1000;<br />
<br />
return (integer) (min + llFrand(max-min));<br />
}<br />
<br />
<br />
<br />
// Returns a true value depending on the first character in input - anything else is assumed false.<br />
integer true_value(string input)<br />
{<br />
string value=llToLower(llGetSubString(input,0,0));<br />
<br />
if (value == "y" || value == "t" || value =="1")<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.<br />
integer process_line(string dataline)<br />
{<br />
string line=llStringTrim(dataline,STRING_TRIM);<br />
integer index=llSubStringIndex(line,comment_char);<br />
<br />
if (index==0) // line starts with comment - ignore line<br />
return TRUE;<br />
<br />
if (index!=-1)<br />
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail<br />
<br />
if (line=="") // Ignore blank lines<br />
return TRUE;<br />
<br />
if (llToLower(line) == "[access]")<br />
{<br />
section = 1;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[banned]")<br />
{<br />
section = 2;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[genre]")<br />
{<br />
section = 3;<br />
return TRUE;<br />
}<br />
else if (llToLower(line) == "[station]")<br />
{<br />
section = 4;<br />
return TRUE;<br />
}<br />
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")<br />
{<br />
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
if (section == 0)<br />
{<br />
llWhisper(0,"error: no section found on line: " + (string) lineno);<br />
config_error = TRUE;<br />
return FALSE;<br />
}<br />
<br />
list breakup=llParseString2List(line,["="],[]);<br />
<br />
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);<br />
<br />
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);<br />
<br />
if (section == 1) // access<br />
{<br />
field=llToLower(field);<br />
<br />
if (field=="dj")<br />
{<br />
dj_access=true_value(values); <br />
return TRUE;<br />
}<br />
else if (field=="group")<br />
{ <br />
group_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (field=="public")<br />
{<br />
public_access=true_value(values);<br />
return TRUE;<br />
}<br />
else if (llStringLength(field) == 36 )<br />
{<br />
UUID_access += [(key)field];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
}<br />
else if (section == 2) // ban list<br />
{<br />
key try=(key) field;<br />
<br />
if (try)<br />
{<br />
banned_keys+=(list)((key) field);<br />
return TRUE;<br />
}<br />
else<br />
return FALSE;<br />
}<br />
else if (section == 3) // categories<br />
{<br />
if (llListFindList(category_list,(list)field) == -1)<br />
{<br />
category_list+=(list)field;<br />
}<br />
else<br />
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");<br />
<br />
return TRUE;<br />
}<br />
else if (section == 4) // stations<br />
{<br />
list parse=llParseString2List(line,sep_char_list, []);<br />
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);<br />
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);<br />
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);<br />
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);<br />
string AviUUID=llStringTrim(llToLower(llList2String(parse,4)),STRING_TRIM);<br />
<br />
if (!available_category(category))<br />
{<br />
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);<br />
config_error=TRUE;<br />
return FALSE;<br />
}<br />
<br />
<br />
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1 || llListFindList(station_name,(list)name) == -1)<br />
{<br />
num_stations++;<br />
station_category+=(list)category;<br />
station_name+=(list)name;<br />
station_desc+=(list)desc;<br />
station_url+=(list)url;<br />
dj_UUID += [(key)AviUUID];<br />
return TRUE;<br />
}<br />
else<br />
{<br />
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);<br />
return TRUE;<br />
}<br />
<br />
}<br />
<br />
return FALSE;<br />
}<br />
<br />
// Sets the parcel URL and updates the display<br />
set_parcel_url(string url)<br />
{<br />
parcel_url=url;<br />
llSetParcelMusicURL(parcel_url);<br />
<br />
llRegionSay(DeedChannel,ParcelName + "|" + parcel_url);<br />
<br />
llSay(0," changinf url for " + ParcelName);<br />
<br />
if (parcel_url=="")<br />
{<br />
clear_display();<br />
display_line("1","Radio is OFF");<br />
display_line("2","");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");<br />
display_line("1","Station: " + llList2String(station_desc,station_index));<br />
display_line("2", llList2String(category_list,category_index));<br />
display_line("3","Now playing.....");<br />
llSetTimerEvent(update_time);<br />
}<br />
}<br />
<br />
// Returns if a category (genre) exists.<br />
integer available_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(category_list);<br />
<br />
for (i=0;i<len;i++)<br />
if (llToLower(category) == llToLower(llList2String(category_list,i)))<br />
return TRUE;<br />
<br />
return FALSE;<br />
}<br />
<br />
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))<br />
integer empty_category(string category)<br />
{<br />
integer i;<br />
integer len=llGetListLength(station_category);<br />
<br />
for (i=0; i < len; i++)<br />
if (llToLower(category) == llToLower(llList2String(station_category,i)))<br />
return FALSE;<br />
<br />
return TRUE;<br />
}<br />
<br />
// Removes categories (genres) for which no station is known.<br />
skip_empty_categories()<br />
{<br />
integer i=0;<br />
<br />
while (i<llGetListLength(category_list))<br />
{<br />
if (empty_category(llList2String(category_list,i)))<br />
{<br />
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");<br />
category_list=llDeleteSubList(category_list,i,i);<br />
}<br />
else<br />
i++;<br />
}<br />
<br />
num_categories=llGetListLength(category_list);<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state default<br />
////////////////////////////////////////////<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
flag=FALSE;<br />
lineno=0;<br />
config_error=FALSE;<br />
num_stations=0;<br />
num_categories=0;<br />
radio_status=0;<br />
menu_num=0;<br />
menu_type=0;<br />
<br />
MyOwner = llGetOwner();<br />
<br />
list details = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]);<br />
ParcelName = llList2String(details ,0);<br />
<br />
imagesfound = llGetInventoryNumber(INVENTORY_TEXTURE);<br />
<br />
llParticleSystem([]);<br />
<br />
if (imagesfound < 1)<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, "adbff0cd-09c0-54b1-aeaa-ffd6eabfcab09",<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
else<br />
{<br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,0),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
}<br />
<br />
llSetPrimMediaParams(displayface,[PRIM_MEDIA_HEIGHT_PIXELS, 1024, PRIM_MEDIA_WIDTH_PIXELS, 2048, PRIM_MEDIA_PERMS_CONTROL , PRIM_MEDIA_PERM_NONE]);<br />
<br />
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)<br />
{<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
llWhisper(0, "Reading config notecard...");<br />
display_line("1","Reading configuration.");<br />
display_line("2","Wait....");<br />
display_line("3","");<br />
}<br />
else<br />
{<br />
llWhisper(0,"No config notecard '" + config_notecard + "' present.");<br />
state offline;<br />
}<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
dataserver(key id, string data)<br />
{<br />
if (reqid==id)<br />
{ <br />
if (data==EOF)<br />
{<br />
skip_empty_categories();<br />
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");<br />
display_line("1","Configuration OK");<br />
display_line("2","Genres : " + (string)num_categories);<br />
display_line("3","Stations: " + (string)num_stations);<br />
state menu;<br />
}<br />
else<br />
{<br />
if (process_line(data))<br />
reqid=llGetNotecardLine(config_notecard,lineno++);<br />
else if (config_error)<br />
{<br />
llWhisper(0,"errors found in configuration. please correct them.");<br />
state offline;<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state offline<br />
////////////////////////////////////////////<br />
<br />
state offline<br />
{<br />
state_entry()<br />
{<br />
llWhisper(0,"Reset on owner touch or when notecard updated.");<br />
}<br />
<br />
touch_start(integer t)<br />
{<br />
if (llDetectedKey(0)==llGetOwner())<br />
llResetScript();<br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
/////////////////////////////////////////////<br />
// state menu<br />
////////////////////////////////////////////<br />
<br />
state menu<br />
{<br />
state_entry()<br />
{<br />
menu_type=0;<br />
menu_num=0;<br />
listen_handle=0;<br />
}<br />
<br />
on_rez(integer param)<br />
{<br />
llResetScript();<br />
}<br />
<br />
touch_start(integer total_num)<br />
{<br />
key toucher=llDetectedKey(0);<br />
<br />
if (has_access(toucher))<br />
{<br />
make_menu(toucher);<br />
}<br />
else<br />
llWhisper(0,"sorry, no access.");<br />
}<br />
<br />
listen(integer chan, string name,key id,string msg)<br />
{<br />
integer index;<br />
<br />
if (menu_type == 0) // main menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else if (msg == button_ON)<br />
{<br />
radio_status=1; <br />
display_line("1","Radio is ON");<br />
menu_num=0;<br />
llWhisper(0,"Radio now turned on.");<br />
make_menu(id);<br />
}<br />
else if (msg == button_OFF)<br />
{<br />
radio_status=0;<br />
set_parcel_url("");<br />
llSetTimerEvent(0.0);<br />
llWhisper(0,"Radio now turned off.");<br />
}<br />
else if (msg == button_HELP)<br />
{<br />
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)<br />
{<br />
llGiveInventory(id,info_notecard);<br />
}<br />
else<br />
llWhisper(0,"sorry, help not available.");<br />
}<br />
else if (radio_status == 1)<br />
{<br />
index = llListFindList(category_list, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: genre not found: " + msg);<br />
else<br />
{<br />
category_index=index;<br />
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");<br />
menu_type=1;<br />
menu_num=0;<br />
make_menu(id);<br />
}<br />
}<br />
}<br />
else if (menu_type == 1 && radio_status == 1) // station menu<br />
{<br />
if (msg == button_MAIN)<br />
{<br />
menu_type=0;<br />
menu_num =0;<br />
make_menu(id);<br />
}<br />
else if (msg == button_NEXT)<br />
{<br />
menu_num++;<br />
make_menu(id);<br />
}<br />
else if (msg == button_PREV)<br />
{<br />
menu_num--;<br />
make_menu(id);<br />
}<br />
else<br />
{<br />
index = llListFindList(station_name, (list)msg);<br />
<br />
if (index == -1)<br />
llWhisper(0,"error: station not found: " + msg);<br />
else<br />
{<br />
station_index=index;<br />
string new_url=llList2String(station_url,station_index);<br />
string new_avi=llList2String(dj_UUID,station_index);<br />
<br />
llSay(0, llList2String(category_list,category_index) + " - found profile ID " + new_avi);<br />
<br />
if (new_url != parcel_url)<br />
{<br />
if (llList2String(category_list,category_index) == "DJ")<br />
{<br />
// getProfilePic(new_avi);<br />
}<br />
else<br />
{<br />
llParticleSystem([]);<br />
}<br />
<br />
set_parcel_url(new_url);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
timer()<br />
{<br />
retrieve_titelinfo();<br />
<br />
if (imagesfound > 0 )<br />
{ <br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 0.0]); <br />
<br />
llSetPrimitiveParams([PRIM_FULLBRIGHT,displayface,TRUE, PRIM_TEXTURE, displayface, llGetInventoryName(INVENTORY_TEXTURE,whichimage),<1.0,1.0,0.0>, <0.0,0.0,0.0>, 0.0]);<br />
llSleep(1.5);<br />
<br />
llSetPrimitiveParams([PRIM_COLOR,displayface,<1.0,1.0,1.0>, 1.0]); <br />
<br />
whichimage +=1;<br />
if (whichimage == imagesfound)<br />
whichimage = 0;<br />
}<br />
<br />
llSetTimerEvent(update_time);<br />
}<br />
<br />
http_response(key id, integer status, list meta, string body)<br />
{<br />
if (id == httpreq_id)<br />
{<br />
if (status == 200)<br />
{<br />
// llSay(0," http response : " + body);<br />
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);<br />
list feed_list = llParseString2List(feed,[","],[]);<br />
string current_title_info= llList2String(feed_list,6);<br />
integer length = llGetListLength(feed_list);<br />
<br />
if(llList2String(feed_list,7))<br />
{<br />
integer a = 7;<br />
for(; a<length; ++a)<br />
{<br />
current_title_info += ", " + llList2String(feed_list,a);<br />
}<br />
}<br />
<br />
if (current_title_info != LastTitle)<br />
{<br />
display_line("3", current_title_info);<br />
}<br />
}<br />
else<br />
{<br />
display_line("3", no_title_info);<br />
}<br />
}<br />
<br />
if (id == ppReqID)<br />
{<br />
llSay(0,"profile pic request returned");<br />
<br />
integer s1 = llSubStringIndex(body,"<meta name=\"imageid\" content=\"");<br />
integer s1l = llStringLength("<meta name=\"imageid\" content=\"");<br />
integer s2 = llSubStringIndex(body,"\" /> \n <meta name=\"agentid\"") - 1;<br />
<br />
if(s1 == -1)<br />
{<br />
ProfilePic = NULL_KEY;<br />
}<br />
else <br />
{<br />
ProfilePic = (key)llGetSubString(body,s1+s1l,s2);<br />
<br />
if ( ProfilePic != "00000000-0000-0000-0000-000000000000")<br />
{ <br />
if (lastWho == ProfilePic)<br />
{<br />
setProfilePic("a2769d9c-5733-dec8-ef86-a1bf27334de9");<br />
lastWho = NULL_KEY;<br />
}<br />
else<br />
{<br />
setProfilePic(ProfilePic);<br />
lastWho = ProfilePic;<br />
} <br />
} <br />
}<br />
} <br />
}<br />
<br />
changed(integer ch)<br />
{<br />
if (ch & CHANGED_INVENTORY)<br />
llResetScript();<br />
}<br />
}<br />
<br />
//////////////////////////////<br />
// end of script<br />
//////////////////////////////<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/ShoutCast
User:Dz/ShoutCast
2015-08-31T21:02:26Z
<p>Dz: Created page with "== dzShoutCast == As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs. If you have feedback on script..."</p>
<hr />
<div>== dzShoutCast ==<br />
<br />
<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/ShoutCast]]<br />
<br />
<br />
=== The script ===<br />
<br />
I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it.<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
<br />
<br />
<br />
</source ><br />
<br />
=== Group Land add-on ===<br />
<br />
When you try and change the URL on group owned land, you need to use an object deeded to the group..<br />
If you deed the ShoutCast board, you will probably lose the ability to edit the config note card...<br />
<br />
Place this script in a small prim somewhere on the parcel and then deed the prim to the proper group.<br />
It will relay the original ShoutCast board message....<br />
<br />
<source lang = "lsl"><br />
<br />
// dzShoutCast group land add on BETA<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, 2015 Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
// This scipt is designed to listen for a shoutcast board on the current parcel<br />
// to send a "Change URL" message. It is useful on group owned land.<br />
// Instead of deeding the shoutcast board to the group,.. Place this script in a prim,<br />
// leave the prim somewhere on the parcel, and then deed the prim to the group. <br />
<br />
integer listen_handle = 0; // Initialize handler to register listener<br />
string ParcelName = "";<br />
integer listen_channel = -142356;<br />
<br />
default<br />
{ <br />
state_entry() // Set the parcel Name and start listening for messages on the designated channel<br />
{<br />
ParcelName = llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0);<br />
<br />
listen_handle = llListen( listen_channel, "", "", "");<br />
}<br />
<br />
listen( integer channel, string name, key id, string message ) // Wait for incoming messages... <br />
{<br />
if(llGetSubString(name, 0, 6) == "dzShout") // Check to see they are from an object name we expect<br />
{<br />
list msg_list = llParseString2List(message,["|"],[""]); // parse the listen message<br />
string msgParcel = llList2String(msg_list ,0); // Looking for the parcel name it was sent from<br />
string msgHttp = llList2String(msg_list ,1); // and double checking it sent us an URL<br />
<br />
if (llGetSubString(msgHttp, 0, 3) == "http" && msgParcel == ParcelName)<br />
{<br />
llSetParcelMusicURL(msgHttp); // if everyhting looks good, set the new URL<br />
<br />
// llSay(0,"Setting url to : " + msgHttp); // and squawk about it Or not<br />
}<br />
} <br />
}<br />
<br />
on_rez(integer param) //Triggered when the object is rezed<br />
{ <br />
llResetScript(); // By resetting the script on rez it forces the listen to re-register.<br />
}<br />
<br />
changed(integer mask)<br />
{ <br />
if(mask & CHANGED_OWNER) // Triggered when the object containing this script changes owner.<br />
{<br />
llResetScript(); // should reset when deeded to group in place.<br />
}<br />
}<br />
}<br />
<br />
<br />
</source ><br />
<br />
=== Configuration Notecard ===<br />
<br />
This is how URLs are added to the menus and grouped into Genres.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz
User:Dz
2015-08-31T20:51:05Z
<p>Dz: Added ShoutCast board section</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Welcome to the OpenSimulator Space of dz ==<br />
<br />
I am generally involved in running OpenSim instances for fun, but I have been induced to try it for profit and the pursuit of scholarly credits.<br />
<br />
I am an incessant lurker...It took me 2 years to add these 3 lines to my profile here.<br />
<br />
I monitor the following OpenSimulator mailing-lists Opensim-Users, OpenSim-devs, libomv-dev. <br />
I can also be found lurking in the SL opensim group chat.<br />
<br />
I have been administering Linux based OpenSim servers since release 6.1, mostly on Ubuntu.<br />
I have active avatars on OSGrid, ScienceSim, Inworldz, and that "SL" place.<br />
<br />
<br />
<br />
----<br />
<br />
== NPC Utilities ==<br />
<br />
[[User:Dz/NPC Scripts]] Has the Latest NPC utilities<br />
<br />
<br />
== Animation overrides ==<br />
<br />
[[User:Dz/AO]] Has the Latest Animation Overrides designed for OpenSimulator<br />
<br />
<br />
== Avatar Proportion Scale ==<br />
<br />
[[User:Dz/Avatar Scale]] A simple scale to help you create more realistic avatar shapes<br />
<br />
<br />
== Media On a Prim Shoutcast Board ==<br />
<br />
[[User:Dz/ShoutCast]] A note card controlled ShoutCast board using MOAP to display stream info.</div>
Dz
http://opensimulator.org/wiki/User_talk:Dz/Avatar_Scale
User talk:Dz/Avatar Scale
2014-09-21T19:28:32Z
<p>Dz: added base to feedback page</p>
<hr />
<div>This page is for '''CONSTRUCTIVE''' comments realted to the use and operation of the Avatar Scale script.</div>
Dz
http://opensimulator.org/wiki/User:Dz/Avatar_Scale
User:Dz/Avatar Scale
2014-09-21T19:22:49Z
<p>Dz: added note card text</p>
<hr />
<div>== Avatar Scale ==<br />
<br />
This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator.<br />
With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using<br />
the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even<br />
attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue<br />
experimenting and improving this important skill.<br />
<br />
Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results<br />
of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique<br />
I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic<br />
BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
The scale relies on the ability to move a seated avatar via script. <br />
This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release.<br />
It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/Avatar Scale]]<br />
<br />
<br />
=== The script ===<br />
<br />
I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it.<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// Avatar proportion scale BETA<br />
// based on an "8 head" (Natural) or "9 head" (Heroic) human shape<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
//<br />
// To create your own scale from scratch, <br />
// Make a cube to act as your base. Texture it as you like and turn it phantom.<br />
// Make 9 more cubes and stack them on top of each other. <br />
// Link the 9 cubes together and then link that stack to your "base" cube<br />
// Copy the [CheckPorportions] animation and the [Proportional Avatar Sizing} notecard into the base<br />
// Drop this script into your base cube. <br />
// Your stack of cubes should transform into a "Natural" scale for a 2 meter avatar<br />
//<br />
//<br />
<br />
vector MyLocation = <0,0,0>;<br />
rotation MyRotation = ZERO_ROTATION;<br />
<br />
list offsetMultiplier = [1,3,5,7,9,11,13,15,17];<br />
<br />
string ANIMATION = "CheckProportions";<br />
<br />
key avatar = NULL_KEY;<br />
list menuButtons = ["Heroic","Natural","Set Height"]; <br />
list heightButtons = [ "Move Up", "Move Down"];<br />
integer menuchannel = -13572468;<br />
integer heightchannel = -13572469;<br />
integer mListener = 0;<br />
integer cListener = 0;<br />
float sitTargetHeight = 0;<br />
integer NaturalMode = TRUE;<br />
string menuStatusInfo = "";<br />
float currentScaleSize = 2.0;<br />
float menuTimeout = 30.0;<br />
vector primColor = <0.0, 0.0, 0.0>;<br />
float panelDivisor = 4.0;<br />
float widthAdjust = 0.02;<br />
<br />
setScaleDimensions(float newSize)<br />
{<br />
integer numlinks = 11;<br />
panelDivisor = 4.5;<br />
widthAdjust = 0.05;<br />
<br />
if (NaturalMode)<br />
{<br />
numlinks = 10;<br />
panelDivisor = 4;<br />
widthAdjust = -0.025;<br />
}<br />
<br />
llSay(0, "Resizing scale for a " +(string) newSize + " meter avatar");<br />
<br />
currentScaleSize = newSize;<br />
<br />
sitTargetHeight = newSize/2.3;<br />
<br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
<br />
integer link = 2;<br />
while (link < numlinks)<br />
{<br />
float heightOffset = (llList2Integer(offsetMultiplier,link-2) * (newSize/(panelDivisor * 4)));<br />
if (link%2 == 0)<br />
{ <br />
primColor = <0.75, 0.75, 0.75>;<br />
}<br />
else<br />
{<br />
primColor = <0.0, 0.0, 0.0>;<br />
} <br />
<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, heightOffset>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE,<br />
PRIM_COLOR, ALL_SIDES, primColor, 0.5 ]);<br />
link ++;<br />
} <br />
<br />
if (NaturalMode)<br />
{<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, 0.0>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE, <br />
PRIM_COLOR, ALL_SIDES, primColor, 0.0]);<br />
} <br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "OpenSimian Avatar scale is ready to use");<br />
MyLocation = llGetRootPosition(); <br />
MyRotation = llGetRootRotation(); <br />
setScaleDimensions(currentScaleSize); <br />
}<br />
<br />
touch_start(integer numTouches)<br />
{<br />
string mode = "Heroic";<br />
if(NaturalMode)<br />
mode = "Natural";<br />
<br />
menuStatusInfo = "\nCurrent mode : " + mode + "\nAvatar height: " + llGetSubString((string) currentScaleSize, 0, 4) +"(meters)\n \nMake a selection"; <br />
<br />
if (avatar != NULL_KEY)<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, heightButtons, heightchannel);<br />
llSetTimerEvent(menuTimeout); <br />
} <br />
else<br />
{ <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, menuButtons, menuchannel);<br />
llSetTimerEvent(menuTimeout);<br />
} <br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(channel == menuchannel)<br />
{<br />
llListenRemove(mListener);<br />
llSetTimerEvent(0);<br />
<br />
if (message == "Heroic")<br />
{<br />
if ( NaturalMode )<br />
{<br />
NaturalMode = FALSE;<br />
llSay(0,"Resetting to Heroic Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
else<br />
{<br />
llSay(0,"Already in Heroic Mode");<br />
}<br />
}<br />
<br />
if (message == "Natural")<br />
{<br />
if ( NaturalMode )<br />
{<br />
llSay(0,"Already in Natural Mode");<br />
}<br />
else<br />
{<br />
NaturalMode = TRUE;<br />
llSay(0,"Resetting to Natural Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
} <br />
<br />
if (message == "Set Height")<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llTextBox(id, "Enter the total Height of the avatar in METERS", heightchannel);<br />
}<br />
if (message == "Move Up")<br />
{<br />
sitTargetHeight += .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
if (message == "Move Down")<br />
{<br />
sitTargetHeight -= .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
} <br />
if(channel== heightchannel)<br />
{<br />
llListenRemove(cListener);<br />
setScaleDimensions((float) message); <br />
}<br />
}<br />
<br />
changed(integer change) <br />
{<br />
if(change & CHANGED_LINK) <br />
{<br />
avatar = llAvatarOnSitTarget();<br />
if(avatar != NULL_KEY)<br />
{<br />
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);<br />
}<br />
else<br />
{<br />
if (llGetPermissionsKey() != NULL_KEY)<br />
{ <br />
llStopAnimation(ANIMATION); <br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
avatar = NULL_KEY;<br />
}<br />
}<br />
}<br />
if(change & CHANGED_INVENTORY) { llResetScript(); }<br />
if(change & CHANGED_OWNER) { llResetScript(); }<br />
}<br />
<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION) {<br />
llStopAnimation("sit");<br />
llStartAnimation(ANIMATION);<br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(avatar, "Select an Option", heightButtons, menuchannel); <br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSay(0, "Menu selection time limit ( 30 seconds ) exceeded, please touch the scale again for a new menu");<br />
llListenRemove(mListener); <br />
llSetTimerEvent(0);<br />
}<br />
}<br />
</source ><br />
<br />
=== CheckProportions BVH file ===<br />
<br />
This is a very basic animation that stands the avatar upright with feet together and hands hanging down. <br />
It is a close enough match to the references included in the note card. <br />
You should be able to upload this file as an animation file and use it with most avatar models that the scale is appropriate for.<br />
The script expects the uploaded animation to be named "CheckProportions". Feel free to change it, but then you will also need to change the script.<br />
<br />
I recommend that you set the animation priority to 4 and set the animation to LOOP when uploaded. <br />
This will help insure it remains active while the avatar is on the scale.<br />
<br />
<source lang = "lsl"><br />
HIERARCHY<br />
ROOT hip<br />
{<br />
OFFSET 0.00 0.00 0.00 <br />
CHANNELS 6 Xposition Yposition Zposition Xrotation Zrotation Yrotation<br />
JOINT abdomen<br />
{<br />
OFFSET 0.000000 3.422050 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT chest<br />
{<br />
OFFSET 0.000000 8.486693 -0.684411<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT neck<br />
{<br />
OFFSET 0.000000 10.266162 -0.273764<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT head<br />
{<br />
OFFSET 0.000000 3.148285 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 3.148289 0.000000<br />
}<br />
}<br />
}<br />
JOINT lCollar<br />
{<br />
OFFSET 3.422053 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lShldr<br />
{<br />
OFFSET 3.285171 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT lForeArm<br />
{<br />
OFFSET 10.129278 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lHand<br />
{<br />
OFFSET 8.486692 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET 4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT rCollar<br />
{<br />
OFFSET -3.558935 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rShldr<br />
{<br />
OFFSET -3.148289 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT rForeArm<br />
{<br />
OFFSET -10.266159 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rHand<br />
{<br />
OFFSET -8.349810 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET -4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT lThigh<br />
{<br />
OFFSET 5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lShin<br />
{<br />
OFFSET -2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
JOINT rThigh<br />
{<br />
OFFSET -5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rShin<br />
{<br />
OFFSET 2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
}<br />
MOTION<br />
Frames: 1<br />
Frame Time: 0.5<br />
0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0<br />
<br />
<br />
<br />
</source ><br />
<br />
=== Information Notecard ===<br />
<br />
This is an optional add-on. It is not required, but I have included it to help explain the use to a novice user.<br />
I recommend that you at least READ through the note card before you attempt to use the scale for yourself.<br />
If you intend to re-distribute the scale, Please Please Please include this or something like it to minimize the support questions that may result.<br />
<br />
<source lang = "lsl"><br />
This is a BETA implementation of an avatar sizing scale<br />
It is designed to provide a simple scale with which you can measure the proportions of your avatar.<br />
<br />
There are 2 scale modes enabled. <br />
The default "Natural" mode is based on a 8 head scale. <br />
Realistic human avatars should be approximately 8 heads tall, and just under 2 heads wide.<br />
<br />
It also supports a "Heroic" mode based on a 9 head scale. <br />
Heroic avatars will have longer legs and should be wider at both the shoulders and hips. <br />
There are some studies that show this is considered more attractive in many western cultures.<br />
<br />
The scale has alternating Dark and Light "bars" in it to help you see the important locations..<br />
<br />
To use the scale, place it on a flat surface so that the base of the scale is close to the surface but not beneath it.<br />
Touch the scale and use the menu buttons to set the mode you desire (Default is Natural) , or select the [SET Height] button.<br />
Enter the desired avatar height ( in METERS) in the text box ( without hitting return, Use the submit button...). <br />
<br />
The scale should adjust its configuration or size and give you a message as it does so.<br />
<br />
DO NOT SIT ON THE SCALE UNTIL YOU HAVE SET THE PROPER MODE AND SIZE<br />
The scale will attempt to "guess" at, and set, a proper sit location. This will NOT work if you are already sitting..<br />
<br />
Once the scale has reset you can sit on the scale. There is an animation provided to pose you appropriately. <br />
You should be positioned in the middle of the base with the scale running up the middle of your avatar.<br />
Your feet should be close to the ground. <br />
<br />
Touch the scale again and use the {Move Up] or {Move Down] buttons to adjust your position until your feet are on the base.<br />
( Note) this BETA version of the scale has issues and you may see your avatar JUMP the first time you try to adjust.<br />
<br />
*********************************************<br />
<br />
What you SHOULD see if your "Natural" avatar is correctly proportioned<br />
<br />
The first (top) bar should go from the top of your head to the bottom of your chin.<br />
Your shoulders should be approximately the same width as the scale.<br />
Male nipples should be slightly above or at the bottom of the second bar.<br />
Female nipples should be slightly below the bottom of the second bar.<br />
Your "belly button" should be just under the third bar.<br />
Your crotch should be at the bottom of the fourth bar, 1/2 way down.<br />
Your wrists should also be in approximately the same place, 1/2 way down.<br />
Your knees should be above the 6th bar, at least 2 bars above the ground.<br />
Your Feet should be on the base.<br />
<br />
When using "Heroic" mode the following adjustments should be made..<br />
Both Male and Females nipples should appear just under the bottom of the second bar.<br />
Male crotch should be 1/4 - 1/3 of the way down from the top of the 5th bar.<br />
Knees should be under, instead of above, the bottom of the 6th bar.<br />
<br />
*******************************************<br />
Unfortunately, you will not be able to make avatar size adjustments while sitting on the scale.<br />
To adjust body size, you must stand, use [edit appearance] to make changes, and sit on the scale again to check.<br />
The scale is supposed to remember the adjustments you made, but you may have to adjust it again ( its BETA)<br />
********************************************<br />
<br />
As a rough guide, the following appearance parameters can be modified to achieve the best "fit"<br />
<br />
In the BODY section, use the HEIGHT slider.<br />
<br />
In the HEAD section, first use the HEAD SIZE slider, and then the HEAD STRETCH<br />
( you may want to play with the CHIN section sliders, but I recommend you come back to those later)<br />
<br />
In the TORSO section, Use SHOULDERS to set the shoulder width. <br />
(Muscular torsos will extend beyond the scale slightly)<br />
Use the ARM LENGTH slider to position your wrists<br />
Use the TORSO LENGTH slider to move your belly<br />
<br />
In the LEGS section, use LEG LENGTH to adjust the position of your knees and get your feet on the ground.<br />
Adjust HIP LENGTH to modify your belly button and crotch locations. <br />
<br />
<br />
************************************************<br />
<br />
Here are some web references to help you visualize the "landmarks" provided by the scale...<br />
<br />
http://www.idrawdigital.com/2009/01/drawing-tutorial-anatomy-and-proportion-1/<br />
<br />
http://www.3dhaze.com/tutorials/char_model/proportions.html<br />
<br />
http://www.pinterest.com/lillegerd/human-proportions/<br />
<br />
http://hpc.anatomy4sculptors.com/<br />
<br />
<br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/Avatar_Scale
User:Dz/Avatar Scale
2014-09-21T19:22:21Z
<p>Dz: /* CheckProportions BVH file */</p>
<hr />
<div>== Avatar Scale ==<br />
<br />
This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator.<br />
With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using<br />
the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even<br />
attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue<br />
experimenting and improving this important skill.<br />
<br />
Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results<br />
of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique<br />
I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic<br />
BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
The scale relies on the ability to move a seated avatar via script. <br />
This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release.<br />
It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/Avatar Scale]]<br />
<br />
<br />
=== The script ===<br />
<br />
I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it.<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// Avatar proportion scale BETA<br />
// based on an "8 head" (Natural) or "9 head" (Heroic) human shape<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
//<br />
// To create your own scale from scratch, <br />
// Make a cube to act as your base. Texture it as you like and turn it phantom.<br />
// Make 9 more cubes and stack them on top of each other. <br />
// Link the 9 cubes together and then link that stack to your "base" cube<br />
// Copy the [CheckPorportions] animation and the [Proportional Avatar Sizing} notecard into the base<br />
// Drop this script into your base cube. <br />
// Your stack of cubes should transform into a "Natural" scale for a 2 meter avatar<br />
//<br />
//<br />
<br />
vector MyLocation = <0,0,0>;<br />
rotation MyRotation = ZERO_ROTATION;<br />
<br />
list offsetMultiplier = [1,3,5,7,9,11,13,15,17];<br />
<br />
string ANIMATION = "CheckProportions";<br />
<br />
key avatar = NULL_KEY;<br />
list menuButtons = ["Heroic","Natural","Set Height"]; <br />
list heightButtons = [ "Move Up", "Move Down"];<br />
integer menuchannel = -13572468;<br />
integer heightchannel = -13572469;<br />
integer mListener = 0;<br />
integer cListener = 0;<br />
float sitTargetHeight = 0;<br />
integer NaturalMode = TRUE;<br />
string menuStatusInfo = "";<br />
float currentScaleSize = 2.0;<br />
float menuTimeout = 30.0;<br />
vector primColor = <0.0, 0.0, 0.0>;<br />
float panelDivisor = 4.0;<br />
float widthAdjust = 0.02;<br />
<br />
setScaleDimensions(float newSize)<br />
{<br />
integer numlinks = 11;<br />
panelDivisor = 4.5;<br />
widthAdjust = 0.05;<br />
<br />
if (NaturalMode)<br />
{<br />
numlinks = 10;<br />
panelDivisor = 4;<br />
widthAdjust = -0.025;<br />
}<br />
<br />
llSay(0, "Resizing scale for a " +(string) newSize + " meter avatar");<br />
<br />
currentScaleSize = newSize;<br />
<br />
sitTargetHeight = newSize/2.3;<br />
<br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
<br />
integer link = 2;<br />
while (link < numlinks)<br />
{<br />
float heightOffset = (llList2Integer(offsetMultiplier,link-2) * (newSize/(panelDivisor * 4)));<br />
if (link%2 == 0)<br />
{ <br />
primColor = <0.75, 0.75, 0.75>;<br />
}<br />
else<br />
{<br />
primColor = <0.0, 0.0, 0.0>;<br />
} <br />
<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, heightOffset>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE,<br />
PRIM_COLOR, ALL_SIDES, primColor, 0.5 ]);<br />
link ++;<br />
} <br />
<br />
if (NaturalMode)<br />
{<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, 0.0>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE, <br />
PRIM_COLOR, ALL_SIDES, primColor, 0.0]);<br />
} <br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "OpenSimian Avatar scale is ready to use");<br />
MyLocation = llGetRootPosition(); <br />
MyRotation = llGetRootRotation(); <br />
setScaleDimensions(currentScaleSize); <br />
}<br />
<br />
touch_start(integer numTouches)<br />
{<br />
string mode = "Heroic";<br />
if(NaturalMode)<br />
mode = "Natural";<br />
<br />
menuStatusInfo = "\nCurrent mode : " + mode + "\nAvatar height: " + llGetSubString((string) currentScaleSize, 0, 4) +"(meters)\n \nMake a selection"; <br />
<br />
if (avatar != NULL_KEY)<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, heightButtons, heightchannel);<br />
llSetTimerEvent(menuTimeout); <br />
} <br />
else<br />
{ <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, menuButtons, menuchannel);<br />
llSetTimerEvent(menuTimeout);<br />
} <br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(channel == menuchannel)<br />
{<br />
llListenRemove(mListener);<br />
llSetTimerEvent(0);<br />
<br />
if (message == "Heroic")<br />
{<br />
if ( NaturalMode )<br />
{<br />
NaturalMode = FALSE;<br />
llSay(0,"Resetting to Heroic Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
else<br />
{<br />
llSay(0,"Already in Heroic Mode");<br />
}<br />
}<br />
<br />
if (message == "Natural")<br />
{<br />
if ( NaturalMode )<br />
{<br />
llSay(0,"Already in Natural Mode");<br />
}<br />
else<br />
{<br />
NaturalMode = TRUE;<br />
llSay(0,"Resetting to Natural Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
} <br />
<br />
if (message == "Set Height")<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llTextBox(id, "Enter the total Height of the avatar in METERS", heightchannel);<br />
}<br />
if (message == "Move Up")<br />
{<br />
sitTargetHeight += .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
if (message == "Move Down")<br />
{<br />
sitTargetHeight -= .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
} <br />
if(channel== heightchannel)<br />
{<br />
llListenRemove(cListener);<br />
setScaleDimensions((float) message); <br />
}<br />
}<br />
<br />
changed(integer change) <br />
{<br />
if(change & CHANGED_LINK) <br />
{<br />
avatar = llAvatarOnSitTarget();<br />
if(avatar != NULL_KEY)<br />
{<br />
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);<br />
}<br />
else<br />
{<br />
if (llGetPermissionsKey() != NULL_KEY)<br />
{ <br />
llStopAnimation(ANIMATION); <br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
avatar = NULL_KEY;<br />
}<br />
}<br />
}<br />
if(change & CHANGED_INVENTORY) { llResetScript(); }<br />
if(change & CHANGED_OWNER) { llResetScript(); }<br />
}<br />
<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION) {<br />
llStopAnimation("sit");<br />
llStartAnimation(ANIMATION);<br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(avatar, "Select an Option", heightButtons, menuchannel); <br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSay(0, "Menu selection time limit ( 30 seconds ) exceeded, please touch the scale again for a new menu");<br />
llListenRemove(mListener); <br />
llSetTimerEvent(0);<br />
}<br />
}<br />
</source ><br />
<br />
=== CheckProportions BVH file ===<br />
<br />
This is a very basic animation that stands the avatar upright with feet together and hands hanging down. <br />
It is a close enough match to the references included in the note card. <br />
You should be able to upload this file as an animation file and use it with most avatar models that the scale is appropriate for.<br />
The script expects the uploaded animation to be named "CheckProportions". Feel free to change it, but then you will also need to change the script.<br />
<br />
I recommend that you set the animation priority to 4 and set the animation to LOOP when uploaded. <br />
This will help insure it remains active while the avatar is on the scale.<br />
<br />
<source lang = "lsl"><br />
HIERARCHY<br />
ROOT hip<br />
{<br />
OFFSET 0.00 0.00 0.00 <br />
CHANNELS 6 Xposition Yposition Zposition Xrotation Zrotation Yrotation<br />
JOINT abdomen<br />
{<br />
OFFSET 0.000000 3.422050 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT chest<br />
{<br />
OFFSET 0.000000 8.486693 -0.684411<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT neck<br />
{<br />
OFFSET 0.000000 10.266162 -0.273764<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT head<br />
{<br />
OFFSET 0.000000 3.148285 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 3.148289 0.000000<br />
}<br />
}<br />
}<br />
JOINT lCollar<br />
{<br />
OFFSET 3.422053 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lShldr<br />
{<br />
OFFSET 3.285171 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT lForeArm<br />
{<br />
OFFSET 10.129278 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lHand<br />
{<br />
OFFSET 8.486692 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET 4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT rCollar<br />
{<br />
OFFSET -3.558935 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rShldr<br />
{<br />
OFFSET -3.148289 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT rForeArm<br />
{<br />
OFFSET -10.266159 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rHand<br />
{<br />
OFFSET -8.349810 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET -4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT lThigh<br />
{<br />
OFFSET 5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lShin<br />
{<br />
OFFSET -2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
JOINT rThigh<br />
{<br />
OFFSET -5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rShin<br />
{<br />
OFFSET 2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
}<br />
MOTION<br />
Frames: 1<br />
Frame Time: 0.5<br />
0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0<br />
<br />
<br />
<br />
</source ><br />
<br />
=== Information Notecard ===<br />
<br />
This is an optional add-on. It is not required, but I have included it to help explain the use to a novice user.<br />
I recommend that you at least READ through the note card before you attempt to use the scale for yourself.<br />
If you intend to re-distribute the scale, Please Please Please include this or something like it to minimize the support questions that may result.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/Avatar_Scale
User:Dz/Avatar Scale
2014-09-21T19:19:49Z
<p>Dz: /* CheckProportions BVH file */</p>
<hr />
<div>== Avatar Scale ==<br />
<br />
This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator.<br />
With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using<br />
the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even<br />
attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue<br />
experimenting and improving this important skill.<br />
<br />
Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results<br />
of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique<br />
I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic<br />
BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
The scale relies on the ability to move a seated avatar via script. <br />
This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release.<br />
It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/Avatar Scale]]<br />
<br />
<br />
=== The script ===<br />
<br />
I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it.<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// Avatar proportion scale BETA<br />
// based on an "8 head" (Natural) or "9 head" (Heroic) human shape<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
//<br />
// To create your own scale from scratch, <br />
// Make a cube to act as your base. Texture it as you like and turn it phantom.<br />
// Make 9 more cubes and stack them on top of each other. <br />
// Link the 9 cubes together and then link that stack to your "base" cube<br />
// Copy the [CheckPorportions] animation and the [Proportional Avatar Sizing} notecard into the base<br />
// Drop this script into your base cube. <br />
// Your stack of cubes should transform into a "Natural" scale for a 2 meter avatar<br />
//<br />
//<br />
<br />
vector MyLocation = <0,0,0>;<br />
rotation MyRotation = ZERO_ROTATION;<br />
<br />
list offsetMultiplier = [1,3,5,7,9,11,13,15,17];<br />
<br />
string ANIMATION = "CheckProportions";<br />
<br />
key avatar = NULL_KEY;<br />
list menuButtons = ["Heroic","Natural","Set Height"]; <br />
list heightButtons = [ "Move Up", "Move Down"];<br />
integer menuchannel = -13572468;<br />
integer heightchannel = -13572469;<br />
integer mListener = 0;<br />
integer cListener = 0;<br />
float sitTargetHeight = 0;<br />
integer NaturalMode = TRUE;<br />
string menuStatusInfo = "";<br />
float currentScaleSize = 2.0;<br />
float menuTimeout = 30.0;<br />
vector primColor = <0.0, 0.0, 0.0>;<br />
float panelDivisor = 4.0;<br />
float widthAdjust = 0.02;<br />
<br />
setScaleDimensions(float newSize)<br />
{<br />
integer numlinks = 11;<br />
panelDivisor = 4.5;<br />
widthAdjust = 0.05;<br />
<br />
if (NaturalMode)<br />
{<br />
numlinks = 10;<br />
panelDivisor = 4;<br />
widthAdjust = -0.025;<br />
}<br />
<br />
llSay(0, "Resizing scale for a " +(string) newSize + " meter avatar");<br />
<br />
currentScaleSize = newSize;<br />
<br />
sitTargetHeight = newSize/2.3;<br />
<br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
<br />
integer link = 2;<br />
while (link < numlinks)<br />
{<br />
float heightOffset = (llList2Integer(offsetMultiplier,link-2) * (newSize/(panelDivisor * 4)));<br />
if (link%2 == 0)<br />
{ <br />
primColor = <0.75, 0.75, 0.75>;<br />
}<br />
else<br />
{<br />
primColor = <0.0, 0.0, 0.0>;<br />
} <br />
<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, heightOffset>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE,<br />
PRIM_COLOR, ALL_SIDES, primColor, 0.5 ]);<br />
link ++;<br />
} <br />
<br />
if (NaturalMode)<br />
{<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, 0.0>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE, <br />
PRIM_COLOR, ALL_SIDES, primColor, 0.0]);<br />
} <br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "OpenSimian Avatar scale is ready to use");<br />
MyLocation = llGetRootPosition(); <br />
MyRotation = llGetRootRotation(); <br />
setScaleDimensions(currentScaleSize); <br />
}<br />
<br />
touch_start(integer numTouches)<br />
{<br />
string mode = "Heroic";<br />
if(NaturalMode)<br />
mode = "Natural";<br />
<br />
menuStatusInfo = "\nCurrent mode : " + mode + "\nAvatar height: " + llGetSubString((string) currentScaleSize, 0, 4) +"(meters)\n \nMake a selection"; <br />
<br />
if (avatar != NULL_KEY)<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, heightButtons, heightchannel);<br />
llSetTimerEvent(menuTimeout); <br />
} <br />
else<br />
{ <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, menuButtons, menuchannel);<br />
llSetTimerEvent(menuTimeout);<br />
} <br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(channel == menuchannel)<br />
{<br />
llListenRemove(mListener);<br />
llSetTimerEvent(0);<br />
<br />
if (message == "Heroic")<br />
{<br />
if ( NaturalMode )<br />
{<br />
NaturalMode = FALSE;<br />
llSay(0,"Resetting to Heroic Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
else<br />
{<br />
llSay(0,"Already in Heroic Mode");<br />
}<br />
}<br />
<br />
if (message == "Natural")<br />
{<br />
if ( NaturalMode )<br />
{<br />
llSay(0,"Already in Natural Mode");<br />
}<br />
else<br />
{<br />
NaturalMode = TRUE;<br />
llSay(0,"Resetting to Natural Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
} <br />
<br />
if (message == "Set Height")<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llTextBox(id, "Enter the total Height of the avatar in METERS", heightchannel);<br />
}<br />
if (message == "Move Up")<br />
{<br />
sitTargetHeight += .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
if (message == "Move Down")<br />
{<br />
sitTargetHeight -= .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
} <br />
if(channel== heightchannel)<br />
{<br />
llListenRemove(cListener);<br />
setScaleDimensions((float) message); <br />
}<br />
}<br />
<br />
changed(integer change) <br />
{<br />
if(change & CHANGED_LINK) <br />
{<br />
avatar = llAvatarOnSitTarget();<br />
if(avatar != NULL_KEY)<br />
{<br />
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);<br />
}<br />
else<br />
{<br />
if (llGetPermissionsKey() != NULL_KEY)<br />
{ <br />
llStopAnimation(ANIMATION); <br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
avatar = NULL_KEY;<br />
}<br />
}<br />
}<br />
if(change & CHANGED_INVENTORY) { llResetScript(); }<br />
if(change & CHANGED_OWNER) { llResetScript(); }<br />
}<br />
<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION) {<br />
llStopAnimation("sit");<br />
llStartAnimation(ANIMATION);<br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(avatar, "Select an Option", heightButtons, menuchannel); <br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSay(0, "Menu selection time limit ( 30 seconds ) exceeded, please touch the scale again for a new menu");<br />
llListenRemove(mListener); <br />
llSetTimerEvent(0);<br />
}<br />
}<br />
</source ><br />
<br />
=== CheckProportions BVH file ===<br />
<br />
This is a very basic animation that stands the avatar upright with feet together and hands hanging down. <br />
It is a close enough match to the references included in the note card. <br />
You should be able to upload this file as an animation file and use it with most avatar models that the scale is appropriate for.<br />
The script expects the uploaded animation to be named "CheckProportions". Feel free to change it, but then you will also need to change the script.<br />
<br />
I recommend that you set the animation priority to 4 and set the animation to LOOP when uploaded. <br />
This will help insure it remains active while the avatar is on the scale.<br />
<br />
<source lang = "lsl"><br />
HIERARCHY<br />
ROOT hip<br />
{<br />
OFFSET 0.00 0.00 0.00 <br />
CHANNELS 6 Xposition Yposition Zposition Xrotation Zrotation Yrotation<br />
JOINT abdomen<br />
{<br />
OFFSET 0.000000 3.422050 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT chest<br />
{<br />
OFFSET 0.000000 8.486693 -0.684411<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT neck<br />
{<br />
OFFSET 0.000000 10.266162 -0.273764<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT head<br />
{<br />
OFFSET 0.000000 3.148285 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 3.148289 0.000000<br />
}<br />
}<br />
}<br />
JOINT lCollar<br />
{<br />
OFFSET 3.422053 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lShldr<br />
{<br />
OFFSET 3.285171 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT lForeArm<br />
{<br />
OFFSET 10.129278 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lHand<br />
{<br />
OFFSET 8.486692 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET 4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT rCollar<br />
{<br />
OFFSET -3.558935 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rShldr<br />
{<br />
OFFSET -3.148289 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT rForeArm<br />
{<br />
OFFSET -10.266159 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rHand<br />
{<br />
OFFSET -8.349810 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET -4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT lThigh<br />
{<br />
OFFSET 5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lShin<br />
{<br />
OFFSET -2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
JOINT rThigh<br />
{<br />
OFFSET -5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rShin<br />
{<br />
OFFSET 2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
}<br />
MOTION<br />
Frames: 1<br />
Frame Time: 0.5<br />
0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0<br />
<br />
</source ><br />
<br />
=== Information Notecard ===<br />
<br />
This is an optional add-on. It is not required, but I have included it to help explain the use to a novice user.<br />
I recommend that you at least READ through the note card before you attempt to use the scale for yourself.<br />
If you intend to re-distribute the scale, Please Please Please include this or something like it to minimize the support questions that may result.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/Avatar_Scale
User:Dz/Avatar Scale
2014-09-21T19:17:58Z
<p>Dz: added BVH animation content</p>
<hr />
<div>== Avatar Scale ==<br />
<br />
This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator.<br />
With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using<br />
the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even<br />
attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue<br />
experimenting and improving this important skill.<br />
<br />
Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results<br />
of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique<br />
I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic<br />
BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
The scale relies on the ability to move a seated avatar via script. <br />
This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release.<br />
It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/Avatar Scale]]<br />
<br />
<br />
=== The script ===<br />
<br />
I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it.<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// Avatar proportion scale BETA<br />
// based on an "8 head" (Natural) or "9 head" (Heroic) human shape<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
//<br />
// To create your own scale from scratch, <br />
// Make a cube to act as your base. Texture it as you like and turn it phantom.<br />
// Make 9 more cubes and stack them on top of each other. <br />
// Link the 9 cubes together and then link that stack to your "base" cube<br />
// Copy the [CheckPorportions] animation and the [Proportional Avatar Sizing} notecard into the base<br />
// Drop this script into your base cube. <br />
// Your stack of cubes should transform into a "Natural" scale for a 2 meter avatar<br />
//<br />
//<br />
<br />
vector MyLocation = <0,0,0>;<br />
rotation MyRotation = ZERO_ROTATION;<br />
<br />
list offsetMultiplier = [1,3,5,7,9,11,13,15,17];<br />
<br />
string ANIMATION = "CheckProportions";<br />
<br />
key avatar = NULL_KEY;<br />
list menuButtons = ["Heroic","Natural","Set Height"]; <br />
list heightButtons = [ "Move Up", "Move Down"];<br />
integer menuchannel = -13572468;<br />
integer heightchannel = -13572469;<br />
integer mListener = 0;<br />
integer cListener = 0;<br />
float sitTargetHeight = 0;<br />
integer NaturalMode = TRUE;<br />
string menuStatusInfo = "";<br />
float currentScaleSize = 2.0;<br />
float menuTimeout = 30.0;<br />
vector primColor = <0.0, 0.0, 0.0>;<br />
float panelDivisor = 4.0;<br />
float widthAdjust = 0.02;<br />
<br />
setScaleDimensions(float newSize)<br />
{<br />
integer numlinks = 11;<br />
panelDivisor = 4.5;<br />
widthAdjust = 0.05;<br />
<br />
if (NaturalMode)<br />
{<br />
numlinks = 10;<br />
panelDivisor = 4;<br />
widthAdjust = -0.025;<br />
}<br />
<br />
llSay(0, "Resizing scale for a " +(string) newSize + " meter avatar");<br />
<br />
currentScaleSize = newSize;<br />
<br />
sitTargetHeight = newSize/2.3;<br />
<br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
<br />
integer link = 2;<br />
while (link < numlinks)<br />
{<br />
float heightOffset = (llList2Integer(offsetMultiplier,link-2) * (newSize/(panelDivisor * 4)));<br />
if (link%2 == 0)<br />
{ <br />
primColor = <0.75, 0.75, 0.75>;<br />
}<br />
else<br />
{<br />
primColor = <0.0, 0.0, 0.0>;<br />
} <br />
<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, heightOffset>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE,<br />
PRIM_COLOR, ALL_SIDES, primColor, 0.5 ]);<br />
link ++;<br />
} <br />
<br />
if (NaturalMode)<br />
{<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, 0.0>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE, <br />
PRIM_COLOR, ALL_SIDES, primColor, 0.0]);<br />
} <br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "OpenSimian Avatar scale is ready to use");<br />
MyLocation = llGetRootPosition(); <br />
MyRotation = llGetRootRotation(); <br />
setScaleDimensions(currentScaleSize); <br />
}<br />
<br />
touch_start(integer numTouches)<br />
{<br />
string mode = "Heroic";<br />
if(NaturalMode)<br />
mode = "Natural";<br />
<br />
menuStatusInfo = "\nCurrent mode : " + mode + "\nAvatar height: " + llGetSubString((string) currentScaleSize, 0, 4) +"(meters)\n \nMake a selection"; <br />
<br />
if (avatar != NULL_KEY)<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, heightButtons, heightchannel);<br />
llSetTimerEvent(menuTimeout); <br />
} <br />
else<br />
{ <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, menuButtons, menuchannel);<br />
llSetTimerEvent(menuTimeout);<br />
} <br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(channel == menuchannel)<br />
{<br />
llListenRemove(mListener);<br />
llSetTimerEvent(0);<br />
<br />
if (message == "Heroic")<br />
{<br />
if ( NaturalMode )<br />
{<br />
NaturalMode = FALSE;<br />
llSay(0,"Resetting to Heroic Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
else<br />
{<br />
llSay(0,"Already in Heroic Mode");<br />
}<br />
}<br />
<br />
if (message == "Natural")<br />
{<br />
if ( NaturalMode )<br />
{<br />
llSay(0,"Already in Natural Mode");<br />
}<br />
else<br />
{<br />
NaturalMode = TRUE;<br />
llSay(0,"Resetting to Natural Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
} <br />
<br />
if (message == "Set Height")<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llTextBox(id, "Enter the total Height of the avatar in METERS", heightchannel);<br />
}<br />
if (message == "Move Up")<br />
{<br />
sitTargetHeight += .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
if (message == "Move Down")<br />
{<br />
sitTargetHeight -= .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
} <br />
if(channel== heightchannel)<br />
{<br />
llListenRemove(cListener);<br />
setScaleDimensions((float) message); <br />
}<br />
}<br />
<br />
changed(integer change) <br />
{<br />
if(change & CHANGED_LINK) <br />
{<br />
avatar = llAvatarOnSitTarget();<br />
if(avatar != NULL_KEY)<br />
{<br />
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);<br />
}<br />
else<br />
{<br />
if (llGetPermissionsKey() != NULL_KEY)<br />
{ <br />
llStopAnimation(ANIMATION); <br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
avatar = NULL_KEY;<br />
}<br />
}<br />
}<br />
if(change & CHANGED_INVENTORY) { llResetScript(); }<br />
if(change & CHANGED_OWNER) { llResetScript(); }<br />
}<br />
<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION) {<br />
llStopAnimation("sit");<br />
llStartAnimation(ANIMATION);<br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(avatar, "Select an Option", heightButtons, menuchannel); <br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSay(0, "Menu selection time limit ( 30 seconds ) exceeded, please touch the scale again for a new menu");<br />
llListenRemove(mListener); <br />
llSetTimerEvent(0);<br />
}<br />
}<br />
</source ><br />
<br />
=== CheckProportions BVH file ===<br />
<br />
This is a very basic animation that stands the avatar upright with feet together and hands hanging down. <br />
It is a close enough match to the references included in the note card. <br />
You should be able to upload this file as an animation file and use it with most avatar models that the scale is appropriate for.<br />
The script expects the uploaded animation to be named "CheckProportions". Feel free to change it, but then you will also need to change the script.<br />
<br />
I recommend that you set the animation priority to 4 and set the animation to LOOP when uploaded. <br />
This will help insure it remains active while the avatar is on the scale.<br />
<br />
<source lang = "lsl"><br />
HIERARCHY<br />
ROOT hip<br />
{<br />
OFFSET 0.00 0.00 0.00 <br />
CHANNELS 6 Xposition Yposition Zposition Xrotation Zrotation Yrotation<br />
JOINT abdomen<br />
{<br />
OFFSET 0.000000 3.422050 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT chest<br />
{<br />
OFFSET 0.000000 8.486693 -0.684411<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT neck<br />
{<br />
OFFSET 0.000000 10.266162 -0.273764<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT head<br />
{<br />
OFFSET 0.000000 3.148285 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 3.148289 0.000000<br />
}<br />
}<br />
}<br />
JOINT lCollar<br />
{<br />
OFFSET 3.422053 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lShldr<br />
{<br />
OFFSET 3.285171 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT lForeArm<br />
{<br />
OFFSET 10.129278 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT lHand<br />
{<br />
OFFSET 8.486692 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET 4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT rCollar<br />
{<br />
OFFSET -3.558935 6.707223 -0.821293<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rShldr<br />
{<br />
OFFSET -3.148289 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
JOINT rForeArm<br />
{<br />
OFFSET -10.266159 0.000000 0.000000<br />
CHANNELS 3 Yrotation Zrotation Xrotation<br />
JOINT rHand<br />
{<br />
OFFSET -8.349810 0.000000 0.000000<br />
CHANNELS 3 Zrotation Yrotation Xrotation<br />
End Site<br />
{<br />
OFFSET -4.106464 0.000000 0.000000<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
JOINT lThigh<br />
{<br />
OFFSET 5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lShin<br />
{<br />
OFFSET -2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT lFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
JOINT rThigh<br />
{<br />
OFFSET -5.338403 -1.642589 1.368821<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rShin<br />
{<br />
OFFSET 2.053232 -20.121670 0.000000<br />
CHANNELS 3 Xrotation Zrotation Yrotation<br />
JOINT rFoot<br />
{<br />
OFFSET 0.000000 -19.300380 -1.231939<br />
CHANNELS 3 Xrotation Yrotation Zrotation<br />
End Site<br />
{<br />
OFFSET 0.000000 -2.463878 4.653993<br />
}<br />
}<br />
}<br />
}<br />
}<br />
MOTION<br />
Frames: 1<br />
Frame Time: 0.5<br />
0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 88.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0<br />
</source ><br />
<br />
=== Information Notecard ===<br />
<br />
This is an optional add-on. It is not required, but I have included it to help explain the use to a novice user.<br />
I recommend that you at least READ through the note card before you attempt to use the scale for yourself.<br />
If you intend to re-distribute the scale, Please Please Please include this or something like it to minimize the support questions that may result.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/Avatar_Scale
User:Dz/Avatar Scale
2014-09-21T19:13:46Z
<p>Dz: Added latest version of the actual code</p>
<hr />
<div>== Avatar Scale ==<br />
<br />
This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator.<br />
With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using<br />
the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even<br />
attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue<br />
experimenting and improving this important skill.<br />
<br />
Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results<br />
of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique<br />
I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic<br />
BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
The scale relies on the ability to move a seated avatar via script. <br />
This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release.<br />
It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/Avatar Scale]]<br />
<br />
<br />
=== The script ===<br />
<br />
I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it.<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
// Avatar proportion scale BETA<br />
// based on an "8 head" (Natural) or "9 head" (Heroic) human shape<br />
<br />
// Doug Osborn MOSES grid 9/17/2014<br />
// Copyright (c) 2014, Douglas Osborn<br />
// All rights reserved.<br />
<br />
// Redistribution and use in source and binary forms, with or without<br />
// modification, are permitted provided that the following conditions are met:<br />
<br />
// 1. Redistributions of source code must retain the above copyright notice, this<br />
// list of conditions and the following disclaimer. <br />
// 2. Redistributions in binary form must reproduce the above copyright notice,<br />
// this list of conditions and the following disclaimer in the documentation<br />
// and/or other materials provided with the distribution.<br />
<br />
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND<br />
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE<br />
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR<br />
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES<br />
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;<br />
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND<br />
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br />
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS <br />
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <br />
<br />
//<br />
// To create your own scale from scratch, <br />
// Make a cube to act as your base. Texture it as you like and turn it phantom.<br />
// Make 9 more cubes and stack them on top of each other. <br />
// Link the 9 cubes together and then link that stack to your "base" cube<br />
// Copy the [CheckPorportions] animation and the [Proportional Avatar Sizing} notecard into the base<br />
// Drop this script into your base cube. <br />
// Your stack of cubes should transform into a "Natural" scale for a 2 meter avatar<br />
//<br />
//<br />
<br />
vector MyLocation = <0,0,0>;<br />
rotation MyRotation = ZERO_ROTATION;<br />
<br />
list offsetMultiplier = [1,3,5,7,9,11,13,15,17];<br />
<br />
string ANIMATION = "CheckProportions";<br />
<br />
key avatar = NULL_KEY;<br />
list menuButtons = ["Heroic","Natural","Set Height"]; <br />
list heightButtons = [ "Move Up", "Move Down"];<br />
integer menuchannel = -13572468;<br />
integer heightchannel = -13572469;<br />
integer mListener = 0;<br />
integer cListener = 0;<br />
float sitTargetHeight = 0;<br />
integer NaturalMode = TRUE;<br />
string menuStatusInfo = "";<br />
float currentScaleSize = 2.0;<br />
float menuTimeout = 30.0;<br />
vector primColor = <0.0, 0.0, 0.0>;<br />
float panelDivisor = 4.0;<br />
float widthAdjust = 0.02;<br />
<br />
setScaleDimensions(float newSize)<br />
{<br />
integer numlinks = 11;<br />
panelDivisor = 4.5;<br />
widthAdjust = 0.05;<br />
<br />
if (NaturalMode)<br />
{<br />
numlinks = 10;<br />
panelDivisor = 4;<br />
widthAdjust = -0.025;<br />
}<br />
<br />
llSay(0, "Resizing scale for a " +(string) newSize + " meter avatar");<br />
<br />
currentScaleSize = newSize;<br />
<br />
sitTargetHeight = newSize/2.3;<br />
<br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
<br />
integer link = 2;<br />
while (link < numlinks)<br />
{<br />
float heightOffset = (llList2Integer(offsetMultiplier,link-2) * (newSize/(panelDivisor * 4)));<br />
if (link%2 == 0)<br />
{ <br />
primColor = <0.75, 0.75, 0.75>;<br />
}<br />
else<br />
{<br />
primColor = <0.0, 0.0, 0.0>;<br />
} <br />
<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, heightOffset>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE,<br />
PRIM_COLOR, ALL_SIDES, primColor, 0.5 ]);<br />
link ++;<br />
} <br />
<br />
if (NaturalMode)<br />
{<br />
llSetLinkPrimitiveParamsFast( link,[PRIM_SIZE, < newSize/panelDivisor + widthAdjust ,0.02, newSize/(panelDivisor * 2)>, <br />
PRIM_POS_LOCAL,<0.0 , 0.0, 0.0>,<br />
PRIM_ROT_LOCAL,MyRotation, PRIM_PHANTOM,TRUE, <br />
PRIM_COLOR, ALL_SIDES, primColor, 0.0]);<br />
} <br />
}<br />
<br />
default<br />
{<br />
state_entry()<br />
{<br />
llSay(0, "OpenSimian Avatar scale is ready to use");<br />
MyLocation = llGetRootPosition(); <br />
MyRotation = llGetRootRotation(); <br />
setScaleDimensions(currentScaleSize); <br />
}<br />
<br />
touch_start(integer numTouches)<br />
{<br />
string mode = "Heroic";<br />
if(NaturalMode)<br />
mode = "Natural";<br />
<br />
menuStatusInfo = "\nCurrent mode : " + mode + "\nAvatar height: " + llGetSubString((string) currentScaleSize, 0, 4) +"(meters)\n \nMake a selection"; <br />
<br />
if (avatar != NULL_KEY)<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, heightButtons, heightchannel);<br />
llSetTimerEvent(menuTimeout); <br />
} <br />
else<br />
{ <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(llDetectedKey(0), menuStatusInfo, menuButtons, menuchannel);<br />
llSetTimerEvent(menuTimeout);<br />
} <br />
}<br />
<br />
listen(integer channel, string name, key id, string message)<br />
{<br />
if(channel == menuchannel)<br />
{<br />
llListenRemove(mListener);<br />
llSetTimerEvent(0);<br />
<br />
if (message == "Heroic")<br />
{<br />
if ( NaturalMode )<br />
{<br />
NaturalMode = FALSE;<br />
llSay(0,"Resetting to Heroic Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
else<br />
{<br />
llSay(0,"Already in Heroic Mode");<br />
}<br />
}<br />
<br />
if (message == "Natural")<br />
{<br />
if ( NaturalMode )<br />
{<br />
llSay(0,"Already in Natural Mode");<br />
}<br />
else<br />
{<br />
NaturalMode = TRUE;<br />
llSay(0,"Resetting to Natural Mode");<br />
setScaleDimensions(currentScaleSize); <br />
}<br />
} <br />
<br />
if (message == "Set Height")<br />
{<br />
cListener = llListen( heightchannel, "", "", ""); <br />
llTextBox(id, "Enter the total Height of the avatar in METERS", heightchannel);<br />
}<br />
if (message == "Move Up")<br />
{<br />
sitTargetHeight += .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
if (message == "Move Down")<br />
{<br />
sitTargetHeight -= .025;<br />
llSetLinkPrimitiveParams(llGetNumberOfPrims(),[PRIM_POS_LOCAL,<0,0,sitTargetHeight>]); <br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(id, "Select an Option", heightButtons, menuchannel); <br />
}<br />
} <br />
if(channel== heightchannel)<br />
{<br />
llListenRemove(cListener);<br />
setScaleDimensions((float) message); <br />
}<br />
}<br />
<br />
changed(integer change) <br />
{<br />
if(change & CHANGED_LINK) <br />
{<br />
avatar = llAvatarOnSitTarget();<br />
if(avatar != NULL_KEY)<br />
{<br />
llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION);<br />
}<br />
else<br />
{<br />
if (llGetPermissionsKey() != NULL_KEY)<br />
{ <br />
llStopAnimation(ANIMATION); <br />
llSitTarget(< 0,0,sitTargetHeight>,MyRotation*llEuler2Rot(<0,0,PI_BY_TWO>));<br />
avatar = NULL_KEY;<br />
}<br />
}<br />
}<br />
if(change & CHANGED_INVENTORY) { llResetScript(); }<br />
if(change & CHANGED_OWNER) { llResetScript(); }<br />
}<br />
<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if(perm & PERMISSION_TRIGGER_ANIMATION) {<br />
llStopAnimation("sit");<br />
llStartAnimation(ANIMATION);<br />
mListener = llListen( menuchannel, "", "", ""); <br />
llDialog(avatar, "Select an Option", heightButtons, menuchannel); <br />
}<br />
}<br />
<br />
timer()<br />
{<br />
llSay(0, "Menu selection time limit ( 30 seconds ) exceeded, please touch the scale again for a new menu");<br />
llListenRemove(mListener); <br />
llSetTimerEvent(0);<br />
}<br />
}<br />
</source ><br />
<br />
=== CheckProportions BVH file ===<br />
<br />
This is a very basic animation that stands the avatar upright with feet together and hands hanging down. <br />
It is a close enough match to the references included in the note card. <br />
You should be able to upload this file as an animation file and use it with most avatar models that the scale is appropriate for.<br />
The script expects the uploaded animation to be named "CheckProportions". Feel free to change it, but then you will also need to change the script.<br />
<br />
I recommend that you set the animation priority to 4 and set the animation to LOOP when uploaded. <br />
This will help insure it remains active while the avatar is on the scale.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ><br />
<br />
=== Information Notecard ===<br />
<br />
This is an optional add-on. It is not required, but I have included it to help explain the use to a novice user.<br />
I recommend that you at least READ through the note card before you attempt to use the scale for yourself.<br />
If you intend to re-distribute the scale, Please Please Please include this or something like it to minimize the support questions that may result.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/Avatar_Scale
User:Dz/Avatar Scale
2014-09-21T19:12:19Z
<p>Dz: Added script, animation, and note card information sections</p>
<hr />
<div>== Avatar Scale ==<br />
<br />
This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator.<br />
With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using<br />
the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even<br />
attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue<br />
experimenting and improving this important skill.<br />
<br />
Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results<br />
of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique<br />
I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic<br />
BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
The scale relies on the ability to move a seated avatar via script. <br />
This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release.<br />
It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/Avatar Scale]]<br />
<br />
<br />
=== The script ===<br />
<br />
I'm not going to write a lot about this script. It is relatively simple and I haven't really spent a ton of time refining it.<br />
Read the comments for information about use and distribution..<br />
<br />
<source lang = "lsl"><br />
<br />
</source ><br />
<br />
=== CheckProportions BVH file ===<br />
<br />
This is a very basic animation that stands the avatar upright with feet together and hands hanging down. <br />
It is a close enough match to the references included in the note card. <br />
You should be able to upload this file as an animation file and use it with most avatar models that the scale is appropriate for.<br />
The script expects the uploaded animation to be named "CheckProportions". Feel free to change it, but then you will also need to change the script.<br />
<br />
I recommend that you set the animation priority to 4 and set the animation to LOOP when uploaded. <br />
This will help insure it remains active while the avatar is on the scale.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ><br />
<br />
=== Information Notecard ===<br />
<br />
This is an optional add-on. It is not required, but I have included it to help explain the use to a novice user.<br />
I recommend that you at least READ through the note card before you attempt to use the scale for yourself.<br />
If you intend to re-distribute the scale, Please Please Please include this or something like it to minimize the support questions that may result.<br />
<br />
<source lang = "lsl"><br />
<br />
</source ></div>
Dz
http://opensimulator.org/wiki/User:Dz/Avatar_Scale
User:Dz/Avatar Scale
2014-09-21T18:55:45Z
<p>Dz: Created base page and project summary info</p>
<hr />
<div>== Avatar Scale ==<br />
<br />
This project was the result of a recent discussion on the difficulty of creating realistically proportioned avatars in OpenSimulator.<br />
With 7 years of experience "tweaking" my own shapes, and helping friends with "body makeovers", it is clear that the process of using<br />
the sliders in [edit appearance] to create a reasonable shape is not a simple task for most. Being able to generate realistic or even<br />
attractive shapes can be frustrating, and new users who are "stuck" using avatars they think look "weird" are less likely to continue<br />
experimenting and improving this important skill.<br />
<br />
Unfortunately, I cannot change the process of how avatar shapes are modified, But what I can give you is a way to measure the results<br />
of your shape changing efforts. This scale is not the "silver bullet" to making attractive avatars, but it has been a useful technique<br />
I have used to generate the "rough shapes" I build my avatars around. This project consist of 3 parts. An LSL script, a very basic<br />
BVH animation file, and a note card describing the features and some web references that might be useful for future investigation.<br />
<br />
As with all OpenSimian projects posted here, You are free to copy/modify/and IMPROVE the functionality to fit your needs.<br />
<br />
The scale relies on the ability to move a seated avatar via script. <br />
This functionality has been the focus of a number of MANTIS reports, and may not be working unless you are using a very recent release.<br />
It is still possible to use the script but you will have to edit the script and adjust the calculation that sets the initial sit position.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/Avatar Scale]]</div>
Dz
http://opensimulator.org/wiki/User:Dz
User:Dz
2014-09-21T18:34:48Z
<p>Dz: Added reference to Avatar Scale page</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Welcome to the OpenSimulator Space of dz ==<br />
<br />
I am generally involved in running OpenSim instances for fun, but I have been induced to try it for profit and the pursuit of scholarly credits.<br />
<br />
I am an incessant lurker...It took me 2 years to add these 3 lines to my profile here.<br />
<br />
I monitor the following OpenSimulator mailing-lists Opensim-Users, OpenSim-devs, libomv-dev. <br />
I can also be found lurking in the SL opensim group chat.<br />
<br />
I have been administering Linux based OpenSim servers since release 6.1, mostly on Ubuntu.<br />
I have active avatars on OSGrid, ScienceSim, Inworldz, and that "SL" place.<br />
<br />
<br />
<br />
----<br />
<br />
== NPC Utilities ==<br />
<br />
[[User:Dz/NPC Scripts]] Has the Latest NPC utilities<br />
<br />
<br />
== Animation overrides ==<br />
<br />
[[User:Dz/AO]] Has the Latest Animation Overrides designed for OpenSimulator<br />
<br />
<br />
== Avatar Proportion Scale ==<br />
<br />
[[User:Dz/Avatar Scale]] A simple scale to help you create more realistic avatar shapes</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-31T05:21:06Z
<p>Dz: /* Animation Override scripts */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This is an example of an AO script designed for use in OpenSimulator. These instructions describe how to make your own AO from scratch.<br />
<br />
For this example, I use animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. <br />
<br />
The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Step 1. Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Step 2. Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Step 3. Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Step 5. Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Step 6. Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Step 7. Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Step 8. Attach it to one of your HUD positions ... <br />
<br />
Step 9. Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour versus 6000 events using the modified script...<br />
<br />
In OpenSimulator, the design can be much more efficient. The developers have added a CHANGED_ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the script with the one you saved in step 2 above.</div>
Dz
http://opensimulator.org/wiki/Development_Team
Development Team
2014-01-27T05:26:51Z
<p>Dz: /* Additional Developers/Testers/Contributors */</p>
<hr />
<div>__NOTOC__ {{Quicklinks}} <br />
<br />
== Active Core Developers ==<br />
<br />
Developers who have commit access to our central server, are [http://www.ohloh.net/projects/4753/contributors regular contributors] to the codebase, and have voting rights over development and process issues of the OpenSimulator project. See [[Organization]]. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Adam Frisby|Adam Frisby]] <br />
| Adam Frisby <br />
| Adam Zaius <br />
| <br />
| +8 <br />
| DeepThink Pty Ltd <br />
| Terrain, Performance<br />
|-<br />
| [[User:Chi11ken|chi11ken]] <br />
| Jeff Ames <br />
| Chillken Proto <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Justincc|justincc]] <br />
| Justin Clark-Casey <br />
| Lulworth Beaumont <br />
| Justin Clark-Casey (all other grids) <br />
| 0 <br />
| OSVW Consulting<br />[http://justincc.org/blog justincc's OpenSimulator blog] <br />
| Grid, performance &amp; reliability, inventory (avatar and object), assets, scenes, OARs, etc. Generally speaking, my main interest is to create infrastructure that other people can build on top of.<br />
|-<br />
| [[User:Dahlia|dahlia]] <br />
| T. Hoff <br />
| Dahlia Trimble <br />
| <br />
| -8 / -7 <br />
| Independent <br />
| Collision geometry, various math and physics issues, occasional bug fixes and random enhancements<br />
|-<br />
| [[User:Melanie T|Melanie_T]] <br />
| Melanie <br />
| Melanie Milland <br />
| <br /> <br />
| +1 <br />
| Independent <br />
| Scripting, Prims/Scene, Life, The Universe, and Everything<br />
|-<br />
| [[User:Diva|Diva]] <br />
| Crista Lopes <br />
| Diva Canto <br />
| Crista Lopes / Diva Canto <br />
| -8 <br />
| University of California, Irvine <br />
| Everything, except databases<br />
|-<br />
| [[User:Dslake|dslake]] <br />
| Dan Lake <br />
| Dan Lake <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| Scalability, Performance, Network stack<br />
|-<br />
| [[User:Marck|Marck00]] <br />
| M. Kirsch <br />
| Marck Kjeller <br />
| <br />
| +1 <br />
| Independent <br />
| Everything that catches my attention and that I can get my head around. <br />
| <br />
|-<br />
| cmickeyb <br />
| Mic Bowman <br />
| Mic Bowman <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| <br />
|-<br />
| [[User:BlueWall|BlueWall]] <br />
| James Hughes <br />
| BlueWall Slade <br />
| BlueWall Slade <br />
| -5 <br />
| BlueWall Information Technologies, LLC <br />
| Various parts<br />
|-<br />
| [[User:Nebadon|Nebadon]] <br />
| Michael Emory Cerquoni <br />
| Nebadon Izumi <br />
| Nebadon Izumi <br />
| -7 Arizona <br />
| Oni Kenkon Creations <br />
| Building, Scripting, Testing<br />
|-<br />
| [[User:Snoopy2|Snoopy2]] <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
|<br />
| [http://www.dreamlandmetaverse.com/ http://www.dreamlandmetaverse.com/] <br />
| OpenSim region and grid hosting<br />
|-<br />
| radams<br />
| Robert Adams<br />
| <br />
| <br />
| <br />
| Looking Glass Viewer <br />
| <br />
|}<br />
<br />
<br /><br />
<br />
== Core Developers Following the White Rabbit ==<br />
<br />
Core developers who have temporarily (we hope) gone chasing the white rabbit. They are in all similar to the active core developers, except that they haven't been that active lately, so their voting rights are awaiting their come back. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Lbsa71|lbsa71]] <br />
| Stefan Andersson <br />
| Tribal Skytower <br />
| OSG:Stefan Andersson<br />TN:Stefan Andersson <br />
| +1 <br />
| [http://tribalmedia.se/ Tribal Media AB] <br />
| Web Integration<br />
|-<br />
| [[User:MW|MW]] <br />
| Darren <br />
| Wright Juran <br />
| <br />
| 0 <br />
| <br />
| Everything<br />
|-<br />
| ckrinke <br />
| Charles&nbsp;Krinke <br />
| Charlesk&nbsp;Bing <br />
| <br />
| -8 <br />
| &nbsp; <br />
| Reliability/Grid servers/ll-functions<br />
|-<br />
| [[User:Mikem|mikem]] <br />
| Mike Mazur <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| Independent <br />
| Patches, scripting improvements, LSL compiler<br />
|-<br />
| [[User:HomerHorwitz|homerh]] <br />
| Homer Horwitz <br />
| Homer Horwitz <br />
| <br /> <br />
| +2 <br />
| Independent <br />
| Rev. engineering, "now, that's funny" problems, but still interested in all parts of it<br />
|-<br />
| [[User:Nlin|nlin]] <br />
| N Lin <br />
| Standard Drucker <br />
| <br /> <br />
| +9 <br />
| [http://www.3di.jp/en/ 3Di Inc, Japan]<br />http://www.3di.jp/en/ <br />
| Physics, scripting, more to come<br />
|-<br />
| [[User:Arthursv|arthursv]] <br />
| Arthur Valadares <br />
| <br />
| NONE <br />
| -8 <br />
| University of California, Irvine <br />
| Unit testing, database plugins, bug fixes, general<br />
|-<br />
| [[User:DrScofield|drscofld]] <br />
| Dirk Husemann <br />
| Dr Scofield <br />
| <br />
| +1 <br />
| [http://xyzzyxyzzy.net/ xyzzyxyzzy.net] <br />
| Reliability, networking protocols, inventory, assets, remote control, voice, and pretty much everything else&nbsp;:-) <br />
| <br />
|-<br />
| [[User:Teravus|Teravus]] <br />
| Daniel Olivares <br />
| Teravus Ousley <br />
| <br />
| -5 <br />
| W3z <br />
| Physics &amp; Admin tools, A working sim.<br />
|}<br />
<br />
== Retired Core Developers ==<br />
<br />
Core developers who have transcended our mortal plane, i.e. they are no longer directly engaged with the project. Thank you forever for your contributions! <br />
<br />
* '''Only formerly voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Babblefrog|babblefrog]] <br />
| Brian McBee <br />
| Dogen Coldstream <br />
| Babblefrog Ballistic (osgrid) <br />
| -8 <br />
| Disorganized <br />
| &nbsp;<br />
|-<br />
| [[User:Danx0r|danx0r]] <br />
| Dan Miller <br />
| Albert Pascal <br />
| <br />
| -8 <br />
| squiggle.com <br />
| PHEEZIKS; everything<br />
|-<br />
| Tleiades <br />
| &nbsp; <br />
| Tleiades&nbsp;Hax <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Grid servers/Database<br />
|-<br />
| [[User:Darok|Darok]] <br />
| &nbsp; <br />
| Darok Kaminski <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Physics engines (especially BulletX)<br />
|-<br />
| Gareth / Gwen <br />
| Gareth Nelson <br />
| Gareth Ellison <br />
| Gareth Nelson (on everywhere but SL) <br />
| BST (UTC+1) <br />
| Litesim Ltd <br />
| Grid servers, sim border crossing, avatar animations<br />
|-<br />
| [[User:Dalien|dalien]] <br />
| Dalien Talbot <br />
| Dalien Talbot <br />
| <br />
| +1 <br />
| Mostly TCP-based <br />
| Small fixes; rev.eng./prototyping; nightlies; git-keeper<br />
|-<br />
| [[Alondria]] <br />
| <br />
| Alondria LeFay <br />
| Alondria LeFay (OSGrid) <br />
| -8 <br />
| Independent <br />
| Implementation of LSL functions and other scripting tidbits.<br />
|-<br />
| [[User:SeanDague|sdague]] <br />
| Sean Dague <br />
| Neas Bade <br />
| <br />
| -5 <br />
| IBM <br />
| Database, Linux, Testing, Misc<br />
|-<br />
| [[User:MingChen|MingChen]] <br />
| Mike/Michael Ortman <br />
| Ming Chen <br />
| <br />
| -6 (-5 in Summer) <br />
| DeepThink Pty Ltd <br />
| Estate/Parcel Support/Modules/Keeping things all neat and tidy.<br />
|-<br />
| [[User:Tedd|Tedd]] <br />
| Tedd Hansen <br />
| Tedd Maa <br />
| <br />
| +1 <br />
| Tedd Hansen <br />
| Programming/Scripting/Architecture<br />
|-<br />
| [[User:Adjohn|adjohn]] <br />
| Adam Johnson <br />
| Zeuz Zenovka <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Joha1|joha1]] <br />
| Johan Berntsson <br />
| Joppi Brandenburg <br />
| <br /> <br />
| +9 <br />
| &nbsp; <br />
| Performance, packet handling/libSL<br />
|-<br />
| jhurliman <br />
| John Hurliman <br />
| John Hurliman <br />
| <br />
| <br />
| <br />
|}<br />
<br />
== Wiki Sysops ==<br />
<br />
Along with the core developers, these people help manage the OpenSimulator wiki as well as make other contributions (see Areas of Interest). <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Makopoppo|Makopoppo]] <br />
| Makiko Nomura <br />
| Mako Nozaki <br />
| Everywhere <br />
| +9 Tokyo, Japan <br />
| As an individual developer <br />
| Everything for improving usability and connectability - wiki/issue management, documentation, localization(Japanese), modifying the interface mainly of core modules<br />
|-<br />
| [[User:Fritigern|Fritigern]] <br />
| S-E-C-R-E-T <br />
| Fritigern Gothly <br />
| SecondLife, OSGrid <br />
| +1 GMT <br />
| <br />
| My interests are many, and extremely varied. One thing that i am very interested in, is seeing OpenSimulator grow, mature, and develop into something that really does rival SL/LL.<br />
|}<br />
<br />
== Additional Developers/Testers/Contributors ==<br />
<br />
These people have contributed and/or are contributing bug reports, patches, testing, and all sorts of other goodies to the project. <br /> '''Newcomers please add yourself to bottom of the list!''' <br /> <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Jtclark48|jclark4]] <br />
| Jay Clark <br />
| Jay Clarke <br />
| <br />
| -5 <br />
| IBM <br />
| Physics, Grid Host, AI, Scripting, Testing<br />
|-<br />
| [[User:AdamStevenson|BigFootAg]] <br />
| Adam Stevenson <br />
| Adamus Petrov <br />
| <br />
| -6 <br />
| Texas A&amp;M University <br />
| AI, Skynet, Evolving Systems, Biology<br />
|-<br />
| [[User:Jeff1564|Jeff1564]] <br />
| Jeff <br />
| Potter Taurog <br />
| Potter Taurog <br />
| -8 <br />
| http://myopengrid.com <br />
| Building, Scripting, Testing<br />
|-<br />
| Rock_Vacirca <br />
| Colin Withers <br />
| Rock Vacirca <br />
| &nbsp; <br />
| +1 <br />
| http://rock-vacirca.blogspot.com <br />
| Testing, building, scripting, maintaining an opensim blog.<br />
|-<br />
| simsim <br />
| caocao <br />
| &nbsp; <br />
| &nbsp; <br />
| +9 <br />
| &nbsp; <br />
| Testing whole functions of OpenSimulator system,working with OpenSim-Engine,reporting on OpenSimulator<br />
|-<br />
| [[User:Vicero Lambert|Vicero Lambert]] <br />
| &nbsp; <br />
| &nbsp; <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
| [[User:Magi|Magi]] <br />
| Andy Agnew <br />
| Magi Merlin <br />
| <br />
| +10 <br />
| Spun Pty Ltd <br />
| 3D Web Integration, Database stuff and playing with the odds and ends box.<br />
|-<br />
| [[User:ClarkZone|ClarkZone]] <br />
| Troy Admin(@ClarkZone) <br />
| Troy Childs <br />
| Troy Admin (ClarkZone) <br />
| -5 <br />
| Http://clarkzone.dyndns.org <br />
| Tester and Grid Host<br />
|-<br />
| [[User:Aiaustin|aiaustin]] <br />
| Ai Austin <br />
| Ai Austin <br />
| Ai Austin <br />
| +0 <br />
| AIAI, Virtual University of Edinburgh<br />http://www.aiai.ed.ac.uk/~ai/<br />http://vue.ed.ac.uk/openvue/ <br />
| Windows tests<br />Content testing<br />Use of multiple VWs<br />
|-<br />
| Marc Manders <br />
| Marc Manders <br />
| &nbsp; <br />
| &nbsp; <br />
| +6 <br />
| marcmanders@gmail.com <br />
| Creative features<br />
|-<br />
| [[User:Balthazar|balthazar]] <br />
| Trevor Brooks <br />
| Balthazar Sin <br />
| <br />
| -5 <br />
| None <br />
| Terrains, testing and some small coding tasks<br />
|-<br />
| [[User:Jimbo2120|jimbo2120]] <br />
| Michael Osias <br />
| Illuminous Beltran <br />
| <br />
| -5 <br />
| IBM <br />
| Grid, AI, Skynet, coding and testing<br />
|-<br />
| ZeroPoint <br />
| &nbsp; <br />
| Guilderoy&nbsp;Dench <br />
| <br />
| -5 <br />
| &nbsp; <br />
| Programming/Database<br />
|-<br />
| [[User:DerekTang|DerekTang]] <br />
| Derek Tang <br />
| Derek Timeless <br />
| Derek Tang (ChineseGrid) <br />
| +8 <br />
| http://ChineseGrid.net <br />
| Running a public WINDOWS sim for testing, Docs, Helping Chinese users to enjoy OpenSim; building Chinese OpenSimulator communities. In construction...<br />
|-<br />
| [[User:TayB|TayB]] <br />
| Earl Balai <br />
| Taylor Dae <br />
| <br />
| -10 <br />
| WhynGrid <br />
| Grid Host,Networking,Contributions &amp; Testing.<br />
|-<br />
| [[User:JamieDav|JamieDav]] <br />
| Jamie David <br />
| Jamie David <br />
| <br />
| +7 <br />
| Forum <br />
| Grid, Sim, Avitar, Functionality<br />
|-<br />
| [[User:Krtaylor|Krtaylor]] <br />
| Kurt Taylor <br />
| Kurt Stringer <br />
| <br />
| -6 <br />
| IBM <br />
| Grid, Networking, Monitoring, Scripting, Inventory, Testing<br />
|-<br />
| [[User:Nink|Nink]] <br />
| Peter Finn <br />
| Nink Noonan <br />
| <br />
| -5 <br />
| IBM <br />
| Disruptive Influence.<br />
|-<br />
| [[User:Bruce|Bruce]] <br />
| Bruce Meerson <br />
| Bruce Meerson <br />
| <br />
| +8 <br />
| HiPiHi <br />
| Watching.<br />
|-<br />
| [[User:Darb|DarbD]] <br />
| Brian B. Quinn <br />
| Darb Dabney <br />
| regions<br />near Marin <br />
| PST/SLT (-7 or -8) <br />
| County of Marin, California<br /> http://blog.3dmap.me <br />
| LiDAR-based sculpties, real-world terrain, <br />pursuit of civic paraverses, virtual Emergency Operations Centers<br />
|-<br />
| [[User:Charlie Omega|CharlieO]] <br />
| Dan <br />
| Charlie Omega <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| Mild coding/tweaking/simple feature adds, Stress testing/break stuff, Testing limits of existing code. Making sure [[LSL Status]] is up to date<br />
|-<br />
| oobscure <br />
| &nbsp; <br />
| Opensource Obscure <br />
| <br />
| +1 <br />
| http://www.opensim.it <br />
| Running a public Linux sim for testing, Docs, Helping italian users, Building opensim communities, Watching<br />
|-<br />
| pitman <br />
| Mike Pitman <br />
| Rez Tone <br />
| <br />
| &nbsp; <br />
| IBM <br />
| Scientific visualization schemes, virt world product design, persistant workspaces, virt world based big biz<br />
|-<br />
| Shenlei <br />
| Shenlei Winkler <br />
| Shenlei Flasheart, Shenlei Winkler <br />
| <br />
| &nbsp; <br />
| Fashion Research Institute <br />
| Product Design and Development, Apparel industry, and o yes, I wrote the book&nbsp;;)<br />
|-<br />
| cmu <br />
| Christopher Mumme <br />
| Snook Destiny <br />
| <br />
| +1 <br />
| http://www.cmu-develop.de/ and research group "Collaboration Systems and CSCW" at Clausthal University of Technology <br />
| Testing OpenSim, working with OpenSim-Engine, reporting on OpenSimulator<br />
|-<br />
| [[Silpol]] <br />
| Andriy Tymchenko <br />
| Andy Tir <br />
| <br />
| EET (+2/3) <br />
| http://silpol.blogspot.com/ (also visible at Nokia) <br />
| Highly uncoordinated mess with elements of palace games, under-table diplomacy, rebellion, coup d'état and mutiny. optionally pirate<br />
|-<br />
| [[User:Grumly|Grumly]] <br />
| <br />
| Forest Klaar <br />
| Grumly TheBear <br />
| GMT+1 <br />
| .NET MCAD Dev/Arch/Trainer http://www.devoteam.com <br />
| Trying to get into OpenSimulator code for now. Particularly interrested in data persistence. blog (Hello, Avatar!): http://lslblog.free.fr<br />
|-<br />
| [[User:DaTwitch|DaTwitch]] <br />
| James G. Stallings II <br />
| <br />Lazarus Longstaff <br />
| Hiro Protagonist (OSGrid) <br />
| -5 <br />
| House Husband <br />
| OSGrid Region owner, OSGrid Operator,<br />Forum Admin, sometime wiki editor<br />
|-<br />
| gryc <br />
| Gryc Ueusp <br />
| Gryc Uriza <br />
| Gryc Uriza(OSGrid) <br />
| -6 <br />
| <br />
| PHP scripting, web interfaces, interconnectivity, cross-platformedness<br />
|-<br />
| [[User:Phrearch|Phrearch]] <br />
| Jeroen van Veen <br />
| Phrearch Miles <br />
| Phrearch Miles(OSGrid) <br />
| Amsterdam/Paris <br />
| <br />
| HWIOS, WiXTD, Wikidoc, Moo, User interfaces<br />
|-<br />
| [[User:Burnman|Burnman]] <br />
| Allen <br />
| Burnman Bedlam <br />
| <br />
| Boston, USA <br />
| <br />
| Testing, testing, and more testing! Getting familiar with the source, interested in all aspects of the project.<br />
|-<br />
| [[User:Krisbfunk|krisbfunk]] <br />
| Kris Bulman <br />
| Krisbfunk Vought <br />
| Krisbfunk Nocturnal(OSGrid) <br />
| PE, Canada (-4) <br />
| Edactive Technologies<br />NocturnalEye Productions<br />UPEI <br />
| Currently: Testing, bug reports, wiki updating, building on OSGrid<br />
|-<br />
| [[User:HashBox|HashBox]] <br />
| &nbsp; <br />
| Sibariel Darkstone <br />
| Sibariel Darkstone (OSGrid) <br />
| New Zealand (+12) <br />
| <br />
| Testing, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Kinoc|Kinoc]] <br />
| Kino Coursey <br />
| Daxxon Jaxxon <br />
| Daxxon Kinoc (OSgrid) <br />
| -6 <br />
| Daxtron Laboratories <br /> http://www.daxtron.com<br /> University of North Texas <br />
| AI, Semantic web, Ontologies, Natural Laanguage Processing, Cyc, Bots, NPC<br />
|-<br />
| [[User:Trapuh|trapuh]] <br />
| Pedro Ribeiro <br />
| Vaiten Forder <br />
| <br />
| GMT <br />
| University Student, Escola Superior de Educação de Viseu, Portugal <br />
| Testing, eventual bug reports and wiki. Music, web/digital arts and php+sql.<br />
|-<br />
| [[User:SonicViz|SonicViz]] <br />
| Paul Cohen <br />
| Komuso Tokugawa <br />
| <br />
| +9 <br />
| Http://sonicviz.com <br />
| Audio/Music, Interactive Music, Control Protocols, Interfaces, VisualFX, Procedural animation/Generative systems + testing and general dev<br />
|-<br />
| [[User:Mokele|mokele]] <br />
| Scott Norman <br />
| Mokelembembe Mokeev <br />
| <br />
| -8 (Southern California) <br />
| Web Developer (PHP and MySQL) <br />
| Interested in seeing running on PowerPC Macs which it is. So, when I can, I'll compile and test on PowerPC Mac (PowerBook G4) and submit reports and then update the wiki if need on installing on Mac. Also have a Ubuntu 7.10 server that I can do testing on too.<br />
|-<br />
| [[User:Devalnor|devalnor]] <br />
| Devalnor <br />
| M. Watkin <br />
| <br />
| +1 (Belgium) <br />
| <br />
| Small Patch code, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Ezekiel|Ezekiel]] <br />
| Ezekiel <br />
| Ezekiel Zabelin <br />
| <br />
| +1 <br />
| http://www.yosims.com <br />
| Concepts, business aspects of virtual worlds - web developer (PHP, MySQL, Javascript, LSL)<br />
|-<br />
| [[User:Buggmaster|Buggmaster]] <br />
| Mike D <br />
| Bug Master <br />
| None <br />
| -8 <br />
| http://www.adultmetaverse.com <br />
| Grid, Data/Web PHP/PERL/MySQL<br />
|-<br />
| [[User:Nixnerd|nixnerd]] <br />
| <br />
| Dangerously Moody <br />
| None <br />
| GMT <br />
| http://www.integratedtechnologies.eu <br />
| Cross Platform Testing, Feedback, Bug Reporting<br />
|-<br />
| [[User:MoHax|mohax]] <br />
| Mo Hax <br />
| Mo Hax <br />
| <br />
| -5 Eastern <br />
| IBM <br />
| Testing, Feedback, Content Contributions, Bug Reporting, Documenting, Development<br />
|-<br />
| [[User:Webmage|webmage]] <br />
| webmage <br />
| Leyla Masala <br />
| Web Mage <br />
| +1 <br />
| IBM <br />
| Testing, terrain<br />
|-<br />
| [[User:NLStitch|NLStitch]] <br />
| Marijn Oosterveld <br />
| Stitch Seale <br />
| NYA <br />
| GMT +1 Amsterdam <br />
| Twingate Systems (http://www.twingate.nl)<br />HanzeHogeschool Groningen, Netherlands <br />
| Programming, Photography, AI<br />
|-<br />
| [[User:Ideia Boa|Ideia Boa]] <br />
| Joao Lopes <br />
| Ideia Boa <br />
| Ideia Boa or Boa Ideia in some grids <br />
| GTM+1 Stockholm/Sweden <br />
| WorldSimTERRA - Virtual World that speaks Portuguese too<br />http://www.worldsimterra.com <br />
| Testing and more testing! Updating the original wiki and translating the OpenSimulator Wiki into Portuguese and reporting on OpenSimulator<br />
|-<br />
| [[User:Lulurun|lulurun]] <br />
| liu <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| 3Di Inc, Japan <br />http://www.3di.jp <br />
| Patches, openid, server performance, UGAI<br />
|-<br />
| [[User:Carlosroundel|Carlosrounde]] <br />
| Carlosroundel <br />
| Carlos Roundel <br />
| <br /> <br />
| +1 <br />
| Cyberlandia Italy<br />http://www.cyberlandia.net <br />
| Grid, programmer, database, tester<br />
|-<br />
| [[User:Mikebert|Mikebert]] <br />
| Michael Strunck <br />
| Mikebert Miles <br />
| Mikebert M34 <br />
| +1 <br />
| OpenSIM Wiki, Germany<br />http://www.opensim.de <br />
| German Wiki, Translater, Server Performance (Linux/Windows), Tester, Feedback, Bug Reporting, Server-Hosting<br />
|-<br />
| Taoki <br />
| Mircea Kitsune / Taoki Vixen <br />
| Mircea Kitsune (OSGrid) / Mircea Lobo (LL grid) <br />
| <br /> <br />
| GMT +2 <br />
| <br /> <br />
| Usually testing and bug reporting but I also make smaller patches where I know what to do.<br />
|-<br />
| [[User:Patnad|Patnad]] <br />
| Patrick <br />
| Patnad Babii <br />
| Patnad Babii (OSGrid) <br />
| GMT -5 <br />
| RezzMe Technologies<br />http://www.rezzme.com <br />
| Bug testing and reporting, I code C# and have submitted a few patches<br />
|-<br />
| [[User:^DarkMan|^DarkMan]] <br />
| Brian Adair <br />
| Patrick Ouachita <br />
| Brian Adair &#124; Patrick Meta <br />
| -6 CST <br />
| RealMetaLife &#124; B&amp;H Networking <br />
| Building, Scripting, Testing, etc.<br />
|-<br />
| [[User:Tlaukkan|Tommi Laukkanen]] <br />
| Tommi Laukkanen <br />
| &nbsp; <br />
| Tommi Laukkanen <br />
| +2 GMT <br />
| http://www.bubblecloud.org <br />
| Protocols ([http://www.bubblecloud.org MXP]), NHibernate, Scrip API, Map Generation, Bug Fixes, Grid Hosting<br />
|-<br />
| [[User:Mystical|Mystical]] <br />
| Kevin Tweedy <br />
| Mystical Demina <br />
| Mystical Demina <br />
| -5 <br />
| Extreme Reality Grid<br />http://www.XRGrid.com <br />
| Windows Communication Framework, Windows Workflow,Entity Framework, MSSQL<br />Enhancements,Commerce, Content,DotNetNuke based portal, development services<br />
|-<br />
| [[User:Godfrey|Godfrey]] <br />
| Jeff Lee <br />
| Warin Cascabel <br />
| <br />
| -5 (EST5EDT) <br />
| <br />
| Testing, minor bugfixes. Scripting, building, animating<br />
|-<br />
| Jamenai <br />
| Christopher Händler <br />
| Jamenai Luik <br />
| Jamenai Luik <br />
| +1 <br />
| Playneko Grid &#124; XIMDEX Jamenai<br />http://www.playneko.de<br />http://www.ximdex.de <br />
| Performance,Bug Reporting, Hosting, Grid-Owner,(PHP, MySQL, Perl, JavaScript, LSL)<br />
|-<br />
| [[User:Bikcmp|bikcmp]] <br />
| Jason <br />
| Jake1500 Allen <br />
| Jason Helios (The Helios Grid) <br />
| EST <br />
| Blue Software <br />
| Search, groups, land, and currency<br />
|-<br />
| [[User:Mark.malewski|Slipaway]] <br />
| Mark Malewski <br />
| Chris Rock <br />
| <br />
| -6 (-5 during summer - CDT) <br />
| NexTECH / Joopla <br />
| Web development &amp; systems integration, terrain, WIKI documentation, tutorials, testing, bug reporting and feedback.<br />
|-<br />
| barakademi <br />
| Steve Topp <br />
| barakademi Barzane <br />
| same avi on baragrid OSgrid Grid4us sciencesim <br />
| utc+1 (CET) paris <br />
| http://xbot-sl.barakademi.org http://vps.barakademi.org/oswi http://vps.barakademi.org/oswi/loginscreen.php <br />
| Music LiveMusic MetaverseMusic Opensim Libomv Mono-2.4 Linux (suse,debian,ubuntu) Admin Scripting Automating Development Intergration php mysql bash nant +++<br />
|-<br />
| [[User:Robert d|robert_d]] <br />
| Robert Dzikowski <br />
| <br />
| OSGrid: robert_d 13 <br />
| UTC+1 <br />
| [http://blog.rd-it.net http://blog.rd-it.net] <br />
| Region Modules, Tutorials<br />
|-<br />
| john_ <br />
| John&nbsp;Moyer <br />
| VAJohn&nbsp;GeekSquad or&nbsp;Matthew&nbsp;Kendal <br />
| <br />
| -5 <br />
| Best&nbsp;Buy/Geek&nbsp;Squad <br />
| Tester<br />
|-<br />
| [[User:W!cKeD|_WicKeD]] <br />
| Maik <br />
| Maik Galaxy <br />
| El Diablo <br />
| +1 Germany <br />
| Creatio Inc. / [http://www.OpenSimGerman.us/ OpenSimGerman.us] <br />
| German Support, Translator, Building, Scripting, Testing, Hosting<br />
|-<br />
| [[User:Stevie Wakowski|Stevie Wakowksi]] <br />
| Steve Roberts <br />
| Stevie Wakowski <br />
| <br />
| +10 Australia <br />
| IBM <br />
| OpenSimulator builds, Linux, Modrex, bug reporting, evangalist for OpenSimulator in business applications.<br />
|-<br />
| Revolution <br />
| Matthew <br />
| Revolution Smythe <br />
| Revolution Smythe <br />
| -6 Central USA <br />
| None <br />
| Script engine, physics engine, general odd bugs, interesting and odd things<br />
|-<br />
| [[User:ClemsonGS|clemsonGS]] <br />
| Brian Cass <br />
| BC Sands <br />
| Brian Cass (VWC Grid) <br />
| -5 <br />
| http://www.cvwconline.org/ <br />
| Developing virtual worlds for use in higher education<br />
|-<br />
| <br />
| AlexRa <br />
| <br />
| <br />
| <br />
| Independent <br />
| <br />
|-<br />
| <br />
| <br />
| Mikko Pallari <br />
| <br />
| <br />
| Realxtend <br />
| <br />
|-<br />
| <br />
| StrawberryFride <br />
| Chris Hart <br />
| <br />
| <br />
| ReactionGrid <br />
| <br />
|-<br />
| [[User:RemedyTomm|RemedyTomm]] <br />
| Tom Grimshaw <br />
| Tomm Remedy <br />
| KGrid: Casper Warden OSGrid: Tomm Remedy <br />
| UTC+0 (BST) <br />
| Remedy Communications <br />
| Texture pipeline, Groups, ObjectUpdates<br />
|-<br />
| <br />
| <br />
| Rob Smart <br />
| <br />
| <br />
| IBM <br />
| <br />
|-<br />
| MicheilMerlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| -6 <br />
| Independent <br /> [http://www.iliveisl.com/ http://www.iliveisl.com/] <br />
| Scripting, patches, and testcases<br />
|-<br />
| Pato Donald <br />
| Pato Donald <br />
| Morgam Biedermann <br />
| Pato Donald <br />
| -3 <br />
| Independent [http://www.matheusmk3.co.cc/ http://www.matheusmk3.co.cc/ <br />
| Groups, Scripts, Physics, Communication, Integration<br />
|-<br />
| <br />
| Sera Marx <br />
| Darkfire Soulstar <br />
| <br />
| +12 <br />
| Radiance promotions <br />
| Grid Host, Commissioner. ~ Anyone looking for work related to the development of Opensimulator or Viewers please contact me. Any work undertaken for me will be returned to Opensimulator unless made strictly for my Grid<br />
|-<br />
|[[User:dz|dz]] <br />
| Doug Osborn <br />
| ydoo magic<br />
| delta zed @ OSGRID Doug Osborn @ ScienceSim & MOSES grids<br />
| PST/SLT (-7 or -8) <br />
| CEO OpenSimian <br />
| Performance testing, advanced scripting, high prim count builds, Client and server side bots, Animation Overrides, MANTIS maintenance.<br />
|-<br />
| [[User:Hallow Palmer|Hallow Palmer]] <br />
| Markus <br />
| Hallow Palmer <br />
| <br /> <br />
| +1 <br />
| Grid4Us<br />http://www.grid4us.net <br />
| Server Performance (Windows), Tester, Feedback, Business concepts,Bug Reporting, Server-Hosting<br />
|-<br />
| [[User:LenaVanilli|LenaVanilli]] <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| +1 Germany <br />
| [http://www.hypergrid.org http://www.hypergrid.org] <br />
| Grid-Management, Testing Testing Testing, Region Hosting<br />
|-<br />
| [[User:Aduffy70|aduffy70]] <br />
| Aaron Duffy <br />
| Aeran Stipe <br />
| Aaron Duffy @ScienceSim <br />
| -7 <br />
| USU <br />
| Scientific visualization &amp; education, Region modules, Heavily scripted regions<br />
|-<br />
| <br />
| Erich Bremer <br />
| Erich Bremer <br />
| <br />
Erich Bremer@OSGrid <br />
<br />
| -5 <br />
| http://www.ebremer.com <br />
| Semantic Web, Data Visualization<br />
|-<br />
| [[User:MarkIDCAS|MarkIDCAS]] <br />
| Mark Bannon <br />
| Mark IDCAS <br />
| 3D Grid Association, AtMeeting, Valhalla Virtual and IDCAS. <br />
| GMT <br />
| [http://www.valhallavirtual.com http://www.valhallavirtual.com] <br />
| Grid Management &amp; systems integration. Scripting. WIKI documentation, tutorials, bug reporting and feedback.<br />
|-<br />
| [[User:Allquixotic|allquixotic]] <br />
| Sean McNamara <br />
| Tiyuk Quellmalz <br />
| OSG: Tiyuk Quellmalz <br />
| -5 <br />
| None <br />
| Bugfixing; networking; performance; data integrity; LSL; auto-backup; null DB (eventual consistency).<br />
|-<br />
| [[User:Orenh|orenh]] <br />
| Oren Hurvitz <br />
| <br />
| Oren Hurvitz (Kitely) <br />
| +2 <br />
| Kitely <br />
| <br />
|-<br />
| [[User:Randomhuman|randomhuman]] <br />
| Kevin Houlihan <br />
| random Radikal <br />
| random human (OSGrid) <br />
| WET/IST <br />
| CrimsonCookie <br />
| RemoteAdmin module; On-demand grids; web integration.<br />
|<br />
|-<br />
| [[User:Oddball Otoole|oddball otoole]]<br />
| J.v.Hogeloon<br />
| Oddball Otoole<br />
| Oddball Otoole (OSGrid<br />
| +1 (The Netherlands<br />
| None<br />
| Building, scripting, testing, social stuff.<br />
|-<br />
| [[User:Pixel|Pixel Tomsen]]<br />
| Christian Kurzhals<br />
| Pixel Tomsen<br />
| Pixel Tomsen OSGrid<br />
| +1 (Germany<br />
| see my profil<br />
| Dev, Building, scripting, sim-hosting, some modules, patches, osgrid<br />
|-<br />
| [[User:kenearlg|kenearlg]]<br />
| Ken Grunke<br />
| Key Grau<br />
| Key Gruin (Osgrid)<br />
| -6 CST<br />
| http://www.osgrid.org/<br />
| testing, moderating, inworld games & recreation, wiki spam control<br />
|}<br />
<br />
== Retired Additional Developers ==<br />
<br />
Additional developers who are no longer working on the OpenSimulator project. Thank you forever for your contributions! <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Fly-man-|Fly-Man-]] <br />
| Laurence <br />
| <br />
| OSGrid: Fly Man <br />
| GMT +1 <br />
| Private Company<br />
| Testing, OpenSimSearch, OpenSimProfile<br />
|-<br />
|}<br />
<br />
[[Category:Development]]<br />
[[Category:Tech Reference]]<br />
[[Category:Help]]</div>
Dz
http://opensimulator.org/wiki/Development_Team
Development Team
2014-01-27T05:25:12Z
<p>Dz: /* Additional Developers/Testers/Contributors */</p>
<hr />
<div>__NOTOC__ {{Quicklinks}} <br />
<br />
== Active Core Developers ==<br />
<br />
Developers who have commit access to our central server, are [http://www.ohloh.net/projects/4753/contributors regular contributors] to the codebase, and have voting rights over development and process issues of the OpenSimulator project. See [[Organization]]. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Adam Frisby|Adam Frisby]] <br />
| Adam Frisby <br />
| Adam Zaius <br />
| <br />
| +8 <br />
| DeepThink Pty Ltd <br />
| Terrain, Performance<br />
|-<br />
| [[User:Chi11ken|chi11ken]] <br />
| Jeff Ames <br />
| Chillken Proto <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Justincc|justincc]] <br />
| Justin Clark-Casey <br />
| Lulworth Beaumont <br />
| Justin Clark-Casey (all other grids) <br />
| 0 <br />
| OSVW Consulting<br />[http://justincc.org/blog justincc's OpenSimulator blog] <br />
| Grid, performance &amp; reliability, inventory (avatar and object), assets, scenes, OARs, etc. Generally speaking, my main interest is to create infrastructure that other people can build on top of.<br />
|-<br />
| [[User:Dahlia|dahlia]] <br />
| T. Hoff <br />
| Dahlia Trimble <br />
| <br />
| -8 / -7 <br />
| Independent <br />
| Collision geometry, various math and physics issues, occasional bug fixes and random enhancements<br />
|-<br />
| [[User:Melanie T|Melanie_T]] <br />
| Melanie <br />
| Melanie Milland <br />
| <br /> <br />
| +1 <br />
| Independent <br />
| Scripting, Prims/Scene, Life, The Universe, and Everything<br />
|-<br />
| [[User:Diva|Diva]] <br />
| Crista Lopes <br />
| Diva Canto <br />
| Crista Lopes / Diva Canto <br />
| -8 <br />
| University of California, Irvine <br />
| Everything, except databases<br />
|-<br />
| [[User:Dslake|dslake]] <br />
| Dan Lake <br />
| Dan Lake <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| Scalability, Performance, Network stack<br />
|-<br />
| [[User:Marck|Marck00]] <br />
| M. Kirsch <br />
| Marck Kjeller <br />
| <br />
| +1 <br />
| Independent <br />
| Everything that catches my attention and that I can get my head around. <br />
| <br />
|-<br />
| cmickeyb <br />
| Mic Bowman <br />
| Mic Bowman <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| <br />
|-<br />
| [[User:BlueWall|BlueWall]] <br />
| James Hughes <br />
| BlueWall Slade <br />
| BlueWall Slade <br />
| -5 <br />
| BlueWall Information Technologies, LLC <br />
| Various parts<br />
|-<br />
| [[User:Nebadon|Nebadon]] <br />
| Michael Emory Cerquoni <br />
| Nebadon Izumi <br />
| Nebadon Izumi <br />
| -7 Arizona <br />
| Oni Kenkon Creations <br />
| Building, Scripting, Testing<br />
|-<br />
| [[User:Snoopy2|Snoopy2]] <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
|<br />
| [http://www.dreamlandmetaverse.com/ http://www.dreamlandmetaverse.com/] <br />
| OpenSim region and grid hosting<br />
|-<br />
| radams<br />
| Robert Adams<br />
| <br />
| <br />
| <br />
| Looking Glass Viewer <br />
| <br />
|}<br />
<br />
<br /><br />
<br />
== Core Developers Following the White Rabbit ==<br />
<br />
Core developers who have temporarily (we hope) gone chasing the white rabbit. They are in all similar to the active core developers, except that they haven't been that active lately, so their voting rights are awaiting their come back. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Lbsa71|lbsa71]] <br />
| Stefan Andersson <br />
| Tribal Skytower <br />
| OSG:Stefan Andersson<br />TN:Stefan Andersson <br />
| +1 <br />
| [http://tribalmedia.se/ Tribal Media AB] <br />
| Web Integration<br />
|-<br />
| [[User:MW|MW]] <br />
| Darren <br />
| Wright Juran <br />
| <br />
| 0 <br />
| <br />
| Everything<br />
|-<br />
| ckrinke <br />
| Charles&nbsp;Krinke <br />
| Charlesk&nbsp;Bing <br />
| <br />
| -8 <br />
| &nbsp; <br />
| Reliability/Grid servers/ll-functions<br />
|-<br />
| [[User:Mikem|mikem]] <br />
| Mike Mazur <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| Independent <br />
| Patches, scripting improvements, LSL compiler<br />
|-<br />
| [[User:HomerHorwitz|homerh]] <br />
| Homer Horwitz <br />
| Homer Horwitz <br />
| <br /> <br />
| +2 <br />
| Independent <br />
| Rev. engineering, "now, that's funny" problems, but still interested in all parts of it<br />
|-<br />
| [[User:Nlin|nlin]] <br />
| N Lin <br />
| Standard Drucker <br />
| <br /> <br />
| +9 <br />
| [http://www.3di.jp/en/ 3Di Inc, Japan]<br />http://www.3di.jp/en/ <br />
| Physics, scripting, more to come<br />
|-<br />
| [[User:Arthursv|arthursv]] <br />
| Arthur Valadares <br />
| <br />
| NONE <br />
| -8 <br />
| University of California, Irvine <br />
| Unit testing, database plugins, bug fixes, general<br />
|-<br />
| [[User:DrScofield|drscofld]] <br />
| Dirk Husemann <br />
| Dr Scofield <br />
| <br />
| +1 <br />
| [http://xyzzyxyzzy.net/ xyzzyxyzzy.net] <br />
| Reliability, networking protocols, inventory, assets, remote control, voice, and pretty much everything else&nbsp;:-) <br />
| <br />
|-<br />
| [[User:Teravus|Teravus]] <br />
| Daniel Olivares <br />
| Teravus Ousley <br />
| <br />
| -5 <br />
| W3z <br />
| Physics &amp; Admin tools, A working sim.<br />
|}<br />
<br />
== Retired Core Developers ==<br />
<br />
Core developers who have transcended our mortal plane, i.e. they are no longer directly engaged with the project. Thank you forever for your contributions! <br />
<br />
* '''Only formerly voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Babblefrog|babblefrog]] <br />
| Brian McBee <br />
| Dogen Coldstream <br />
| Babblefrog Ballistic (osgrid) <br />
| -8 <br />
| Disorganized <br />
| &nbsp;<br />
|-<br />
| [[User:Danx0r|danx0r]] <br />
| Dan Miller <br />
| Albert Pascal <br />
| <br />
| -8 <br />
| squiggle.com <br />
| PHEEZIKS; everything<br />
|-<br />
| Tleiades <br />
| &nbsp; <br />
| Tleiades&nbsp;Hax <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Grid servers/Database<br />
|-<br />
| [[User:Darok|Darok]] <br />
| &nbsp; <br />
| Darok Kaminski <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Physics engines (especially BulletX)<br />
|-<br />
| Gareth / Gwen <br />
| Gareth Nelson <br />
| Gareth Ellison <br />
| Gareth Nelson (on everywhere but SL) <br />
| BST (UTC+1) <br />
| Litesim Ltd <br />
| Grid servers, sim border crossing, avatar animations<br />
|-<br />
| [[User:Dalien|dalien]] <br />
| Dalien Talbot <br />
| Dalien Talbot <br />
| <br />
| +1 <br />
| Mostly TCP-based <br />
| Small fixes; rev.eng./prototyping; nightlies; git-keeper<br />
|-<br />
| [[Alondria]] <br />
| <br />
| Alondria LeFay <br />
| Alondria LeFay (OSGrid) <br />
| -8 <br />
| Independent <br />
| Implementation of LSL functions and other scripting tidbits.<br />
|-<br />
| [[User:SeanDague|sdague]] <br />
| Sean Dague <br />
| Neas Bade <br />
| <br />
| -5 <br />
| IBM <br />
| Database, Linux, Testing, Misc<br />
|-<br />
| [[User:MingChen|MingChen]] <br />
| Mike/Michael Ortman <br />
| Ming Chen <br />
| <br />
| -6 (-5 in Summer) <br />
| DeepThink Pty Ltd <br />
| Estate/Parcel Support/Modules/Keeping things all neat and tidy.<br />
|-<br />
| [[User:Tedd|Tedd]] <br />
| Tedd Hansen <br />
| Tedd Maa <br />
| <br />
| +1 <br />
| Tedd Hansen <br />
| Programming/Scripting/Architecture<br />
|-<br />
| [[User:Adjohn|adjohn]] <br />
| Adam Johnson <br />
| Zeuz Zenovka <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Joha1|joha1]] <br />
| Johan Berntsson <br />
| Joppi Brandenburg <br />
| <br /> <br />
| +9 <br />
| &nbsp; <br />
| Performance, packet handling/libSL<br />
|-<br />
| jhurliman <br />
| John Hurliman <br />
| John Hurliman <br />
| <br />
| <br />
| <br />
|}<br />
<br />
== Wiki Sysops ==<br />
<br />
Along with the core developers, these people help manage the OpenSimulator wiki as well as make other contributions (see Areas of Interest). <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Makopoppo|Makopoppo]] <br />
| Makiko Nomura <br />
| Mako Nozaki <br />
| Everywhere <br />
| +9 Tokyo, Japan <br />
| As an individual developer <br />
| Everything for improving usability and connectability - wiki/issue management, documentation, localization(Japanese), modifying the interface mainly of core modules<br />
|-<br />
| [[User:Fritigern|Fritigern]] <br />
| S-E-C-R-E-T <br />
| Fritigern Gothly <br />
| SecondLife, OSGrid <br />
| +1 GMT <br />
| <br />
| My interests are many, and extremely varied. One thing that i am very interested in, is seeing OpenSimulator grow, mature, and develop into something that really does rival SL/LL.<br />
|}<br />
<br />
== Additional Developers/Testers/Contributors ==<br />
<br />
These people have contributed and/or are contributing bug reports, patches, testing, and all sorts of other goodies to the project. <br /> '''Newcomers please add yourself to bottom of the list!''' <br /> <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Jtclark48|jclark4]] <br />
| Jay Clark <br />
| Jay Clarke <br />
| <br />
| -5 <br />
| IBM <br />
| Physics, Grid Host, AI, Scripting, Testing<br />
|-<br />
| [[User:AdamStevenson|BigFootAg]] <br />
| Adam Stevenson <br />
| Adamus Petrov <br />
| <br />
| -6 <br />
| Texas A&amp;M University <br />
| AI, Skynet, Evolving Systems, Biology<br />
|-<br />
| [[User:Jeff1564|Jeff1564]] <br />
| Jeff <br />
| Potter Taurog <br />
| Potter Taurog <br />
| -8 <br />
| http://myopengrid.com <br />
| Building, Scripting, Testing<br />
|-<br />
| Rock_Vacirca <br />
| Colin Withers <br />
| Rock Vacirca <br />
| &nbsp; <br />
| +1 <br />
| http://rock-vacirca.blogspot.com <br />
| Testing, building, scripting, maintaining an opensim blog.<br />
|-<br />
| simsim <br />
| caocao <br />
| &nbsp; <br />
| &nbsp; <br />
| +9 <br />
| &nbsp; <br />
| Testing whole functions of OpenSimulator system,working with OpenSim-Engine,reporting on OpenSimulator<br />
|-<br />
| [[User:Vicero Lambert|Vicero Lambert]] <br />
| &nbsp; <br />
| &nbsp; <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
| [[User:Magi|Magi]] <br />
| Andy Agnew <br />
| Magi Merlin <br />
| <br />
| +10 <br />
| Spun Pty Ltd <br />
| 3D Web Integration, Database stuff and playing with the odds and ends box.<br />
|-<br />
| [[User:ClarkZone|ClarkZone]] <br />
| Troy Admin(@ClarkZone) <br />
| Troy Childs <br />
| Troy Admin (ClarkZone) <br />
| -5 <br />
| Http://clarkzone.dyndns.org <br />
| Tester and Grid Host<br />
|-<br />
| [[User:Aiaustin|aiaustin]] <br />
| Ai Austin <br />
| Ai Austin <br />
| Ai Austin <br />
| +0 <br />
| AIAI, Virtual University of Edinburgh<br />http://www.aiai.ed.ac.uk/~ai/<br />http://vue.ed.ac.uk/openvue/ <br />
| Windows tests<br />Content testing<br />Use of multiple VWs<br />
|-<br />
| Marc Manders <br />
| Marc Manders <br />
| &nbsp; <br />
| &nbsp; <br />
| +6 <br />
| marcmanders@gmail.com <br />
| Creative features<br />
|-<br />
| [[User:Balthazar|balthazar]] <br />
| Trevor Brooks <br />
| Balthazar Sin <br />
| <br />
| -5 <br />
| None <br />
| Terrains, testing and some small coding tasks<br />
|-<br />
| [[User:Jimbo2120|jimbo2120]] <br />
| Michael Osias <br />
| Illuminous Beltran <br />
| <br />
| -5 <br />
| IBM <br />
| Grid, AI, Skynet, coding and testing<br />
|-<br />
| ZeroPoint <br />
| &nbsp; <br />
| Guilderoy&nbsp;Dench <br />
| <br />
| -5 <br />
| &nbsp; <br />
| Programming/Database<br />
|-<br />
| [[User:DerekTang|DerekTang]] <br />
| Derek Tang <br />
| Derek Timeless <br />
| Derek Tang (ChineseGrid) <br />
| +8 <br />
| http://ChineseGrid.net <br />
| Running a public WINDOWS sim for testing, Docs, Helping Chinese users to enjoy OpenSim; building Chinese OpenSimulator communities. In construction...<br />
|-<br />
| [[User:TayB|TayB]] <br />
| Earl Balai <br />
| Taylor Dae <br />
| <br />
| -10 <br />
| WhynGrid <br />
| Grid Host,Networking,Contributions &amp; Testing.<br />
|-<br />
| [[User:JamieDav|JamieDav]] <br />
| Jamie David <br />
| Jamie David <br />
| <br />
| +7 <br />
| Forum <br />
| Grid, Sim, Avitar, Functionality<br />
|-<br />
| [[User:Krtaylor|Krtaylor]] <br />
| Kurt Taylor <br />
| Kurt Stringer <br />
| <br />
| -6 <br />
| IBM <br />
| Grid, Networking, Monitoring, Scripting, Inventory, Testing<br />
|-<br />
| [[User:Nink|Nink]] <br />
| Peter Finn <br />
| Nink Noonan <br />
| <br />
| -5 <br />
| IBM <br />
| Disruptive Influence.<br />
|-<br />
| [[User:Bruce|Bruce]] <br />
| Bruce Meerson <br />
| Bruce Meerson <br />
| <br />
| +8 <br />
| HiPiHi <br />
| Watching.<br />
|-<br />
| [[User:Darb|DarbD]] <br />
| Brian B. Quinn <br />
| Darb Dabney <br />
| regions<br />near Marin <br />
| PST/SLT (-7 or -8) <br />
| County of Marin, California<br /> http://blog.3dmap.me <br />
| LiDAR-based sculpties, real-world terrain, <br />pursuit of civic paraverses, virtual Emergency Operations Centers<br />
|-<br />
| [[User:Charlie Omega|CharlieO]] <br />
| Dan <br />
| Charlie Omega <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| Mild coding/tweaking/simple feature adds, Stress testing/break stuff, Testing limits of existing code. Making sure [[LSL Status]] is up to date<br />
|-<br />
| oobscure <br />
| &nbsp; <br />
| Opensource Obscure <br />
| <br />
| +1 <br />
| http://www.opensim.it <br />
| Running a public Linux sim for testing, Docs, Helping italian users, Building opensim communities, Watching<br />
|-<br />
| pitman <br />
| Mike Pitman <br />
| Rez Tone <br />
| <br />
| &nbsp; <br />
| IBM <br />
| Scientific visualization schemes, virt world product design, persistant workspaces, virt world based big biz<br />
|-<br />
| Shenlei <br />
| Shenlei Winkler <br />
| Shenlei Flasheart, Shenlei Winkler <br />
| <br />
| &nbsp; <br />
| Fashion Research Institute <br />
| Product Design and Development, Apparel industry, and o yes, I wrote the book&nbsp;;)<br />
|-<br />
| cmu <br />
| Christopher Mumme <br />
| Snook Destiny <br />
| <br />
| +1 <br />
| http://www.cmu-develop.de/ and research group "Collaboration Systems and CSCW" at Clausthal University of Technology <br />
| Testing OpenSim, working with OpenSim-Engine, reporting on OpenSimulator<br />
|-<br />
| [[Silpol]] <br />
| Andriy Tymchenko <br />
| Andy Tir <br />
| <br />
| EET (+2/3) <br />
| http://silpol.blogspot.com/ (also visible at Nokia) <br />
| Highly uncoordinated mess with elements of palace games, under-table diplomacy, rebellion, coup d'état and mutiny. optionally pirate<br />
|-<br />
| [[User:Grumly|Grumly]] <br />
| <br />
| Forest Klaar <br />
| Grumly TheBear <br />
| GMT+1 <br />
| .NET MCAD Dev/Arch/Trainer http://www.devoteam.com <br />
| Trying to get into OpenSimulator code for now. Particularly interrested in data persistence. blog (Hello, Avatar!): http://lslblog.free.fr<br />
|-<br />
| [[User:DaTwitch|DaTwitch]] <br />
| James G. Stallings II <br />
| <br />Lazarus Longstaff <br />
| Hiro Protagonist (OSGrid) <br />
| -5 <br />
| House Husband <br />
| OSGrid Region owner, OSGrid Operator,<br />Forum Admin, sometime wiki editor<br />
|-<br />
| gryc <br />
| Gryc Ueusp <br />
| Gryc Uriza <br />
| Gryc Uriza(OSGrid) <br />
| -6 <br />
| <br />
| PHP scripting, web interfaces, interconnectivity, cross-platformedness<br />
|-<br />
| [[User:Phrearch|Phrearch]] <br />
| Jeroen van Veen <br />
| Phrearch Miles <br />
| Phrearch Miles(OSGrid) <br />
| Amsterdam/Paris <br />
| <br />
| HWIOS, WiXTD, Wikidoc, Moo, User interfaces<br />
|-<br />
| [[User:Burnman|Burnman]] <br />
| Allen <br />
| Burnman Bedlam <br />
| <br />
| Boston, USA <br />
| <br />
| Testing, testing, and more testing! Getting familiar with the source, interested in all aspects of the project.<br />
|-<br />
| [[User:Krisbfunk|krisbfunk]] <br />
| Kris Bulman <br />
| Krisbfunk Vought <br />
| Krisbfunk Nocturnal(OSGrid) <br />
| PE, Canada (-4) <br />
| Edactive Technologies<br />NocturnalEye Productions<br />UPEI <br />
| Currently: Testing, bug reports, wiki updating, building on OSGrid<br />
|-<br />
| [[User:HashBox|HashBox]] <br />
| &nbsp; <br />
| Sibariel Darkstone <br />
| Sibariel Darkstone (OSGrid) <br />
| New Zealand (+12) <br />
| <br />
| Testing, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Kinoc|Kinoc]] <br />
| Kino Coursey <br />
| Daxxon Jaxxon <br />
| Daxxon Kinoc (OSgrid) <br />
| -6 <br />
| Daxtron Laboratories <br /> http://www.daxtron.com<br /> University of North Texas <br />
| AI, Semantic web, Ontologies, Natural Laanguage Processing, Cyc, Bots, NPC<br />
|-<br />
| [[User:Trapuh|trapuh]] <br />
| Pedro Ribeiro <br />
| Vaiten Forder <br />
| <br />
| GMT <br />
| University Student, Escola Superior de Educação de Viseu, Portugal <br />
| Testing, eventual bug reports and wiki. Music, web/digital arts and php+sql.<br />
|-<br />
| [[User:SonicViz|SonicViz]] <br />
| Paul Cohen <br />
| Komuso Tokugawa <br />
| <br />
| +9 <br />
| Http://sonicviz.com <br />
| Audio/Music, Interactive Music, Control Protocols, Interfaces, VisualFX, Procedural animation/Generative systems + testing and general dev<br />
|-<br />
| [[User:Mokele|mokele]] <br />
| Scott Norman <br />
| Mokelembembe Mokeev <br />
| <br />
| -8 (Southern California) <br />
| Web Developer (PHP and MySQL) <br />
| Interested in seeing running on PowerPC Macs which it is. So, when I can, I'll compile and test on PowerPC Mac (PowerBook G4) and submit reports and then update the wiki if need on installing on Mac. Also have a Ubuntu 7.10 server that I can do testing on too.<br />
|-<br />
| [[User:Devalnor|devalnor]] <br />
| Devalnor <br />
| M. Watkin <br />
| <br />
| +1 (Belgium) <br />
| <br />
| Small Patch code, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Ezekiel|Ezekiel]] <br />
| Ezekiel <br />
| Ezekiel Zabelin <br />
| <br />
| +1 <br />
| http://www.yosims.com <br />
| Concepts, business aspects of virtual worlds - web developer (PHP, MySQL, Javascript, LSL)<br />
|-<br />
| [[User:Buggmaster|Buggmaster]] <br />
| Mike D <br />
| Bug Master <br />
| None <br />
| -8 <br />
| http://www.adultmetaverse.com <br />
| Grid, Data/Web PHP/PERL/MySQL<br />
|-<br />
| [[User:Nixnerd|nixnerd]] <br />
| <br />
| Dangerously Moody <br />
| None <br />
| GMT <br />
| http://www.integratedtechnologies.eu <br />
| Cross Platform Testing, Feedback, Bug Reporting<br />
|-<br />
| [[User:MoHax|mohax]] <br />
| Mo Hax <br />
| Mo Hax <br />
| <br />
| -5 Eastern <br />
| IBM <br />
| Testing, Feedback, Content Contributions, Bug Reporting, Documenting, Development<br />
|-<br />
| [[User:Webmage|webmage]] <br />
| webmage <br />
| Leyla Masala <br />
| Web Mage <br />
| +1 <br />
| IBM <br />
| Testing, terrain<br />
|-<br />
| [[User:NLStitch|NLStitch]] <br />
| Marijn Oosterveld <br />
| Stitch Seale <br />
| NYA <br />
| GMT +1 Amsterdam <br />
| Twingate Systems (http://www.twingate.nl)<br />HanzeHogeschool Groningen, Netherlands <br />
| Programming, Photography, AI<br />
|-<br />
| [[User:Ideia Boa|Ideia Boa]] <br />
| Joao Lopes <br />
| Ideia Boa <br />
| Ideia Boa or Boa Ideia in some grids <br />
| GTM+1 Stockholm/Sweden <br />
| WorldSimTERRA - Virtual World that speaks Portuguese too<br />http://www.worldsimterra.com <br />
| Testing and more testing! Updating the original wiki and translating the OpenSimulator Wiki into Portuguese and reporting on OpenSimulator<br />
|-<br />
| [[User:Lulurun|lulurun]] <br />
| liu <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| 3Di Inc, Japan <br />http://www.3di.jp <br />
| Patches, openid, server performance, UGAI<br />
|-<br />
| [[User:Carlosroundel|Carlosrounde]] <br />
| Carlosroundel <br />
| Carlos Roundel <br />
| <br /> <br />
| +1 <br />
| Cyberlandia Italy<br />http://www.cyberlandia.net <br />
| Grid, programmer, database, tester<br />
|-<br />
| [[User:Mikebert|Mikebert]] <br />
| Michael Strunck <br />
| Mikebert Miles <br />
| Mikebert M34 <br />
| +1 <br />
| OpenSIM Wiki, Germany<br />http://www.opensim.de <br />
| German Wiki, Translater, Server Performance (Linux/Windows), Tester, Feedback, Bug Reporting, Server-Hosting<br />
|-<br />
| Taoki <br />
| Mircea Kitsune / Taoki Vixen <br />
| Mircea Kitsune (OSGrid) / Mircea Lobo (LL grid) <br />
| <br /> <br />
| GMT +2 <br />
| <br /> <br />
| Usually testing and bug reporting but I also make smaller patches where I know what to do.<br />
|-<br />
| [[User:Patnad|Patnad]] <br />
| Patrick <br />
| Patnad Babii <br />
| Patnad Babii (OSGrid) <br />
| GMT -5 <br />
| RezzMe Technologies<br />http://www.rezzme.com <br />
| Bug testing and reporting, I code C# and have submitted a few patches<br />
|-<br />
| [[User:^DarkMan|^DarkMan]] <br />
| Brian Adair <br />
| Patrick Ouachita <br />
| Brian Adair &#124; Patrick Meta <br />
| -6 CST <br />
| RealMetaLife &#124; B&amp;H Networking <br />
| Building, Scripting, Testing, etc.<br />
|-<br />
| [[User:Tlaukkan|Tommi Laukkanen]] <br />
| Tommi Laukkanen <br />
| &nbsp; <br />
| Tommi Laukkanen <br />
| +2 GMT <br />
| http://www.bubblecloud.org <br />
| Protocols ([http://www.bubblecloud.org MXP]), NHibernate, Scrip API, Map Generation, Bug Fixes, Grid Hosting<br />
|-<br />
| [[User:Mystical|Mystical]] <br />
| Kevin Tweedy <br />
| Mystical Demina <br />
| Mystical Demina <br />
| -5 <br />
| Extreme Reality Grid<br />http://www.XRGrid.com <br />
| Windows Communication Framework, Windows Workflow,Entity Framework, MSSQL<br />Enhancements,Commerce, Content,DotNetNuke based portal, development services<br />
|-<br />
| [[User:Godfrey|Godfrey]] <br />
| Jeff Lee <br />
| Warin Cascabel <br />
| <br />
| -5 (EST5EDT) <br />
| <br />
| Testing, minor bugfixes. Scripting, building, animating<br />
|-<br />
| Jamenai <br />
| Christopher Händler <br />
| Jamenai Luik <br />
| Jamenai Luik <br />
| +1 <br />
| Playneko Grid &#124; XIMDEX Jamenai<br />http://www.playneko.de<br />http://www.ximdex.de <br />
| Performance,Bug Reporting, Hosting, Grid-Owner,(PHP, MySQL, Perl, JavaScript, LSL)<br />
|-<br />
| [[User:Bikcmp|bikcmp]] <br />
| Jason <br />
| Jake1500 Allen <br />
| Jason Helios (The Helios Grid) <br />
| EST <br />
| Blue Software <br />
| Search, groups, land, and currency<br />
|-<br />
| [[User:Mark.malewski|Slipaway]] <br />
| Mark Malewski <br />
| Chris Rock <br />
| <br />
| -6 (-5 during summer - CDT) <br />
| NexTECH / Joopla <br />
| Web development &amp; systems integration, terrain, WIKI documentation, tutorials, testing, bug reporting and feedback.<br />
|-<br />
| barakademi <br />
| Steve Topp <br />
| barakademi Barzane <br />
| same avi on baragrid OSgrid Grid4us sciencesim <br />
| utc+1 (CET) paris <br />
| http://xbot-sl.barakademi.org http://vps.barakademi.org/oswi http://vps.barakademi.org/oswi/loginscreen.php <br />
| Music LiveMusic MetaverseMusic Opensim Libomv Mono-2.4 Linux (suse,debian,ubuntu) Admin Scripting Automating Development Intergration php mysql bash nant +++<br />
|-<br />
| [[User:Robert d|robert_d]] <br />
| Robert Dzikowski <br />
| <br />
| OSGrid: robert_d 13 <br />
| UTC+1 <br />
| [http://blog.rd-it.net http://blog.rd-it.net] <br />
| Region Modules, Tutorials<br />
|-<br />
| john_ <br />
| John&nbsp;Moyer <br />
| VAJohn&nbsp;GeekSquad or&nbsp;Matthew&nbsp;Kendal <br />
| <br />
| -5 <br />
| Best&nbsp;Buy/Geek&nbsp;Squad <br />
| Tester<br />
|-<br />
| [[User:W!cKeD|_WicKeD]] <br />
| Maik <br />
| Maik Galaxy <br />
| El Diablo <br />
| +1 Germany <br />
| Creatio Inc. / [http://www.OpenSimGerman.us/ OpenSimGerman.us] <br />
| German Support, Translator, Building, Scripting, Testing, Hosting<br />
|-<br />
| [[User:Stevie Wakowski|Stevie Wakowksi]] <br />
| Steve Roberts <br />
| Stevie Wakowski <br />
| <br />
| +10 Australia <br />
| IBM <br />
| OpenSimulator builds, Linux, Modrex, bug reporting, evangalist for OpenSimulator in business applications.<br />
|-<br />
| Revolution <br />
| Matthew <br />
| Revolution Smythe <br />
| Revolution Smythe <br />
| -6 Central USA <br />
| None <br />
| Script engine, physics engine, general odd bugs, interesting and odd things<br />
|-<br />
| [[User:ClemsonGS|clemsonGS]] <br />
| Brian Cass <br />
| BC Sands <br />
| Brian Cass (VWC Grid) <br />
| -5 <br />
| http://www.cvwconline.org/ <br />
| Developing virtual worlds for use in higher education<br />
|-<br />
| <br />
| AlexRa <br />
| <br />
| <br />
| <br />
| Independent <br />
| <br />
|-<br />
| <br />
| <br />
| Mikko Pallari <br />
| <br />
| <br />
| Realxtend <br />
| <br />
|-<br />
| <br />
| StrawberryFride <br />
| Chris Hart <br />
| <br />
| <br />
| ReactionGrid <br />
| <br />
|-<br />
| [[User:RemedyTomm|RemedyTomm]] <br />
| Tom Grimshaw <br />
| Tomm Remedy <br />
| KGrid: Casper Warden OSGrid: Tomm Remedy <br />
| UTC+0 (BST) <br />
| Remedy Communications <br />
| Texture pipeline, Groups, ObjectUpdates<br />
|-<br />
| <br />
| <br />
| Rob Smart <br />
| <br />
| <br />
| IBM <br />
| <br />
|-<br />
| MicheilMerlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| -6 <br />
| Independent <br /> [http://www.iliveisl.com/ http://www.iliveisl.com/] <br />
| Scripting, patches, and testcases<br />
|-<br />
| Pato Donald <br />
| Pato Donald <br />
| Morgam Biedermann <br />
| Pato Donald <br />
| -3 <br />
| Independent [http://www.matheusmk3.co.cc/ http://www.matheusmk3.co.cc/ <br />
| Groups, Scripts, Physics, Communication, Integration<br />
|-<br />
| <br />
| Sera Marx <br />
| Darkfire Soulstar <br />
| <br />
| +12 <br />
| Radiance promotions <br />
| Grid Host, Commissioner. ~ Anyone looking for work related to the development of Opensimulator or Viewers please contact me. Any work undertaken for me will be returned to Opensimulator unless made strictly for my Grid<br />
|-<br />
|[[User:dz|dz]] <br />
| Doug Osborn <br />
| ydoo magic<br />
| Doug Osborn @ScienceSim & MOSES grids<br />
| PST/SLT (-7 or -8) <br />
| CEO OpenSimian <br />
| Performance testing, advanced scripting, high prim count builds, Client and server side bots, Animation Overrides, MANTIS maintenance.<br />
|-<br />
| [[User:Hallow Palmer|Hallow Palmer]] <br />
| Markus <br />
| Hallow Palmer <br />
| <br /> <br />
| +1 <br />
| Grid4Us<br />http://www.grid4us.net <br />
| Server Performance (Windows), Tester, Feedback, Business concepts,Bug Reporting, Server-Hosting<br />
|-<br />
| [[User:LenaVanilli|LenaVanilli]] <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| +1 Germany <br />
| [http://www.hypergrid.org http://www.hypergrid.org] <br />
| Grid-Management, Testing Testing Testing, Region Hosting<br />
|-<br />
| [[User:Aduffy70|aduffy70]] <br />
| Aaron Duffy <br />
| Aeran Stipe <br />
| Aaron Duffy @ScienceSim <br />
| -7 <br />
| USU <br />
| Scientific visualization &amp; education, Region modules, Heavily scripted regions<br />
|-<br />
| <br />
| Erich Bremer <br />
| Erich Bremer <br />
| <br />
Erich Bremer@OSGrid <br />
<br />
| -5 <br />
| http://www.ebremer.com <br />
| Semantic Web, Data Visualization<br />
|-<br />
| [[User:MarkIDCAS|MarkIDCAS]] <br />
| Mark Bannon <br />
| Mark IDCAS <br />
| 3D Grid Association, AtMeeting, Valhalla Virtual and IDCAS. <br />
| GMT <br />
| [http://www.valhallavirtual.com http://www.valhallavirtual.com] <br />
| Grid Management &amp; systems integration. Scripting. WIKI documentation, tutorials, bug reporting and feedback.<br />
|-<br />
| [[User:Allquixotic|allquixotic]] <br />
| Sean McNamara <br />
| Tiyuk Quellmalz <br />
| OSG: Tiyuk Quellmalz <br />
| -5 <br />
| None <br />
| Bugfixing; networking; performance; data integrity; LSL; auto-backup; null DB (eventual consistency).<br />
|-<br />
| [[User:Orenh|orenh]] <br />
| Oren Hurvitz <br />
| <br />
| Oren Hurvitz (Kitely) <br />
| +2 <br />
| Kitely <br />
| <br />
|-<br />
| [[User:Randomhuman|randomhuman]] <br />
| Kevin Houlihan <br />
| random Radikal <br />
| random human (OSGrid) <br />
| WET/IST <br />
| CrimsonCookie <br />
| RemoteAdmin module; On-demand grids; web integration.<br />
|<br />
|-<br />
| [[User:Oddball Otoole|oddball otoole]]<br />
| J.v.Hogeloon<br />
| Oddball Otoole<br />
| Oddball Otoole (OSGrid<br />
| +1 (The Netherlands<br />
| None<br />
| Building, scripting, testing, social stuff.<br />
|-<br />
| [[User:Pixel|Pixel Tomsen]]<br />
| Christian Kurzhals<br />
| Pixel Tomsen<br />
| Pixel Tomsen OSGrid<br />
| +1 (Germany<br />
| see my profil<br />
| Dev, Building, scripting, sim-hosting, some modules, patches, osgrid<br />
|-<br />
| [[User:kenearlg|kenearlg]]<br />
| Ken Grunke<br />
| Key Grau<br />
| Key Gruin (Osgrid)<br />
| -6 CST<br />
| http://www.osgrid.org/<br />
| testing, moderating, inworld games & recreation, wiki spam control<br />
|}<br />
<br />
== Retired Additional Developers ==<br />
<br />
Additional developers who are no longer working on the OpenSimulator project. Thank you forever for your contributions! <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Fly-man-|Fly-Man-]] <br />
| Laurence <br />
| <br />
| OSGrid: Fly Man <br />
| GMT +1 <br />
| Private Company<br />
| Testing, OpenSimSearch, OpenSimProfile<br />
|-<br />
|}<br />
<br />
[[Category:Development]]<br />
[[Category:Tech Reference]]<br />
[[Category:Help]]</div>
Dz
http://opensimulator.org/wiki/Development_Team
Development Team
2014-01-27T05:23:33Z
<p>Dz: /* Additional Developers/Testers/Contributors */</p>
<hr />
<div>__NOTOC__ {{Quicklinks}} <br />
<br />
== Active Core Developers ==<br />
<br />
Developers who have commit access to our central server, are [http://www.ohloh.net/projects/4753/contributors regular contributors] to the codebase, and have voting rights over development and process issues of the OpenSimulator project. See [[Organization]]. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Adam Frisby|Adam Frisby]] <br />
| Adam Frisby <br />
| Adam Zaius <br />
| <br />
| +8 <br />
| DeepThink Pty Ltd <br />
| Terrain, Performance<br />
|-<br />
| [[User:Chi11ken|chi11ken]] <br />
| Jeff Ames <br />
| Chillken Proto <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Justincc|justincc]] <br />
| Justin Clark-Casey <br />
| Lulworth Beaumont <br />
| Justin Clark-Casey (all other grids) <br />
| 0 <br />
| OSVW Consulting<br />[http://justincc.org/blog justincc's OpenSimulator blog] <br />
| Grid, performance &amp; reliability, inventory (avatar and object), assets, scenes, OARs, etc. Generally speaking, my main interest is to create infrastructure that other people can build on top of.<br />
|-<br />
| [[User:Dahlia|dahlia]] <br />
| T. Hoff <br />
| Dahlia Trimble <br />
| <br />
| -8 / -7 <br />
| Independent <br />
| Collision geometry, various math and physics issues, occasional bug fixes and random enhancements<br />
|-<br />
| [[User:Melanie T|Melanie_T]] <br />
| Melanie <br />
| Melanie Milland <br />
| <br /> <br />
| +1 <br />
| Independent <br />
| Scripting, Prims/Scene, Life, The Universe, and Everything<br />
|-<br />
| [[User:Diva|Diva]] <br />
| Crista Lopes <br />
| Diva Canto <br />
| Crista Lopes / Diva Canto <br />
| -8 <br />
| University of California, Irvine <br />
| Everything, except databases<br />
|-<br />
| [[User:Dslake|dslake]] <br />
| Dan Lake <br />
| Dan Lake <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| Scalability, Performance, Network stack<br />
|-<br />
| [[User:Marck|Marck00]] <br />
| M. Kirsch <br />
| Marck Kjeller <br />
| <br />
| +1 <br />
| Independent <br />
| Everything that catches my attention and that I can get my head around. <br />
| <br />
|-<br />
| cmickeyb <br />
| Mic Bowman <br />
| Mic Bowman <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| <br />
|-<br />
| [[User:BlueWall|BlueWall]] <br />
| James Hughes <br />
| BlueWall Slade <br />
| BlueWall Slade <br />
| -5 <br />
| BlueWall Information Technologies, LLC <br />
| Various parts<br />
|-<br />
| [[User:Nebadon|Nebadon]] <br />
| Michael Emory Cerquoni <br />
| Nebadon Izumi <br />
| Nebadon Izumi <br />
| -7 Arizona <br />
| Oni Kenkon Creations <br />
| Building, Scripting, Testing<br />
|-<br />
| [[User:Snoopy2|Snoopy2]] <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
|<br />
| [http://www.dreamlandmetaverse.com/ http://www.dreamlandmetaverse.com/] <br />
| OpenSim region and grid hosting<br />
|-<br />
| radams<br />
| Robert Adams<br />
| <br />
| <br />
| <br />
| Looking Glass Viewer <br />
| <br />
|}<br />
<br />
<br /><br />
<br />
== Core Developers Following the White Rabbit ==<br />
<br />
Core developers who have temporarily (we hope) gone chasing the white rabbit. They are in all similar to the active core developers, except that they haven't been that active lately, so their voting rights are awaiting their come back. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Lbsa71|lbsa71]] <br />
| Stefan Andersson <br />
| Tribal Skytower <br />
| OSG:Stefan Andersson<br />TN:Stefan Andersson <br />
| +1 <br />
| [http://tribalmedia.se/ Tribal Media AB] <br />
| Web Integration<br />
|-<br />
| [[User:MW|MW]] <br />
| Darren <br />
| Wright Juran <br />
| <br />
| 0 <br />
| <br />
| Everything<br />
|-<br />
| ckrinke <br />
| Charles&nbsp;Krinke <br />
| Charlesk&nbsp;Bing <br />
| <br />
| -8 <br />
| &nbsp; <br />
| Reliability/Grid servers/ll-functions<br />
|-<br />
| [[User:Mikem|mikem]] <br />
| Mike Mazur <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| Independent <br />
| Patches, scripting improvements, LSL compiler<br />
|-<br />
| [[User:HomerHorwitz|homerh]] <br />
| Homer Horwitz <br />
| Homer Horwitz <br />
| <br /> <br />
| +2 <br />
| Independent <br />
| Rev. engineering, "now, that's funny" problems, but still interested in all parts of it<br />
|-<br />
| [[User:Nlin|nlin]] <br />
| N Lin <br />
| Standard Drucker <br />
| <br /> <br />
| +9 <br />
| [http://www.3di.jp/en/ 3Di Inc, Japan]<br />http://www.3di.jp/en/ <br />
| Physics, scripting, more to come<br />
|-<br />
| [[User:Arthursv|arthursv]] <br />
| Arthur Valadares <br />
| <br />
| NONE <br />
| -8 <br />
| University of California, Irvine <br />
| Unit testing, database plugins, bug fixes, general<br />
|-<br />
| [[User:DrScofield|drscofld]] <br />
| Dirk Husemann <br />
| Dr Scofield <br />
| <br />
| +1 <br />
| [http://xyzzyxyzzy.net/ xyzzyxyzzy.net] <br />
| Reliability, networking protocols, inventory, assets, remote control, voice, and pretty much everything else&nbsp;:-) <br />
| <br />
|-<br />
| [[User:Teravus|Teravus]] <br />
| Daniel Olivares <br />
| Teravus Ousley <br />
| <br />
| -5 <br />
| W3z <br />
| Physics &amp; Admin tools, A working sim.<br />
|}<br />
<br />
== Retired Core Developers ==<br />
<br />
Core developers who have transcended our mortal plane, i.e. they are no longer directly engaged with the project. Thank you forever for your contributions! <br />
<br />
* '''Only formerly voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Babblefrog|babblefrog]] <br />
| Brian McBee <br />
| Dogen Coldstream <br />
| Babblefrog Ballistic (osgrid) <br />
| -8 <br />
| Disorganized <br />
| &nbsp;<br />
|-<br />
| [[User:Danx0r|danx0r]] <br />
| Dan Miller <br />
| Albert Pascal <br />
| <br />
| -8 <br />
| squiggle.com <br />
| PHEEZIKS; everything<br />
|-<br />
| Tleiades <br />
| &nbsp; <br />
| Tleiades&nbsp;Hax <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Grid servers/Database<br />
|-<br />
| [[User:Darok|Darok]] <br />
| &nbsp; <br />
| Darok Kaminski <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Physics engines (especially BulletX)<br />
|-<br />
| Gareth / Gwen <br />
| Gareth Nelson <br />
| Gareth Ellison <br />
| Gareth Nelson (on everywhere but SL) <br />
| BST (UTC+1) <br />
| Litesim Ltd <br />
| Grid servers, sim border crossing, avatar animations<br />
|-<br />
| [[User:Dalien|dalien]] <br />
| Dalien Talbot <br />
| Dalien Talbot <br />
| <br />
| +1 <br />
| Mostly TCP-based <br />
| Small fixes; rev.eng./prototyping; nightlies; git-keeper<br />
|-<br />
| [[Alondria]] <br />
| <br />
| Alondria LeFay <br />
| Alondria LeFay (OSGrid) <br />
| -8 <br />
| Independent <br />
| Implementation of LSL functions and other scripting tidbits.<br />
|-<br />
| [[User:SeanDague|sdague]] <br />
| Sean Dague <br />
| Neas Bade <br />
| <br />
| -5 <br />
| IBM <br />
| Database, Linux, Testing, Misc<br />
|-<br />
| [[User:MingChen|MingChen]] <br />
| Mike/Michael Ortman <br />
| Ming Chen <br />
| <br />
| -6 (-5 in Summer) <br />
| DeepThink Pty Ltd <br />
| Estate/Parcel Support/Modules/Keeping things all neat and tidy.<br />
|-<br />
| [[User:Tedd|Tedd]] <br />
| Tedd Hansen <br />
| Tedd Maa <br />
| <br />
| +1 <br />
| Tedd Hansen <br />
| Programming/Scripting/Architecture<br />
|-<br />
| [[User:Adjohn|adjohn]] <br />
| Adam Johnson <br />
| Zeuz Zenovka <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Joha1|joha1]] <br />
| Johan Berntsson <br />
| Joppi Brandenburg <br />
| <br /> <br />
| +9 <br />
| &nbsp; <br />
| Performance, packet handling/libSL<br />
|-<br />
| jhurliman <br />
| John Hurliman <br />
| John Hurliman <br />
| <br />
| <br />
| <br />
|}<br />
<br />
== Wiki Sysops ==<br />
<br />
Along with the core developers, these people help manage the OpenSimulator wiki as well as make other contributions (see Areas of Interest). <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Makopoppo|Makopoppo]] <br />
| Makiko Nomura <br />
| Mako Nozaki <br />
| Everywhere <br />
| +9 Tokyo, Japan <br />
| As an individual developer <br />
| Everything for improving usability and connectability - wiki/issue management, documentation, localization(Japanese), modifying the interface mainly of core modules<br />
|-<br />
| [[User:Fritigern|Fritigern]] <br />
| S-E-C-R-E-T <br />
| Fritigern Gothly <br />
| SecondLife, OSGrid <br />
| +1 GMT <br />
| <br />
| My interests are many, and extremely varied. One thing that i am very interested in, is seeing OpenSimulator grow, mature, and develop into something that really does rival SL/LL.<br />
|}<br />
<br />
== Additional Developers/Testers/Contributors ==<br />
<br />
These people have contributed and/or are contributing bug reports, patches, testing, and all sorts of other goodies to the project. <br /> '''Newcomers please add yourself to bottom of the list!''' <br /> <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Jtclark48|jclark4]] <br />
| Jay Clark <br />
| Jay Clarke <br />
| <br />
| -5 <br />
| IBM <br />
| Physics, Grid Host, AI, Scripting, Testing<br />
|-<br />
| [[User:AdamStevenson|BigFootAg]] <br />
| Adam Stevenson <br />
| Adamus Petrov <br />
| <br />
| -6 <br />
| Texas A&amp;M University <br />
| AI, Skynet, Evolving Systems, Biology<br />
|-<br />
| [[User:Jeff1564|Jeff1564]] <br />
| Jeff <br />
| Potter Taurog <br />
| Potter Taurog <br />
| -8 <br />
| http://myopengrid.com <br />
| Building, Scripting, Testing<br />
|-<br />
| Rock_Vacirca <br />
| Colin Withers <br />
| Rock Vacirca <br />
| &nbsp; <br />
| +1 <br />
| http://rock-vacirca.blogspot.com <br />
| Testing, building, scripting, maintaining an opensim blog.<br />
|-<br />
| simsim <br />
| caocao <br />
| &nbsp; <br />
| &nbsp; <br />
| +9 <br />
| &nbsp; <br />
| Testing whole functions of OpenSimulator system,working with OpenSim-Engine,reporting on OpenSimulator<br />
|-<br />
| [[User:Vicero Lambert|Vicero Lambert]] <br />
| &nbsp; <br />
| &nbsp; <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
| [[User:Magi|Magi]] <br />
| Andy Agnew <br />
| Magi Merlin <br />
| <br />
| +10 <br />
| Spun Pty Ltd <br />
| 3D Web Integration, Database stuff and playing with the odds and ends box.<br />
|-<br />
| [[User:ClarkZone|ClarkZone]] <br />
| Troy Admin(@ClarkZone) <br />
| Troy Childs <br />
| Troy Admin (ClarkZone) <br />
| -5 <br />
| Http://clarkzone.dyndns.org <br />
| Tester and Grid Host<br />
|-<br />
| [[User:Aiaustin|aiaustin]] <br />
| Ai Austin <br />
| Ai Austin <br />
| Ai Austin <br />
| +0 <br />
| AIAI, Virtual University of Edinburgh<br />http://www.aiai.ed.ac.uk/~ai/<br />http://vue.ed.ac.uk/openvue/ <br />
| Windows tests<br />Content testing<br />Use of multiple VWs<br />
|-<br />
| Marc Manders <br />
| Marc Manders <br />
| &nbsp; <br />
| &nbsp; <br />
| +6 <br />
| marcmanders@gmail.com <br />
| Creative features<br />
|-<br />
| [[User:Balthazar|balthazar]] <br />
| Trevor Brooks <br />
| Balthazar Sin <br />
| <br />
| -5 <br />
| None <br />
| Terrains, testing and some small coding tasks<br />
|-<br />
| [[User:Jimbo2120|jimbo2120]] <br />
| Michael Osias <br />
| Illuminous Beltran <br />
| <br />
| -5 <br />
| IBM <br />
| Grid, AI, Skynet, coding and testing<br />
|-<br />
| ZeroPoint <br />
| &nbsp; <br />
| Guilderoy&nbsp;Dench <br />
| <br />
| -5 <br />
| &nbsp; <br />
| Programming/Database<br />
|-<br />
| [[User:DerekTang|DerekTang]] <br />
| Derek Tang <br />
| Derek Timeless <br />
| Derek Tang (ChineseGrid) <br />
| +8 <br />
| http://ChineseGrid.net <br />
| Running a public WINDOWS sim for testing, Docs, Helping Chinese users to enjoy OpenSim; building Chinese OpenSimulator communities. In construction...<br />
|-<br />
| [[User:TayB|TayB]] <br />
| Earl Balai <br />
| Taylor Dae <br />
| <br />
| -10 <br />
| WhynGrid <br />
| Grid Host,Networking,Contributions &amp; Testing.<br />
|-<br />
| [[User:JamieDav|JamieDav]] <br />
| Jamie David <br />
| Jamie David <br />
| <br />
| +7 <br />
| Forum <br />
| Grid, Sim, Avitar, Functionality<br />
|-<br />
| [[User:Krtaylor|Krtaylor]] <br />
| Kurt Taylor <br />
| Kurt Stringer <br />
| <br />
| -6 <br />
| IBM <br />
| Grid, Networking, Monitoring, Scripting, Inventory, Testing<br />
|-<br />
| [[User:Nink|Nink]] <br />
| Peter Finn <br />
| Nink Noonan <br />
| <br />
| -5 <br />
| IBM <br />
| Disruptive Influence.<br />
|-<br />
| [[User:Bruce|Bruce]] <br />
| Bruce Meerson <br />
| Bruce Meerson <br />
| <br />
| +8 <br />
| HiPiHi <br />
| Watching.<br />
|-<br />
| [[User:Darb|DarbD]] <br />
| Brian B. Quinn <br />
| Darb Dabney <br />
| regions<br />near Marin <br />
| PST/SLT (-7 or -8) <br />
| County of Marin, California<br /> http://blog.3dmap.me <br />
| LiDAR-based sculpties, real-world terrain, <br />pursuit of civic paraverses, virtual Emergency Operations Centers<br />
|-<br />
| [[User:Charlie Omega|CharlieO]] <br />
| Dan <br />
| Charlie Omega <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| Mild coding/tweaking/simple feature adds, Stress testing/break stuff, Testing limits of existing code. Making sure [[LSL Status]] is up to date<br />
|-<br />
| oobscure <br />
| &nbsp; <br />
| Opensource Obscure <br />
| <br />
| +1 <br />
| http://www.opensim.it <br />
| Running a public Linux sim for testing, Docs, Helping italian users, Building opensim communities, Watching<br />
|-<br />
| pitman <br />
| Mike Pitman <br />
| Rez Tone <br />
| <br />
| &nbsp; <br />
| IBM <br />
| Scientific visualization schemes, virt world product design, persistant workspaces, virt world based big biz<br />
|-<br />
| Shenlei <br />
| Shenlei Winkler <br />
| Shenlei Flasheart, Shenlei Winkler <br />
| <br />
| &nbsp; <br />
| Fashion Research Institute <br />
| Product Design and Development, Apparel industry, and o yes, I wrote the book&nbsp;;)<br />
|-<br />
| cmu <br />
| Christopher Mumme <br />
| Snook Destiny <br />
| <br />
| +1 <br />
| http://www.cmu-develop.de/ and research group "Collaboration Systems and CSCW" at Clausthal University of Technology <br />
| Testing OpenSim, working with OpenSim-Engine, reporting on OpenSimulator<br />
|-<br />
| [[Silpol]] <br />
| Andriy Tymchenko <br />
| Andy Tir <br />
| <br />
| EET (+2/3) <br />
| http://silpol.blogspot.com/ (also visible at Nokia) <br />
| Highly uncoordinated mess with elements of palace games, under-table diplomacy, rebellion, coup d'état and mutiny. optionally pirate<br />
|-<br />
| [[User:Grumly|Grumly]] <br />
| <br />
| Forest Klaar <br />
| Grumly TheBear <br />
| GMT+1 <br />
| .NET MCAD Dev/Arch/Trainer http://www.devoteam.com <br />
| Trying to get into OpenSimulator code for now. Particularly interrested in data persistence. blog (Hello, Avatar!): http://lslblog.free.fr<br />
|-<br />
| [[User:DaTwitch|DaTwitch]] <br />
| James G. Stallings II <br />
| <br />Lazarus Longstaff <br />
| Hiro Protagonist (OSGrid) <br />
| -5 <br />
| House Husband <br />
| OSGrid Region owner, OSGrid Operator,<br />Forum Admin, sometime wiki editor<br />
|-<br />
| gryc <br />
| Gryc Ueusp <br />
| Gryc Uriza <br />
| Gryc Uriza(OSGrid) <br />
| -6 <br />
| <br />
| PHP scripting, web interfaces, interconnectivity, cross-platformedness<br />
|-<br />
| [[User:Phrearch|Phrearch]] <br />
| Jeroen van Veen <br />
| Phrearch Miles <br />
| Phrearch Miles(OSGrid) <br />
| Amsterdam/Paris <br />
| <br />
| HWIOS, WiXTD, Wikidoc, Moo, User interfaces<br />
|-<br />
| [[User:Burnman|Burnman]] <br />
| Allen <br />
| Burnman Bedlam <br />
| <br />
| Boston, USA <br />
| <br />
| Testing, testing, and more testing! Getting familiar with the source, interested in all aspects of the project.<br />
|-<br />
| [[User:Krisbfunk|krisbfunk]] <br />
| Kris Bulman <br />
| Krisbfunk Vought <br />
| Krisbfunk Nocturnal(OSGrid) <br />
| PE, Canada (-4) <br />
| Edactive Technologies<br />NocturnalEye Productions<br />UPEI <br />
| Currently: Testing, bug reports, wiki updating, building on OSGrid<br />
|-<br />
| [[User:HashBox|HashBox]] <br />
| &nbsp; <br />
| Sibariel Darkstone <br />
| Sibariel Darkstone (OSGrid) <br />
| New Zealand (+12) <br />
| <br />
| Testing, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Kinoc|Kinoc]] <br />
| Kino Coursey <br />
| Daxxon Jaxxon <br />
| Daxxon Kinoc (OSgrid) <br />
| -6 <br />
| Daxtron Laboratories <br /> http://www.daxtron.com<br /> University of North Texas <br />
| AI, Semantic web, Ontologies, Natural Laanguage Processing, Cyc, Bots, NPC<br />
|-<br />
| [[User:Trapuh|trapuh]] <br />
| Pedro Ribeiro <br />
| Vaiten Forder <br />
| <br />
| GMT <br />
| University Student, Escola Superior de Educação de Viseu, Portugal <br />
| Testing, eventual bug reports and wiki. Music, web/digital arts and php+sql.<br />
|-<br />
| [[User:SonicViz|SonicViz]] <br />
| Paul Cohen <br />
| Komuso Tokugawa <br />
| <br />
| +9 <br />
| Http://sonicviz.com <br />
| Audio/Music, Interactive Music, Control Protocols, Interfaces, VisualFX, Procedural animation/Generative systems + testing and general dev<br />
|-<br />
| [[User:Mokele|mokele]] <br />
| Scott Norman <br />
| Mokelembembe Mokeev <br />
| <br />
| -8 (Southern California) <br />
| Web Developer (PHP and MySQL) <br />
| Interested in seeing running on PowerPC Macs which it is. So, when I can, I'll compile and test on PowerPC Mac (PowerBook G4) and submit reports and then update the wiki if need on installing on Mac. Also have a Ubuntu 7.10 server that I can do testing on too.<br />
|-<br />
| [[User:Devalnor|devalnor]] <br />
| Devalnor <br />
| M. Watkin <br />
| <br />
| +1 (Belgium) <br />
| <br />
| Small Patch code, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Ezekiel|Ezekiel]] <br />
| Ezekiel <br />
| Ezekiel Zabelin <br />
| <br />
| +1 <br />
| http://www.yosims.com <br />
| Concepts, business aspects of virtual worlds - web developer (PHP, MySQL, Javascript, LSL)<br />
|-<br />
| [[User:Buggmaster|Buggmaster]] <br />
| Mike D <br />
| Bug Master <br />
| None <br />
| -8 <br />
| http://www.adultmetaverse.com <br />
| Grid, Data/Web PHP/PERL/MySQL<br />
|-<br />
| [[User:Nixnerd|nixnerd]] <br />
| <br />
| Dangerously Moody <br />
| None <br />
| GMT <br />
| http://www.integratedtechnologies.eu <br />
| Cross Platform Testing, Feedback, Bug Reporting<br />
|-<br />
| [[User:MoHax|mohax]] <br />
| Mo Hax <br />
| Mo Hax <br />
| <br />
| -5 Eastern <br />
| IBM <br />
| Testing, Feedback, Content Contributions, Bug Reporting, Documenting, Development<br />
|-<br />
| [[User:Webmage|webmage]] <br />
| webmage <br />
| Leyla Masala <br />
| Web Mage <br />
| +1 <br />
| IBM <br />
| Testing, terrain<br />
|-<br />
| [[User:NLStitch|NLStitch]] <br />
| Marijn Oosterveld <br />
| Stitch Seale <br />
| NYA <br />
| GMT +1 Amsterdam <br />
| Twingate Systems (http://www.twingate.nl)<br />HanzeHogeschool Groningen, Netherlands <br />
| Programming, Photography, AI<br />
|-<br />
| [[User:Ideia Boa|Ideia Boa]] <br />
| Joao Lopes <br />
| Ideia Boa <br />
| Ideia Boa or Boa Ideia in some grids <br />
| GTM+1 Stockholm/Sweden <br />
| WorldSimTERRA - Virtual World that speaks Portuguese too<br />http://www.worldsimterra.com <br />
| Testing and more testing! Updating the original wiki and translating the OpenSimulator Wiki into Portuguese and reporting on OpenSimulator<br />
|-<br />
| [[User:Lulurun|lulurun]] <br />
| liu <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| 3Di Inc, Japan <br />http://www.3di.jp <br />
| Patches, openid, server performance, UGAI<br />
|-<br />
| [[User:Carlosroundel|Carlosrounde]] <br />
| Carlosroundel <br />
| Carlos Roundel <br />
| <br /> <br />
| +1 <br />
| Cyberlandia Italy<br />http://www.cyberlandia.net <br />
| Grid, programmer, database, tester<br />
|-<br />
| [[User:Mikebert|Mikebert]] <br />
| Michael Strunck <br />
| Mikebert Miles <br />
| Mikebert M34 <br />
| +1 <br />
| OpenSIM Wiki, Germany<br />http://www.opensim.de <br />
| German Wiki, Translater, Server Performance (Linux/Windows), Tester, Feedback, Bug Reporting, Server-Hosting<br />
|-<br />
| Taoki <br />
| Mircea Kitsune / Taoki Vixen <br />
| Mircea Kitsune (OSGrid) / Mircea Lobo (LL grid) <br />
| <br /> <br />
| GMT +2 <br />
| <br /> <br />
| Usually testing and bug reporting but I also make smaller patches where I know what to do.<br />
|-<br />
| [[User:Patnad|Patnad]] <br />
| Patrick <br />
| Patnad Babii <br />
| Patnad Babii (OSGrid) <br />
| GMT -5 <br />
| RezzMe Technologies<br />http://www.rezzme.com <br />
| Bug testing and reporting, I code C# and have submitted a few patches<br />
|-<br />
| [[User:^DarkMan|^DarkMan]] <br />
| Brian Adair <br />
| Patrick Ouachita <br />
| Brian Adair &#124; Patrick Meta <br />
| -6 CST <br />
| RealMetaLife &#124; B&amp;H Networking <br />
| Building, Scripting, Testing, etc.<br />
|-<br />
| [[User:Tlaukkan|Tommi Laukkanen]] <br />
| Tommi Laukkanen <br />
| &nbsp; <br />
| Tommi Laukkanen <br />
| +2 GMT <br />
| http://www.bubblecloud.org <br />
| Protocols ([http://www.bubblecloud.org MXP]), NHibernate, Scrip API, Map Generation, Bug Fixes, Grid Hosting<br />
|-<br />
| [[User:Mystical|Mystical]] <br />
| Kevin Tweedy <br />
| Mystical Demina <br />
| Mystical Demina <br />
| -5 <br />
| Extreme Reality Grid<br />http://www.XRGrid.com <br />
| Windows Communication Framework, Windows Workflow,Entity Framework, MSSQL<br />Enhancements,Commerce, Content,DotNetNuke based portal, development services<br />
|-<br />
| [[User:Godfrey|Godfrey]] <br />
| Jeff Lee <br />
| Warin Cascabel <br />
| <br />
| -5 (EST5EDT) <br />
| <br />
| Testing, minor bugfixes. Scripting, building, animating<br />
|-<br />
| Jamenai <br />
| Christopher Händler <br />
| Jamenai Luik <br />
| Jamenai Luik <br />
| +1 <br />
| Playneko Grid &#124; XIMDEX Jamenai<br />http://www.playneko.de<br />http://www.ximdex.de <br />
| Performance,Bug Reporting, Hosting, Grid-Owner,(PHP, MySQL, Perl, JavaScript, LSL)<br />
|-<br />
| [[User:Bikcmp|bikcmp]] <br />
| Jason <br />
| Jake1500 Allen <br />
| Jason Helios (The Helios Grid) <br />
| EST <br />
| Blue Software <br />
| Search, groups, land, and currency<br />
|-<br />
| [[User:Mark.malewski|Slipaway]] <br />
| Mark Malewski <br />
| Chris Rock <br />
| <br />
| -6 (-5 during summer - CDT) <br />
| NexTECH / Joopla <br />
| Web development &amp; systems integration, terrain, WIKI documentation, tutorials, testing, bug reporting and feedback.<br />
|-<br />
| barakademi <br />
| Steve Topp <br />
| barakademi Barzane <br />
| same avi on baragrid OSgrid Grid4us sciencesim <br />
| utc+1 (CET) paris <br />
| http://xbot-sl.barakademi.org http://vps.barakademi.org/oswi http://vps.barakademi.org/oswi/loginscreen.php <br />
| Music LiveMusic MetaverseMusic Opensim Libomv Mono-2.4 Linux (suse,debian,ubuntu) Admin Scripting Automating Development Intergration php mysql bash nant +++<br />
|-<br />
| [[User:Robert d|robert_d]] <br />
| Robert Dzikowski <br />
| <br />
| OSGrid: robert_d 13 <br />
| UTC+1 <br />
| [http://blog.rd-it.net http://blog.rd-it.net] <br />
| Region Modules, Tutorials<br />
|-<br />
| john_ <br />
| John&nbsp;Moyer <br />
| VAJohn&nbsp;GeekSquad or&nbsp;Matthew&nbsp;Kendal <br />
| <br />
| -5 <br />
| Best&nbsp;Buy/Geek&nbsp;Squad <br />
| Tester<br />
|-<br />
| [[User:W!cKeD|_WicKeD]] <br />
| Maik <br />
| Maik Galaxy <br />
| El Diablo <br />
| +1 Germany <br />
| Creatio Inc. / [http://www.OpenSimGerman.us/ OpenSimGerman.us] <br />
| German Support, Translator, Building, Scripting, Testing, Hosting<br />
|-<br />
| [[User:Stevie Wakowski|Stevie Wakowksi]] <br />
| Steve Roberts <br />
| Stevie Wakowski <br />
| <br />
| +10 Australia <br />
| IBM <br />
| OpenSimulator builds, Linux, Modrex, bug reporting, evangalist for OpenSimulator in business applications.<br />
|-<br />
| Revolution <br />
| Matthew <br />
| Revolution Smythe <br />
| Revolution Smythe <br />
| -6 Central USA <br />
| None <br />
| Script engine, physics engine, general odd bugs, interesting and odd things<br />
|-<br />
| [[User:ClemsonGS|clemsonGS]] <br />
| Brian Cass <br />
| BC Sands <br />
| Brian Cass (VWC Grid) <br />
| -5 <br />
| http://www.cvwconline.org/ <br />
| Developing virtual worlds for use in higher education<br />
|-<br />
| <br />
| AlexRa <br />
| <br />
| <br />
| <br />
| Independent <br />
| <br />
|-<br />
| <br />
| <br />
| Mikko Pallari <br />
| <br />
| <br />
| Realxtend <br />
| <br />
|-<br />
| <br />
| StrawberryFride <br />
| Chris Hart <br />
| <br />
| <br />
| ReactionGrid <br />
| <br />
|-<br />
| [[User:RemedyTomm|RemedyTomm]] <br />
| Tom Grimshaw <br />
| Tomm Remedy <br />
| KGrid: Casper Warden OSGrid: Tomm Remedy <br />
| UTC+0 (BST) <br />
| Remedy Communications <br />
| Texture pipeline, Groups, ObjectUpdates<br />
|-<br />
| <br />
| <br />
| Rob Smart <br />
| <br />
| <br />
| IBM <br />
| <br />
|-<br />
| MicheilMerlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| -6 <br />
| Independent <br /> [http://www.iliveisl.com/ http://www.iliveisl.com/] <br />
| Scripting, patches, and testcases<br />
|-<br />
| Pato Donald <br />
| Pato Donald <br />
| Morgam Biedermann <br />
| Pato Donald <br />
| -3 <br />
| Independent [http://www.matheusmk3.co.cc/ http://www.matheusmk3.co.cc/ <br />
| Groups, Scripts, Physics, Communication, Integration<br />
|-<br />
| <br />
| Sera Marx <br />
| Darkfire Soulstar <br />
| <br />
| +12 <br />
| Radiance promotions <br />
| Grid Host, Commissioner. ~ Anyone looking for work related to the development of Opensimulator or Viewers please contact me. Any work undertaken for me will be returned to Opensimulator unless made strictly for my Grid<br />
|-<br />
|[[User:dz|dz]] <br />
| Doug Osborn <br />
| ydoo magic<br />
| Doug Osborn @ScienceSim & MOSES grids<br />
| PST/SLT (-7 or -8) <br />
| CEO OpenSimian <br />
| Performance testing, advanced scripting, high prim count builds, Client and server side bots, Animation Overrides, running in-world conferences.<br />
|-<br />
| [[User:Hallow Palmer|Hallow Palmer]] <br />
| Markus <br />
| Hallow Palmer <br />
| <br /> <br />
| +1 <br />
| Grid4Us<br />http://www.grid4us.net <br />
| Server Performance (Windows), Tester, Feedback, Business concepts,Bug Reporting, Server-Hosting<br />
|-<br />
| [[User:LenaVanilli|LenaVanilli]] <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| +1 Germany <br />
| [http://www.hypergrid.org http://www.hypergrid.org] <br />
| Grid-Management, Testing Testing Testing, Region Hosting<br />
|-<br />
| [[User:Aduffy70|aduffy70]] <br />
| Aaron Duffy <br />
| Aeran Stipe <br />
| Aaron Duffy @ScienceSim <br />
| -7 <br />
| USU <br />
| Scientific visualization &amp; education, Region modules, Heavily scripted regions<br />
|-<br />
| <br />
| Erich Bremer <br />
| Erich Bremer <br />
| <br />
Erich Bremer@OSGrid <br />
<br />
| -5 <br />
| http://www.ebremer.com <br />
| Semantic Web, Data Visualization<br />
|-<br />
| [[User:MarkIDCAS|MarkIDCAS]] <br />
| Mark Bannon <br />
| Mark IDCAS <br />
| 3D Grid Association, AtMeeting, Valhalla Virtual and IDCAS. <br />
| GMT <br />
| [http://www.valhallavirtual.com http://www.valhallavirtual.com] <br />
| Grid Management &amp; systems integration. Scripting. WIKI documentation, tutorials, bug reporting and feedback.<br />
|-<br />
| [[User:Allquixotic|allquixotic]] <br />
| Sean McNamara <br />
| Tiyuk Quellmalz <br />
| OSG: Tiyuk Quellmalz <br />
| -5 <br />
| None <br />
| Bugfixing; networking; performance; data integrity; LSL; auto-backup; null DB (eventual consistency).<br />
|-<br />
| [[User:Orenh|orenh]] <br />
| Oren Hurvitz <br />
| <br />
| Oren Hurvitz (Kitely) <br />
| +2 <br />
| Kitely <br />
| <br />
|-<br />
| [[User:Randomhuman|randomhuman]] <br />
| Kevin Houlihan <br />
| random Radikal <br />
| random human (OSGrid) <br />
| WET/IST <br />
| CrimsonCookie <br />
| RemoteAdmin module; On-demand grids; web integration.<br />
|<br />
|-<br />
| [[User:Oddball Otoole|oddball otoole]]<br />
| J.v.Hogeloon<br />
| Oddball Otoole<br />
| Oddball Otoole (OSGrid<br />
| +1 (The Netherlands<br />
| None<br />
| Building, scripting, testing, social stuff.<br />
|-<br />
| [[User:Pixel|Pixel Tomsen]]<br />
| Christian Kurzhals<br />
| Pixel Tomsen<br />
| Pixel Tomsen OSGrid<br />
| +1 (Germany<br />
| see my profil<br />
| Dev, Building, scripting, sim-hosting, some modules, patches, osgrid<br />
|-<br />
| [[User:kenearlg|kenearlg]]<br />
| Ken Grunke<br />
| Key Grau<br />
| Key Gruin (Osgrid)<br />
| -6 CST<br />
| http://www.osgrid.org/<br />
| testing, moderating, inworld games & recreation, wiki spam control<br />
|}<br />
<br />
== Retired Additional Developers ==<br />
<br />
Additional developers who are no longer working on the OpenSimulator project. Thank you forever for your contributions! <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Fly-man-|Fly-Man-]] <br />
| Laurence <br />
| <br />
| OSGrid: Fly Man <br />
| GMT +1 <br />
| Private Company<br />
| Testing, OpenSimSearch, OpenSimProfile<br />
|-<br />
|}<br />
<br />
[[Category:Development]]<br />
[[Category:Tech Reference]]<br />
[[Category:Help]]</div>
Dz
http://opensimulator.org/wiki/Development_Team
Development Team
2014-01-27T05:20:07Z
<p>Dz: /* Additional Developers/Testers/Contributors */</p>
<hr />
<div>__NOTOC__ {{Quicklinks}} <br />
<br />
== Active Core Developers ==<br />
<br />
Developers who have commit access to our central server, are [http://www.ohloh.net/projects/4753/contributors regular contributors] to the codebase, and have voting rights over development and process issues of the OpenSimulator project. See [[Organization]]. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Adam Frisby|Adam Frisby]] <br />
| Adam Frisby <br />
| Adam Zaius <br />
| <br />
| +8 <br />
| DeepThink Pty Ltd <br />
| Terrain, Performance<br />
|-<br />
| [[User:Chi11ken|chi11ken]] <br />
| Jeff Ames <br />
| Chillken Proto <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Justincc|justincc]] <br />
| Justin Clark-Casey <br />
| Lulworth Beaumont <br />
| Justin Clark-Casey (all other grids) <br />
| 0 <br />
| OSVW Consulting<br />[http://justincc.org/blog justincc's OpenSimulator blog] <br />
| Grid, performance &amp; reliability, inventory (avatar and object), assets, scenes, OARs, etc. Generally speaking, my main interest is to create infrastructure that other people can build on top of.<br />
|-<br />
| [[User:Dahlia|dahlia]] <br />
| T. Hoff <br />
| Dahlia Trimble <br />
| <br />
| -8 / -7 <br />
| Independent <br />
| Collision geometry, various math and physics issues, occasional bug fixes and random enhancements<br />
|-<br />
| [[User:Melanie T|Melanie_T]] <br />
| Melanie <br />
| Melanie Milland <br />
| <br /> <br />
| +1 <br />
| Independent <br />
| Scripting, Prims/Scene, Life, The Universe, and Everything<br />
|-<br />
| [[User:Diva|Diva]] <br />
| Crista Lopes <br />
| Diva Canto <br />
| Crista Lopes / Diva Canto <br />
| -8 <br />
| University of California, Irvine <br />
| Everything, except databases<br />
|-<br />
| [[User:Dslake|dslake]] <br />
| Dan Lake <br />
| Dan Lake <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| Scalability, Performance, Network stack<br />
|-<br />
| [[User:Marck|Marck00]] <br />
| M. Kirsch <br />
| Marck Kjeller <br />
| <br />
| +1 <br />
| Independent <br />
| Everything that catches my attention and that I can get my head around. <br />
| <br />
|-<br />
| cmickeyb <br />
| Mic Bowman <br />
| Mic Bowman <br />
| ScienceSim <br />
| -8 / -7 <br />
| Intel <br />
| <br />
|-<br />
| [[User:BlueWall|BlueWall]] <br />
| James Hughes <br />
| BlueWall Slade <br />
| BlueWall Slade <br />
| -5 <br />
| BlueWall Information Technologies, LLC <br />
| Various parts<br />
|-<br />
| [[User:Nebadon|Nebadon]] <br />
| Michael Emory Cerquoni <br />
| Nebadon Izumi <br />
| Nebadon Izumi <br />
| -7 Arizona <br />
| Oni Kenkon Creations <br />
| Building, Scripting, Testing<br />
|-<br />
| [[User:Snoopy2|Snoopy2]] <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
| Snoopy Pfeffer <br />
|<br />
| [http://www.dreamlandmetaverse.com/ http://www.dreamlandmetaverse.com/] <br />
| OpenSim region and grid hosting<br />
|-<br />
| radams<br />
| Robert Adams<br />
| <br />
| <br />
| <br />
| Looking Glass Viewer <br />
| <br />
|}<br />
<br />
<br /><br />
<br />
== Core Developers Following the White Rabbit ==<br />
<br />
Core developers who have temporarily (we hope) gone chasing the white rabbit. They are in all similar to the active core developers, except that they haven't been that active lately, so their voting rights are awaiting their come back. <br />
<br />
* '''Only voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Lbsa71|lbsa71]] <br />
| Stefan Andersson <br />
| Tribal Skytower <br />
| OSG:Stefan Andersson<br />TN:Stefan Andersson <br />
| +1 <br />
| [http://tribalmedia.se/ Tribal Media AB] <br />
| Web Integration<br />
|-<br />
| [[User:MW|MW]] <br />
| Darren <br />
| Wright Juran <br />
| <br />
| 0 <br />
| <br />
| Everything<br />
|-<br />
| ckrinke <br />
| Charles&nbsp;Krinke <br />
| Charlesk&nbsp;Bing <br />
| <br />
| -8 <br />
| &nbsp; <br />
| Reliability/Grid servers/ll-functions<br />
|-<br />
| [[User:Mikem|mikem]] <br />
| Mike Mazur <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| Independent <br />
| Patches, scripting improvements, LSL compiler<br />
|-<br />
| [[User:HomerHorwitz|homerh]] <br />
| Homer Horwitz <br />
| Homer Horwitz <br />
| <br /> <br />
| +2 <br />
| Independent <br />
| Rev. engineering, "now, that's funny" problems, but still interested in all parts of it<br />
|-<br />
| [[User:Nlin|nlin]] <br />
| N Lin <br />
| Standard Drucker <br />
| <br /> <br />
| +9 <br />
| [http://www.3di.jp/en/ 3Di Inc, Japan]<br />http://www.3di.jp/en/ <br />
| Physics, scripting, more to come<br />
|-<br />
| [[User:Arthursv|arthursv]] <br />
| Arthur Valadares <br />
| <br />
| NONE <br />
| -8 <br />
| University of California, Irvine <br />
| Unit testing, database plugins, bug fixes, general<br />
|-<br />
| [[User:DrScofield|drscofld]] <br />
| Dirk Husemann <br />
| Dr Scofield <br />
| <br />
| +1 <br />
| [http://xyzzyxyzzy.net/ xyzzyxyzzy.net] <br />
| Reliability, networking protocols, inventory, assets, remote control, voice, and pretty much everything else&nbsp;:-) <br />
| <br />
|-<br />
| [[User:Teravus|Teravus]] <br />
| Daniel Olivares <br />
| Teravus Ousley <br />
| <br />
| -5 <br />
| W3z <br />
| Physics &amp; Admin tools, A working sim.<br />
|}<br />
<br />
== Retired Core Developers ==<br />
<br />
Core developers who have transcended our mortal plane, i.e. they are no longer directly engaged with the project. Thank you forever for your contributions! <br />
<br />
* '''Only formerly voted in developers are listed here, please do not list yourself'''<br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Babblefrog|babblefrog]] <br />
| Brian McBee <br />
| Dogen Coldstream <br />
| Babblefrog Ballistic (osgrid) <br />
| -8 <br />
| Disorganized <br />
| &nbsp;<br />
|-<br />
| [[User:Danx0r|danx0r]] <br />
| Dan Miller <br />
| Albert Pascal <br />
| <br />
| -8 <br />
| squiggle.com <br />
| PHEEZIKS; everything<br />
|-<br />
| Tleiades <br />
| &nbsp; <br />
| Tleiades&nbsp;Hax <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Grid servers/Database<br />
|-<br />
| [[User:Darok|Darok]] <br />
| &nbsp; <br />
| Darok Kaminski <br />
| <br />
| +1 <br />
| &nbsp; <br />
| Physics engines (especially BulletX)<br />
|-<br />
| Gareth / Gwen <br />
| Gareth Nelson <br />
| Gareth Ellison <br />
| Gareth Nelson (on everywhere but SL) <br />
| BST (UTC+1) <br />
| Litesim Ltd <br />
| Grid servers, sim border crossing, avatar animations<br />
|-<br />
| [[User:Dalien|dalien]] <br />
| Dalien Talbot <br />
| Dalien Talbot <br />
| <br />
| +1 <br />
| Mostly TCP-based <br />
| Small fixes; rev.eng./prototyping; nightlies; git-keeper<br />
|-<br />
| [[Alondria]] <br />
| <br />
| Alondria LeFay <br />
| Alondria LeFay (OSGrid) <br />
| -8 <br />
| Independent <br />
| Implementation of LSL functions and other scripting tidbits.<br />
|-<br />
| [[User:SeanDague|sdague]] <br />
| Sean Dague <br />
| Neas Bade <br />
| <br />
| -5 <br />
| IBM <br />
| Database, Linux, Testing, Misc<br />
|-<br />
| [[User:MingChen|MingChen]] <br />
| Mike/Michael Ortman <br />
| Ming Chen <br />
| <br />
| -6 (-5 in Summer) <br />
| DeepThink Pty Ltd <br />
| Estate/Parcel Support/Modules/Keeping things all neat and tidy.<br />
|-<br />
| [[User:Tedd|Tedd]] <br />
| Tedd Hansen <br />
| Tedd Maa <br />
| <br />
| +1 <br />
| Tedd Hansen <br />
| Programming/Scripting/Architecture<br />
|-<br />
| [[User:Adjohn|adjohn]] <br />
| Adam Johnson <br />
| Zeuz Zenovka <br />
| <br /> <br />
| +9 <br />
| [http://www.genkii.com Genkii] <br />
| <br /><br />
|-<br />
| [[User:Joha1|joha1]] <br />
| Johan Berntsson <br />
| Joppi Brandenburg <br />
| <br /> <br />
| +9 <br />
| &nbsp; <br />
| Performance, packet handling/libSL<br />
|-<br />
| jhurliman <br />
| John Hurliman <br />
| John Hurliman <br />
| <br />
| <br />
| <br />
|}<br />
<br />
== Wiki Sysops ==<br />
<br />
Along with the core developers, these people help manage the OpenSimulator wiki as well as make other contributions (see Areas of Interest). <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Makopoppo|Makopoppo]] <br />
| Makiko Nomura <br />
| Mako Nozaki <br />
| Everywhere <br />
| +9 Tokyo, Japan <br />
| As an individual developer <br />
| Everything for improving usability and connectability - wiki/issue management, documentation, localization(Japanese), modifying the interface mainly of core modules<br />
|-<br />
| [[User:Fritigern|Fritigern]] <br />
| S-E-C-R-E-T <br />
| Fritigern Gothly <br />
| SecondLife, OSGrid <br />
| +1 GMT <br />
| <br />
| My interests are many, and extremely varied. One thing that i am very interested in, is seeing OpenSimulator grow, mature, and develop into something that really does rival SL/LL.<br />
|}<br />
<br />
== Additional Developers/Testers/Contributors ==<br />
<br />
These people have contributed and/or are contributing bug reports, patches, testing, and all sorts of other goodies to the project. <br /> '''Newcomers please add yourself to bottom of the list!''' <br /> <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Jtclark48|jclark4]] <br />
| Jay Clark <br />
| Jay Clarke <br />
| <br />
| -5 <br />
| IBM <br />
| Physics, Grid Host, AI, Scripting, Testing<br />
|-<br />
| [[User:AdamStevenson|BigFootAg]] <br />
| Adam Stevenson <br />
| Adamus Petrov <br />
| <br />
| -6 <br />
| Texas A&amp;M University <br />
| AI, Skynet, Evolving Systems, Biology<br />
|-<br />
| [[User:Jeff1564|Jeff1564]] <br />
| Jeff <br />
| Potter Taurog <br />
| Potter Taurog <br />
| -8 <br />
| http://myopengrid.com <br />
| Building, Scripting, Testing<br />
|-<br />
| Rock_Vacirca <br />
| Colin Withers <br />
| Rock Vacirca <br />
| &nbsp; <br />
| +1 <br />
| http://rock-vacirca.blogspot.com <br />
| Testing, building, scripting, maintaining an opensim blog.<br />
|-<br />
| simsim <br />
| caocao <br />
| &nbsp; <br />
| &nbsp; <br />
| +9 <br />
| &nbsp; <br />
| Testing whole functions of OpenSimulator system,working with OpenSim-Engine,reporting on OpenSimulator<br />
|-<br />
| [[User:Vicero Lambert|Vicero Lambert]] <br />
| &nbsp; <br />
| &nbsp; <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
| [[User:Magi|Magi]] <br />
| Andy Agnew <br />
| Magi Merlin <br />
| <br />
| +10 <br />
| Spun Pty Ltd <br />
| 3D Web Integration, Database stuff and playing with the odds and ends box.<br />
|-<br />
| [[User:ClarkZone|ClarkZone]] <br />
| Troy Admin(@ClarkZone) <br />
| Troy Childs <br />
| Troy Admin (ClarkZone) <br />
| -5 <br />
| Http://clarkzone.dyndns.org <br />
| Tester and Grid Host<br />
|-<br />
| [[User:Aiaustin|aiaustin]] <br />
| Ai Austin <br />
| Ai Austin <br />
| Ai Austin <br />
| +0 <br />
| AIAI, Virtual University of Edinburgh<br />http://www.aiai.ed.ac.uk/~ai/<br />http://vue.ed.ac.uk/openvue/ <br />
| Windows tests<br />Content testing<br />Use of multiple VWs<br />
|-<br />
| Marc Manders <br />
| Marc Manders <br />
| &nbsp; <br />
| &nbsp; <br />
| +6 <br />
| marcmanders@gmail.com <br />
| Creative features<br />
|-<br />
| [[User:Balthazar|balthazar]] <br />
| Trevor Brooks <br />
| Balthazar Sin <br />
| <br />
| -5 <br />
| None <br />
| Terrains, testing and some small coding tasks<br />
|-<br />
| [[User:Jimbo2120|jimbo2120]] <br />
| Michael Osias <br />
| Illuminous Beltran <br />
| <br />
| -5 <br />
| IBM <br />
| Grid, AI, Skynet, coding and testing<br />
|-<br />
| ZeroPoint <br />
| &nbsp; <br />
| Guilderoy&nbsp;Dench <br />
| <br />
| -5 <br />
| &nbsp; <br />
| Programming/Database<br />
|-<br />
| [[User:DerekTang|DerekTang]] <br />
| Derek Tang <br />
| Derek Timeless <br />
| Derek Tang (ChineseGrid) <br />
| +8 <br />
| http://ChineseGrid.net <br />
| Running a public WINDOWS sim for testing, Docs, Helping Chinese users to enjoy OpenSim; building Chinese OpenSimulator communities. In construction...<br />
|-<br />
| [[User:TayB|TayB]] <br />
| Earl Balai <br />
| Taylor Dae <br />
| <br />
| -10 <br />
| WhynGrid <br />
| Grid Host,Networking,Contributions &amp; Testing.<br />
|-<br />
| [[User:JamieDav|JamieDav]] <br />
| Jamie David <br />
| Jamie David <br />
| <br />
| +7 <br />
| Forum <br />
| Grid, Sim, Avitar, Functionality<br />
|-<br />
| [[User:Krtaylor|Krtaylor]] <br />
| Kurt Taylor <br />
| Kurt Stringer <br />
| <br />
| -6 <br />
| IBM <br />
| Grid, Networking, Monitoring, Scripting, Inventory, Testing<br />
|-<br />
| [[User:Nink|Nink]] <br />
| Peter Finn <br />
| Nink Noonan <br />
| <br />
| -5 <br />
| IBM <br />
| Disruptive Influence.<br />
|-<br />
| [[User:Bruce|Bruce]] <br />
| Bruce Meerson <br />
| Bruce Meerson <br />
| <br />
| +8 <br />
| HiPiHi <br />
| Watching.<br />
|-<br />
| [[User:Darb|DarbD]] <br />
| Brian B. Quinn <br />
| Darb Dabney <br />
| regions<br />near Marin <br />
| PST/SLT (-7 or -8) <br />
| County of Marin, California<br /> http://blog.3dmap.me <br />
| LiDAR-based sculpties, real-world terrain, <br />pursuit of civic paraverses, virtual Emergency Operations Centers<br />
|-<br />
| [[User:Charlie Omega|CharlieO]] <br />
| Dan <br />
| Charlie Omega <br />
| <br />
| &nbsp; <br />
| &nbsp; <br />
| Mild coding/tweaking/simple feature adds, Stress testing/break stuff, Testing limits of existing code. Making sure [[LSL Status]] is up to date<br />
|-<br />
| oobscure <br />
| &nbsp; <br />
| Opensource Obscure <br />
| <br />
| +1 <br />
| http://www.opensim.it <br />
| Running a public Linux sim for testing, Docs, Helping italian users, Building opensim communities, Watching<br />
|-<br />
| pitman <br />
| Mike Pitman <br />
| Rez Tone <br />
| <br />
| &nbsp; <br />
| IBM <br />
| Scientific visualization schemes, virt world product design, persistant workspaces, virt world based big biz<br />
|-<br />
| Shenlei <br />
| Shenlei Winkler <br />
| Shenlei Flasheart, Shenlei Winkler <br />
| <br />
| &nbsp; <br />
| Fashion Research Institute <br />
| Product Design and Development, Apparel industry, and o yes, I wrote the book&nbsp;;)<br />
|-<br />
| cmu <br />
| Christopher Mumme <br />
| Snook Destiny <br />
| <br />
| +1 <br />
| http://www.cmu-develop.de/ and research group "Collaboration Systems and CSCW" at Clausthal University of Technology <br />
| Testing OpenSim, working with OpenSim-Engine, reporting on OpenSimulator<br />
|-<br />
| [[Silpol]] <br />
| Andriy Tymchenko <br />
| Andy Tir <br />
| <br />
| EET (+2/3) <br />
| http://silpol.blogspot.com/ (also visible at Nokia) <br />
| Highly uncoordinated mess with elements of palace games, under-table diplomacy, rebellion, coup d'état and mutiny. optionally pirate<br />
|-<br />
| [[User:Grumly|Grumly]] <br />
| <br />
| Forest Klaar <br />
| Grumly TheBear <br />
| GMT+1 <br />
| .NET MCAD Dev/Arch/Trainer http://www.devoteam.com <br />
| Trying to get into OpenSimulator code for now. Particularly interrested in data persistence. blog (Hello, Avatar!): http://lslblog.free.fr<br />
|-<br />
| [[User:DaTwitch|DaTwitch]] <br />
| James G. Stallings II <br />
| <br />Lazarus Longstaff <br />
| Hiro Protagonist (OSGrid) <br />
| -5 <br />
| House Husband <br />
| OSGrid Region owner, OSGrid Operator,<br />Forum Admin, sometime wiki editor<br />
|-<br />
| gryc <br />
| Gryc Ueusp <br />
| Gryc Uriza <br />
| Gryc Uriza(OSGrid) <br />
| -6 <br />
| <br />
| PHP scripting, web interfaces, interconnectivity, cross-platformedness<br />
|-<br />
| [[User:Phrearch|Phrearch]] <br />
| Jeroen van Veen <br />
| Phrearch Miles <br />
| Phrearch Miles(OSGrid) <br />
| Amsterdam/Paris <br />
| <br />
| HWIOS, WiXTD, Wikidoc, Moo, User interfaces<br />
|-<br />
| [[User:Burnman|Burnman]] <br />
| Allen <br />
| Burnman Bedlam <br />
| <br />
| Boston, USA <br />
| <br />
| Testing, testing, and more testing! Getting familiar with the source, interested in all aspects of the project.<br />
|-<br />
| [[User:Krisbfunk|krisbfunk]] <br />
| Kris Bulman <br />
| Krisbfunk Vought <br />
| Krisbfunk Nocturnal(OSGrid) <br />
| PE, Canada (-4) <br />
| Edactive Technologies<br />NocturnalEye Productions<br />UPEI <br />
| Currently: Testing, bug reports, wiki updating, building on OSGrid<br />
|-<br />
| [[User:HashBox|HashBox]] <br />
| &nbsp; <br />
| Sibariel Darkstone <br />
| Sibariel Darkstone (OSGrid) <br />
| New Zealand (+12) <br />
| <br />
| Testing, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Kinoc|Kinoc]] <br />
| Kino Coursey <br />
| Daxxon Jaxxon <br />
| Daxxon Kinoc (OSgrid) <br />
| -6 <br />
| Daxtron Laboratories <br /> http://www.daxtron.com<br /> University of North Texas <br />
| AI, Semantic web, Ontologies, Natural Laanguage Processing, Cyc, Bots, NPC<br />
|-<br />
| [[User:Trapuh|trapuh]] <br />
| Pedro Ribeiro <br />
| Vaiten Forder <br />
| <br />
| GMT <br />
| University Student, Escola Superior de Educação de Viseu, Portugal <br />
| Testing, eventual bug reports and wiki. Music, web/digital arts and php+sql.<br />
|-<br />
| [[User:SonicViz|SonicViz]] <br />
| Paul Cohen <br />
| Komuso Tokugawa <br />
| <br />
| +9 <br />
| Http://sonicviz.com <br />
| Audio/Music, Interactive Music, Control Protocols, Interfaces, VisualFX, Procedural animation/Generative systems + testing and general dev<br />
|-<br />
| [[User:Mokele|mokele]] <br />
| Scott Norman <br />
| Mokelembembe Mokeev <br />
| <br />
| -8 (Southern California) <br />
| Web Developer (PHP and MySQL) <br />
| Interested in seeing running on PowerPC Macs which it is. So, when I can, I'll compile and test on PowerPC Mac (PowerBook G4) and submit reports and then update the wiki if need on installing on Mac. Also have a Ubuntu 7.10 server that I can do testing on too.<br />
|-<br />
| [[User:Devalnor|devalnor]] <br />
| Devalnor <br />
| M. Watkin <br />
| <br />
| +1 (Belgium) <br />
| <br />
| Small Patch code, bug reports, and updating the wiki.<br />
|-<br />
| [[User:Ezekiel|Ezekiel]] <br />
| Ezekiel <br />
| Ezekiel Zabelin <br />
| <br />
| +1 <br />
| http://www.yosims.com <br />
| Concepts, business aspects of virtual worlds - web developer (PHP, MySQL, Javascript, LSL)<br />
|-<br />
| [[User:Buggmaster|Buggmaster]] <br />
| Mike D <br />
| Bug Master <br />
| None <br />
| -8 <br />
| http://www.adultmetaverse.com <br />
| Grid, Data/Web PHP/PERL/MySQL<br />
|-<br />
| [[User:Nixnerd|nixnerd]] <br />
| <br />
| Dangerously Moody <br />
| None <br />
| GMT <br />
| http://www.integratedtechnologies.eu <br />
| Cross Platform Testing, Feedback, Bug Reporting<br />
|-<br />
| [[User:MoHax|mohax]] <br />
| Mo Hax <br />
| Mo Hax <br />
| <br />
| -5 Eastern <br />
| IBM <br />
| Testing, Feedback, Content Contributions, Bug Reporting, Documenting, Development<br />
|-<br />
| [[User:Webmage|webmage]] <br />
| webmage <br />
| Leyla Masala <br />
| Web Mage <br />
| +1 <br />
| IBM <br />
| Testing, terrain<br />
|-<br />
| [[User:NLStitch|NLStitch]] <br />
| Marijn Oosterveld <br />
| Stitch Seale <br />
| NYA <br />
| GMT +1 Amsterdam <br />
| Twingate Systems (http://www.twingate.nl)<br />HanzeHogeschool Groningen, Netherlands <br />
| Programming, Photography, AI<br />
|-<br />
| [[User:Ideia Boa|Ideia Boa]] <br />
| Joao Lopes <br />
| Ideia Boa <br />
| Ideia Boa or Boa Ideia in some grids <br />
| GTM+1 Stockholm/Sweden <br />
| WorldSimTERRA - Virtual World that speaks Portuguese too<br />http://www.worldsimterra.com <br />
| Testing and more testing! Updating the original wiki and translating the OpenSimulator Wiki into Portuguese and reporting on OpenSimulator<br />
|-<br />
| [[User:Lulurun|lulurun]] <br />
| liu <br />
| <br /> <br />
| <br /> <br />
| +9 <br />
| 3Di Inc, Japan <br />http://www.3di.jp <br />
| Patches, openid, server performance, UGAI<br />
|-<br />
| [[User:Carlosroundel|Carlosrounde]] <br />
| Carlosroundel <br />
| Carlos Roundel <br />
| <br /> <br />
| +1 <br />
| Cyberlandia Italy<br />http://www.cyberlandia.net <br />
| Grid, programmer, database, tester<br />
|-<br />
| [[User:Mikebert|Mikebert]] <br />
| Michael Strunck <br />
| Mikebert Miles <br />
| Mikebert M34 <br />
| +1 <br />
| OpenSIM Wiki, Germany<br />http://www.opensim.de <br />
| German Wiki, Translater, Server Performance (Linux/Windows), Tester, Feedback, Bug Reporting, Server-Hosting<br />
|-<br />
| Taoki <br />
| Mircea Kitsune / Taoki Vixen <br />
| Mircea Kitsune (OSGrid) / Mircea Lobo (LL grid) <br />
| <br /> <br />
| GMT +2 <br />
| <br /> <br />
| Usually testing and bug reporting but I also make smaller patches where I know what to do.<br />
|-<br />
| [[User:Patnad|Patnad]] <br />
| Patrick <br />
| Patnad Babii <br />
| Patnad Babii (OSGrid) <br />
| GMT -5 <br />
| RezzMe Technologies<br />http://www.rezzme.com <br />
| Bug testing and reporting, I code C# and have submitted a few patches<br />
|-<br />
| [[User:^DarkMan|^DarkMan]] <br />
| Brian Adair <br />
| Patrick Ouachita <br />
| Brian Adair &#124; Patrick Meta <br />
| -6 CST <br />
| RealMetaLife &#124; B&amp;H Networking <br />
| Building, Scripting, Testing, etc.<br />
|-<br />
| [[User:Tlaukkan|Tommi Laukkanen]] <br />
| Tommi Laukkanen <br />
| &nbsp; <br />
| Tommi Laukkanen <br />
| +2 GMT <br />
| http://www.bubblecloud.org <br />
| Protocols ([http://www.bubblecloud.org MXP]), NHibernate, Scrip API, Map Generation, Bug Fixes, Grid Hosting<br />
|-<br />
| [[User:Mystical|Mystical]] <br />
| Kevin Tweedy <br />
| Mystical Demina <br />
| Mystical Demina <br />
| -5 <br />
| Extreme Reality Grid<br />http://www.XRGrid.com <br />
| Windows Communication Framework, Windows Workflow,Entity Framework, MSSQL<br />Enhancements,Commerce, Content,DotNetNuke based portal, development services<br />
|-<br />
| [[User:Godfrey|Godfrey]] <br />
| Jeff Lee <br />
| Warin Cascabel <br />
| <br />
| -5 (EST5EDT) <br />
| <br />
| Testing, minor bugfixes. Scripting, building, animating<br />
|-<br />
| Jamenai <br />
| Christopher Händler <br />
| Jamenai Luik <br />
| Jamenai Luik <br />
| +1 <br />
| Playneko Grid &#124; XIMDEX Jamenai<br />http://www.playneko.de<br />http://www.ximdex.de <br />
| Performance,Bug Reporting, Hosting, Grid-Owner,(PHP, MySQL, Perl, JavaScript, LSL)<br />
|-<br />
| [[User:Bikcmp|bikcmp]] <br />
| Jason <br />
| Jake1500 Allen <br />
| Jason Helios (The Helios Grid) <br />
| EST <br />
| Blue Software <br />
| Search, groups, land, and currency<br />
|-<br />
| [[User:Mark.malewski|Slipaway]] <br />
| Mark Malewski <br />
| Chris Rock <br />
| <br />
| -6 (-5 during summer - CDT) <br />
| NexTECH / Joopla <br />
| Web development &amp; systems integration, terrain, WIKI documentation, tutorials, testing, bug reporting and feedback.<br />
|-<br />
| barakademi <br />
| Steve Topp <br />
| barakademi Barzane <br />
| same avi on baragrid OSgrid Grid4us sciencesim <br />
| utc+1 (CET) paris <br />
| http://xbot-sl.barakademi.org http://vps.barakademi.org/oswi http://vps.barakademi.org/oswi/loginscreen.php <br />
| Music LiveMusic MetaverseMusic Opensim Libomv Mono-2.4 Linux (suse,debian,ubuntu) Admin Scripting Automating Development Intergration php mysql bash nant +++<br />
|-<br />
| [[User:Robert d|robert_d]] <br />
| Robert Dzikowski <br />
| <br />
| OSGrid: robert_d 13 <br />
| UTC+1 <br />
| [http://blog.rd-it.net http://blog.rd-it.net] <br />
| Region Modules, Tutorials<br />
|-<br />
| john_ <br />
| John&nbsp;Moyer <br />
| VAJohn&nbsp;GeekSquad or&nbsp;Matthew&nbsp;Kendal <br />
| <br />
| -5 <br />
| Best&nbsp;Buy/Geek&nbsp;Squad <br />
| Tester<br />
|-<br />
| [[User:W!cKeD|_WicKeD]] <br />
| Maik <br />
| Maik Galaxy <br />
| El Diablo <br />
| +1 Germany <br />
| Creatio Inc. / [http://www.OpenSimGerman.us/ OpenSimGerman.us] <br />
| German Support, Translator, Building, Scripting, Testing, Hosting<br />
|-<br />
| [[User:Stevie Wakowski|Stevie Wakowksi]] <br />
| Steve Roberts <br />
| Stevie Wakowski <br />
| <br />
| +10 Australia <br />
| IBM <br />
| OpenSimulator builds, Linux, Modrex, bug reporting, evangalist for OpenSimulator in business applications.<br />
|-<br />
| Revolution <br />
| Matthew <br />
| Revolution Smythe <br />
| Revolution Smythe <br />
| -6 Central USA <br />
| None <br />
| Script engine, physics engine, general odd bugs, interesting and odd things<br />
|-<br />
| [[User:ClemsonGS|clemsonGS]] <br />
| Brian Cass <br />
| BC Sands <br />
| Brian Cass (VWC Grid) <br />
| -5 <br />
| http://www.cvwconline.org/ <br />
| Developing virtual worlds for use in higher education<br />
|-<br />
| <br />
| AlexRa <br />
| <br />
| <br />
| <br />
| Independent <br />
| <br />
|-<br />
| <br />
| <br />
| Mikko Pallari <br />
| <br />
| <br />
| Realxtend <br />
| <br />
|-<br />
| <br />
| StrawberryFride <br />
| Chris Hart <br />
| <br />
| <br />
| ReactionGrid <br />
| <br />
|-<br />
| [[User:RemedyTomm|RemedyTomm]] <br />
| Tom Grimshaw <br />
| Tomm Remedy <br />
| KGrid: Casper Warden OSGrid: Tomm Remedy <br />
| UTC+0 (BST) <br />
| Remedy Communications <br />
| Texture pipeline, Groups, ObjectUpdates<br />
|-<br />
| <br />
| <br />
| Rob Smart <br />
| <br />
| <br />
| IBM <br />
| <br />
|-<br />
| MicheilMerlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| Micheil Merlin <br />
| -6 <br />
| Independent <br /> [http://www.iliveisl.com/ http://www.iliveisl.com/] <br />
| Scripting, patches, and testcases<br />
|-<br />
| Pato Donald <br />
| Pato Donald <br />
| Morgam Biedermann <br />
| Pato Donald <br />
| -3 <br />
| Independent [http://www.matheusmk3.co.cc/ http://www.matheusmk3.co.cc/ <br />
| Groups, Scripts, Physics, Communication, Integration<br />
|-<br />
| <br />
| Sera Marx <br />
| Darkfire Soulstar <br />
| <br />
| +12 <br />
| Radiance promotions <br />
| Grid Host, Commissioner. ~ Anyone looking for work related to the development of Opensimulator or Viewers please contact me. Any work undertaken for me will be returned to Opensimulator unless made strictly for my Grid<br />
|-<br />
|[[User:dz|dz]] <br />
| Doug Osborn <br />
| ydoo magic<br />
| Doug Osborn @ScienceSim & MOSES grids<br />
| PST/SLT (-7 or -8) <br />
| CTO, F.R.I. <br />
| Performance testing, scripting, high prim count builds, bots, and running in-world conferences.<br />
|-<br />
| [[User:Hallow Palmer|Hallow Palmer]] <br />
| Markus <br />
| Hallow Palmer <br />
| <br /> <br />
| +1 <br />
| Grid4Us<br />http://www.grid4us.net <br />
| Server Performance (Windows), Tester, Feedback, Business concepts,Bug Reporting, Server-Hosting<br />
|-<br />
| [[User:LenaVanilli|LenaVanilli]] <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| Lena Vanilli <br />
| +1 Germany <br />
| [http://www.hypergrid.org http://www.hypergrid.org] <br />
| Grid-Management, Testing Testing Testing, Region Hosting<br />
|-<br />
| [[User:Aduffy70|aduffy70]] <br />
| Aaron Duffy <br />
| Aeran Stipe <br />
| Aaron Duffy @ScienceSim <br />
| -7 <br />
| USU <br />
| Scientific visualization &amp; education, Region modules, Heavily scripted regions<br />
|-<br />
| <br />
| Erich Bremer <br />
| Erich Bremer <br />
| <br />
Erich Bremer@OSGrid <br />
<br />
| -5 <br />
| http://www.ebremer.com <br />
| Semantic Web, Data Visualization<br />
|-<br />
| [[User:MarkIDCAS|MarkIDCAS]] <br />
| Mark Bannon <br />
| Mark IDCAS <br />
| 3D Grid Association, AtMeeting, Valhalla Virtual and IDCAS. <br />
| GMT <br />
| [http://www.valhallavirtual.com http://www.valhallavirtual.com] <br />
| Grid Management &amp; systems integration. Scripting. WIKI documentation, tutorials, bug reporting and feedback.<br />
|-<br />
| [[User:Allquixotic|allquixotic]] <br />
| Sean McNamara <br />
| Tiyuk Quellmalz <br />
| OSG: Tiyuk Quellmalz <br />
| -5 <br />
| None <br />
| Bugfixing; networking; performance; data integrity; LSL; auto-backup; null DB (eventual consistency).<br />
|-<br />
| [[User:Orenh|orenh]] <br />
| Oren Hurvitz <br />
| <br />
| Oren Hurvitz (Kitely) <br />
| +2 <br />
| Kitely <br />
| <br />
|-<br />
| [[User:Randomhuman|randomhuman]] <br />
| Kevin Houlihan <br />
| random Radikal <br />
| random human (OSGrid) <br />
| WET/IST <br />
| CrimsonCookie <br />
| RemoteAdmin module; On-demand grids; web integration.<br />
|<br />
|-<br />
| [[User:Oddball Otoole|oddball otoole]]<br />
| J.v.Hogeloon<br />
| Oddball Otoole<br />
| Oddball Otoole (OSGrid<br />
| +1 (The Netherlands<br />
| None<br />
| Building, scripting, testing, social stuff.<br />
|-<br />
| [[User:Pixel|Pixel Tomsen]]<br />
| Christian Kurzhals<br />
| Pixel Tomsen<br />
| Pixel Tomsen OSGrid<br />
| +1 (Germany<br />
| see my profil<br />
| Dev, Building, scripting, sim-hosting, some modules, patches, osgrid<br />
|-<br />
| [[User:kenearlg|kenearlg]]<br />
| Ken Grunke<br />
| Key Grau<br />
| Key Gruin (Osgrid)<br />
| -6 CST<br />
| http://www.osgrid.org/<br />
| testing, moderating, inworld games & recreation, wiki spam control<br />
|}<br />
<br />
== Retired Additional Developers ==<br />
<br />
Additional developers who are no longer working on the OpenSimulator project. Thank you forever for your contributions! <br />
<br />
{| cellspacing="0" cellpadding="2" border="1" class="sortable"<br />
|-<br />
! IRC Nick <br />
! Name <br />
! SL Avatar <br />
! Other Grid <br />
! Time Zone<br />(UTC) <br />
! Org <br />
! Areas of Interest<br />
|-<br />
| [[User:Fly-man-|Fly-Man-]] <br />
| Laurence <br />
| <br />
| OSGrid: Fly Man <br />
| GMT +1 <br />
| Private Company<br />
| Testing, OpenSimSearch, OpenSimProfile<br />
|-<br />
|}<br />
<br />
[[Category:Development]]<br />
[[Category:Tech Reference]]<br />
[[Category:Help]]</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:57:24Z
<p>Dz: /* Why you should (probably) NEVER use a Second Life AO script in OpenSimulator */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour versus 6000 events using the modified script...<br />
<br />
In OpenSimulator, the design can be much more efficient. The developers have added a CHANGED_ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the script with the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This is an example of an AO script designed for use in OpenSimulator. These instructions describe how to make your own AO from scratch.<br />
<br />
For this example, I use animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. <br />
<br />
The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Step 1. Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Step 2. Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Step 3. Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Step 5. Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Step 6. Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Step 7. Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Step 8. Attach it to one of your HUD positions ... <br />
<br />
Step 9. Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:54:16Z
<p>Dz: /* Why you should (probably) NEVER use a Second Life AO script in OpenSimulator */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour versus 6000 stand changes in an hour using the modified script...<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the script with the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This is an example of an AO script designed for use in OpenSimulator. These instructions describe how to make your own AO from scratch.<br />
<br />
For this example, I use animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. <br />
<br />
The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Step 1. Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Step 2. Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Step 3. Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Step 5. Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Step 6. Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Step 7. Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Step 8. Attach it to one of your HUD positions ... <br />
<br />
Step 9. Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:51:50Z
<p>Dz: /* Converting ZHAO scripts to work in OpenSim efficiently */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour...<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the script with the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This is an example of an AO script designed for use in OpenSimulator. These instructions describe how to make your own AO from scratch.<br />
<br />
For this example, I use animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. <br />
<br />
The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Step 1. Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Step 2. Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Step 3. Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Step 5. Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Step 6. Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Step 7. Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Step 8. Attach it to one of your HUD positions ... <br />
<br />
Step 9. Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:50:08Z
<p>Dz: /* Simple Click on/off Variable speed AO demo */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour...<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the scriptwith the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This is an example of an AO script designed for use in OpenSimulator. These instructions describe how to make your own AO from scratch.<br />
<br />
For this example, I use animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. <br />
<br />
The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Step 1. Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Step 2. Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Step 3. Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Step 5. Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Step 6. Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Step 7. Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Step 8. Attach it to one of your HUD positions ... <br />
<br />
Step 9. Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:45:56Z
<p>Dz: /* Simple Click on/off Variable speed AO demo */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour...<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the scriptwith the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This is an example of an AO script designed for use in OpenSimulator. <br />
<br />
It uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. <br />
<br />
The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:44:46Z
<p>Dz: /* Simple Click on/off Variable speed AO demo */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour...<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the scriptwith the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This is an example of an AO script designed for use in OpenSimulator. It requires that OS functions are enabled to implement the variable speeds via calls to osSetSpeed. It will not work without modification in regions that have os functions disabled or the threat level set too low.<br />
<br />
It uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:37:41Z
<p>Dz: /* Why you should (probably) NEVER use a Second Life AO script in OpenSimulator */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts. In the example below, setting the timer event to 0.25 seconds would generate 14000 interruptions per hour for each AO.. For our mythical group of 20, 280,000 "are we still standing" questions per hour...<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the scriptwith the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This example uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:33:43Z
<p>Dz: /* Why you should (probably) NEVER use a Second Life AO script in OpenSimulator */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions (per minute) to answer your scripts.''<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the scriptwith the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This example uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:31:58Z
<p>Dz: /* Converting ZHAO scripts to work in OpenSim efficiently */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions to answer your scripts.''<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean more than 14,000 "are we still standing" events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the scriptwith the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This example uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:29:52Z
<p>Dz: /* Converting ZHAO scripts to work in OpenSim efficiently */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions to answer your scripts.''<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in OpenSim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
Step 1. Make sure you have a ZHAO based AO.<br />
<br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. Edit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are interested in calculating the amount of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean as many as 14,000 events an hour. In contrast, changing the stand every 12 seconds for an hour, this modified AO script only requires 300 events. )<br />
<br />
<br />
Step 4. Local the section of code that handles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the scriptwith the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This example uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:25:40Z
<p>Dz: /* Converting ZHAO scripts to work in OpenSim efficiently */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions to answer your scripts.''<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in opensim, Do us all a favor.. follow these instructions and modify your script.<br />
First, the Easy way....<br />
<br />
Step 1. Make sure you have a ZHAO based AO. <br />
Put the AO on the ground and Edit it. Look in the CONTENTS tab.<br />
If you find the scripts ZHAO II CORE, ZHAO II INTERFACE, and notecard named something like ZHAO READ ME, and a notecard named "default", proceed to step 2.<br />
If you did NOT find any of those files, there is a 100% chance that I take no responsibility for you proceeding to step 2.<br />
<br />
Step 2. Make a backup copy of the ZHAO II CORE script by dragging it into your scripts folder in your inventory.<br />
<br />
Step 3. IEdit your ZHAO CORE script and locate the following lines....<br />
<br />
<source lang = "lsl"><br />
// How fast we should poll for changed anims (as fast as possible)<br />
// In practice, you will not poll more than 8 times a second.<br />
float timerEventLength = 0.25;<br />
</source><br />
<br />
REPLACE WHATEVER NUMBER IS AFTER THE = with 0.0..... so the line looks like this....<br />
<source lang = "lsl"><br />
float timerEventLength = 0.0;<br />
</source><br />
<br />
( If you are Interested in calculating the amout of processing you might save... this value of .25 means that your AO checks 4x a second to see what you are up to.<br />
That can mean as many as 14,000 "checks" an hour. In contrast, even changing the stand every 12 seconds for an hour, this AO only requires 300 "checks". )<br />
<br />
<br />
Step 4. Local the section of code that hangles the CHANGE event.... It should look something like this.....<br />
<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
}<br />
</source><br />
<br />
Add the 2 new lines of code....<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
So it looks like this...<br />
<br />
<source lang = "lsl"><br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_REGION)<br />
{<br />
if(llGetAttached())<br />
llRequestPermissions( llGetOwner(), PERMISSION_TRIGGER_ANIMATION|PERMISSION_TAKE_CONTROLS );<br />
}<br />
<br />
if (change & CHANGED_ANIMATION)<br />
checkAndOverride();<br />
<br />
}<br />
</source> <br />
<br />
<br />
Step 5. Save your changes to the script, put the AO in your inventory and then attach/wear it again.<br />
If you have problems, replace your modified version of the scriptwith the one you saved in step 2 above.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This example uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:13:51Z
<p>Dz: /* Converting ZHAO scripts to work in OpenSim efficiently */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions to answer your scripts.''<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
If you LOVE your ZHAO based AO and HAVE TO HAVE IT in opensim, Do us all a favor.. follow these instructions and modify your script.<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This example uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz
http://opensimulator.org/wiki/User:Dz/AO
User:Dz/AO
2014-01-27T04:03:45Z
<p>Dz: /* Simple Click on/off Variable speed AO demo */</p>
<hr />
<div>__FORCETOC__<br />
<br />
== Animation Override scripts ==<br />
<br />
These are AO scripts I have used or developed over time.<br />
Many of them are assembled from bits and pieces of code I have read/seen/fixed/admired.<br />
Some of the code snippets appear with permissions, Please do not remove the attributions where they can be found in the comments.<br />
The code has been shared, only asking simple consideration. Please respect the wishes of the original authors as I have attempted to do.<br />
<br />
These AO designs are NOT compatible with NPCs, as they require a user to touch them to activate.<br />
<br />
If you have feedback on script errors, please post it to the page discussion [[User_talk:Dz/AO]]<br />
<br />
=== Why you should (probably) NEVER use a Second Life AO script in OpenSimulator ===<br />
<br />
Chances are, if you are using a Second Life AO script in OpenSim , you are abusing the region server resources, and perpetuating the myth that all AO's are good for is generating lag. There are fundamental differences between the animation events in SecondLife and Opensim that make Second Life AO script overhead unnecessary. <br />
<br />
When the GPL'd ZHAO code was written for SL, it was designed to ask the region "what is my current animation state?" multiple times a second. It then compares the returned state to the last one to see if anything has changed, and if it has, it looks up the new animation it needs and starts to play it. Depending on the timer settings it can ask the same question 4 or 5 times a second (which doesn't work well in OpenSim). <br />
<br />
Lets look at what happens when you enter a sim and stand, with your AO set for 1/3 second checks, and your stand changing every 20 seconds...<br />
<br />
''Enter sim, Script loads into memory and starts. <br />
<br />
''Script encounters Stand state, activates stand animation,<br />
<br />
''sets stand timer to 20 seconds<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapsed and a new stand animation is triggered<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
''timer elapses and the stand animation changes...<br />
<br />
''in the next 20 seconds the script will ask the sim 60 times "are we still standing?"<br />
<br />
...That's the first minute. <br />
<br />
180 "extra" sim interruptions to make sure you haven't stopped standing still. <br />
Say 20 of you in the sim with the same AO... That's 3600 "extra" sim interruptions to answer your scripts.''<br />
<br />
In OpenSimulator, the design can be MUCH more efficient. The developers have added a CHANGED ANIMATION parameter to the CHANGED event in OpenSim, so our scripts don't have to ask what the current animation state is, it just needs to handle the changed event when it is notified. These lines of code replace the timer loop that asks the repetitive question by sending a notice to the script when a new animation state is triggered.. Our script is basically these lines..<br />
<source lang = "lsl"><br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
}<br />
</source><br />
<br />
Yes, there is still overhead to loading and running the AO script, but with this interrupt driven design we eliminate a vast majority of the overhead and wasted processing time.<br />
<br />
=== Converting ZHAO scripts to work in OpenSim efficiently ===<br />
<br />
<br />
=== Simple Click on/off Variable speed AO demo ===<br />
<br />
This example uses animations found in the Linda Kelly RUGGED male AO. They should be widely available, and you are free to modify the script to use your own. The variable speed option requires that OS functions be enabled and the threat level set appropriately in the region you want to use this in. This script selects a random walk animation from the 3 provided and changes the walk speed to more closely match the animation selected.<br />
<br />
Generate a small cube (0.15, 0.15, 0.15) <br />
<br />
Drag copies of the AO animations you want to use into the contents of the cube.<br />
<br />
Drop this script in the cube. <br />
<br />
<source lang = "lsl"><br />
<br />
//<br />
// OpenSimian Speed Scalable Animation Override for OpenSimulator 2014 v2.0<br />
//<br />
// Copyright 2014 by Doug Osborn.<br />
<br />
// This script is Licensed under the Creative Commons Attribution-Share Alike 3.0 License<br />
// For a copy of the license terms please see http://creativecommons.org/licenses/by-sa/3.0<br />
<br />
<br />
// set the animations as instructed below<br />
// Remember to put the animation in the prim...<br />
<br />
// SpdScale is the float multiplier... 1 is default speed <br />
// you can reset default in the grey state if you want a boost/damper when the AO is off<br />
<br />
<br />
<br />
// ************************** Customize YOUR AO by changing the names of the Animations, and the cycle time for your stands here.<br />
<br />
<br />
list StandNames = ["rugged-stand-1", "rugged-stand-2", "rugged-stand-3"];<br />
integer StandTime = 8; // change this number to the number of seconds between stands<br />
<br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
string TrnRight = "AO-TurnRight-Male"; // Change this string to the name of your turn right animation<br />
<br />
string TrnLeft = "AO-TurnLeft-Male"; // Change this string to the name of your turn left animation<br />
<br />
string RunAnimation = "run"; // Change this string to the name of the RUN animation you want to use<br />
<br />
string SitAnimation = "AO-Sit2-Male"; // Change this string to the name of the crouch animation you want to use<br />
integer OverrideSit = TRUE; // <br />
<br />
string CrouchAnimation = "AO-Crouch-Male"; // Change this string to the name of the crouch animation you want to use<br />
<br />
string CrouchWalkAnimation = "AO-CrouchWalk1-Male"; // Change this string to the name of the crouch walk animation you want to use<br />
<br />
string FlyAnimation = "AO-Fly1-Male"; // Change this string to the name of the fly animation you want to use<br />
<br />
string HoverAnimation = "AO-Hover-Male"; // Change this string to the name of the hover animation you want to use<br />
<br />
string SoftLandAnimation = "AO-Softlanding-Male"; // Change this string to the name of the soft land animation you want to use<br />
integer LandingTime = 3; // Change this to reflect the length of the standing animation in seconds.<br />
<br />
string JumpAnimation = "AO-JumpFlip1-Male"; // Change this string to the name of the jump animation you want to use<br />
<br />
// *******************************************************************************************************************************<br />
<br />
key Owner= NULL_KEY;<br />
integer resetflag = 0;<br />
<br />
vector onColor = <42,255,42>; // all nice and green<br />
vector offColor = <128,128,128>; // and grey<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
<br />
string LastAnimType = ""; <br />
<br />
string LastAnimName = "";<br />
<br />
string LastRunAnim = "";<br />
<br />
string WhichAnimType = "";<br />
<br />
float StandCount = 0.0;<br />
<br />
// Start Me Up<br />
<br />
Initialize(key id) <br />
{<br />
<br />
<br />
if (id == NULL_KEY) // detaching<br />
{ <br />
llSetTimerEvent(0.0); // stop the timer<br />
}<br />
else // attached, or reset while worn <br />
{<br />
Owner = id; <br />
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION); <br />
}<br />
<br />
StandCount = (float) llGetListLength(StandNames);<br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
llSay(0,"Initialized"); <br />
<br />
}<br />
<br />
StartAnimation()<br />
{ <br />
if (LastAnimType != WhichAnimType) <br />
{ <br />
if (WhichAnimType == "Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(WalkAnimations != [])<br />
{ <br />
list RndWalk = llListRandomize(WalkAnimations,2);<br />
<br />
LastAnimName = llList2String(RndWalk,0);<br />
osSetSpeed(Owner,llList2Float(RndWalk,1));<br />
<br />
// llSay(0,LastAnimName);<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
}<br />
<br />
if (WhichAnimType == "Running") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(RunAnimation != "")<br />
{ <br />
LastAnimName = RunAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner,SprintSpdScale); <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Standing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(StandCount > 0.0)<br />
{<br />
<br />
integer whichone = (integer)llFrand(StandCount);// pick a new stand<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
else<br />
{<br />
llSetTimerEvent(0);<br />
} <br />
} <br />
<br />
if (WhichAnimType == "Sitting") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SitAnimation != "" && OverrideSit)<br />
{ <br />
LastAnimName = SitAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
} <br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Flying") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(FlyAnimation != "")<br />
{ <br />
LastAnimName = FlyAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
osSetSpeed(Owner, FlySpdScale);<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Hovering") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(HoverAnimation != "")<br />
{ <br />
LastAnimName = HoverAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Soft Landing") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(SoftLandAnimation != "")<br />
{ <br />
LastAnimName = SoftLandAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
llSetTimerEvent(LandingTime);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
}<br />
<br />
if (WhichAnimType == "Crouching") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchAnimation != "")<br />
{ <br />
LastAnimName = CrouchAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Crouch Walking") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(CrouchWalkAnimation != "")<br />
{ <br />
LastAnimName = CrouchWalkAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Jumping") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(JumpAnimation != "")<br />
{ <br />
LastAnimName = JumpAnimation;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Right") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnRight != "")<br />
{ <br />
LastAnimName = TrnRight;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
if (WhichAnimType == "Turning Left") <br />
{ <br />
llStopAnimation(LastAnimName);<br />
<br />
if(TrnLeft != "")<br />
{ <br />
LastAnimName = TrnLeft;<br />
<br />
llStartAnimation(LastAnimName);<br />
}<br />
<br />
llSetTimerEvent(0);<br />
<br />
} <br />
<br />
} <br />
}<br />
<br />
<br />
<br />
default<br />
{<br />
state_entry() <br />
{ <br />
if (llGetAttached() != 0) <br />
{<br />
Initialize(llGetOwner());<br />
}<br />
}<br />
<br />
on_rez(integer start_param)<br />
{<br />
// Restarts the script every time the object is rezzed<br />
llResetScript(); <br />
}<br />
<br />
attach(key id) <br />
{<br />
Initialize(id);<br />
<br />
}<br />
<br />
run_time_permissions(integer perm) <br />
{<br />
if (perm & PERMISSION_TRIGGER_ANIMATION) <br />
{ <br />
state off; <br />
}<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
// llSay(0, "The script leaves the default state.");<br />
}<br />
}<br />
<br />
state on<br />
{<br />
state_entry()<br />
{<br />
<br />
llSetColor(onColor/255.0, ALL_SIDES);<br />
<br />
osSetSpeed(Owner,WalkSpdScale);<br />
<br />
llSay(0,"Touch to disable"); <br />
<br />
WhichAnimType = llGetAnimation(Owner); <br />
<br />
StartAnimation();<br />
<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state off;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_ANIMATION)<br />
{ <br />
WhichAnimType = llGetAnimation(Owner); <br />
StartAnimation();<br />
LastAnimType = WhichAnimType; <br />
}<br />
<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{<br />
if(resetflag ==1)<br />
llResetScript();<br />
<br />
llStopAnimation(LastAnimName);<br />
<br />
integer whichone = (integer)llFrand(StandCount); // pick the new stand at random<br />
<br />
LastAnimName = llList2String (StandNames,whichone);<br />
<br />
llStartAnimation(LastAnimName);<br />
<br />
// llOwnerSay( "using " + LastAnimName); // uncomment this to see which stand gets trigger by the timer<br />
<br />
llSetTimerEvent(StandTime);<br />
<br />
} <br />
<br />
<br />
state_exit()<br />
{<br />
llStopAnimation(LastAnimName);<br />
}<br />
}<br />
<br />
state off<br />
{<br />
state_entry()<br />
{ <br />
llSetColor(offColor/255.0, ALL_SIDES);<br />
osSetSpeed(Owner,1.0); <br />
llOwnerSay("Touch to enable"); <br />
}<br />
<br />
touch_end(integer num_detected)<br />
{ <br />
state on;<br />
}<br />
<br />
changed(integer change)<br />
{<br />
if (change & CHANGED_INVENTORY)<br />
{<br />
resetflag = 1;<br />
llSetTimerEvent(15);<br />
} <br />
<br />
if (change & CHANGED_REGION_RESTART)<br />
{<br />
llResetScript();<br />
} <br />
}<br />
<br />
timer()<br />
{ <br />
if(resetflag ==1)<br />
llResetScript(); <br />
} <br />
<br />
state_exit()<br />
{<br />
LastAnimType = ""; // should trigger the new animation to start, even if it was the same when we turned it off<br />
}<br />
}<br />
<br />
<br />
<br />
</source><br />
<br />
Edit the script to make sure the animation names in the top section match the animation names you added to the cube.<br />
<br />
Adjust the speed values in the walk animation list and below in the section of code that looks like this... ( 1.0 is the default Opensim speed, this is a multiplier)<br />
<br />
<source lang = "lsl"><br />
list WalkAnimations = [ "Walk-Male-Fast", 1.1, "Walk-Male-Medium", 1.00, "Walk-Male-Slow", 0.95]; // Change this string to the name of the walk animation you want to use<br />
<br />
...<br />
<br />
float WalkSpdScale = 1.0; // default speed scale when OFF <br />
float SprintSpdScale = 1.5; <br />
float FlySpdScale = 2; <br />
</source><br />
<br />
Rename the cube "MYAO" (something you can find in your inventory) and pick it up. <br />
<br />
Attach it to one of your HUD positions ... <br />
<br />
Resize and position. <br />
<br />
Touch to toggle between on and off. Re-attach or edit and "script reset" to reset.</div>
Dz