From 91a6880c93a98c4c81246bed4b7528ef4e92c9f8 Mon Sep 17 00:00:00 2001 From: ChaseLittlepaws Date: Fri, 4 Nov 2022 20:07:41 -0400 Subject: [PATCH] Init commit --- .../Open Close Sign.lsl | 27 ++ Automatic-Open-Close-Sign-SL/README.md | 4 + .../HellhundHeadPatter.lsl | 139 +++++++++ HellhundHeadpatterScript/README.md | 20 ++ Super-Simple-Needs-HUD-SL/README.md | 4 + .../Super Simple Needs.lsl | 264 ++++++++++++++++++ 6 files changed, 458 insertions(+) create mode 100644 Automatic-Open-Close-Sign-SL/Open Close Sign.lsl create mode 100644 Automatic-Open-Close-Sign-SL/README.md create mode 100644 HellhundHeadpatterScript/HellhundHeadPatter.lsl create mode 100644 HellhundHeadpatterScript/README.md create mode 100644 Super-Simple-Needs-HUD-SL/README.md create mode 100644 Super-Simple-Needs-HUD-SL/Super Simple Needs.lsl diff --git a/Automatic-Open-Close-Sign-SL/Open Close Sign.lsl b/Automatic-Open-Close-Sign-SL/Open Close Sign.lsl new file mode 100644 index 0000000..77404bb --- /dev/null +++ b/Automatic-Open-Close-Sign-SL/Open Close Sign.lsl @@ -0,0 +1,27 @@ +string open = "682c41fb-bfa4-9e2e-baf4-50ce596a75cf"; /// UUID for Open Sign +string closed = "9747d088-6fce-28da-1d7e-f6078191b64a"; ///UUID for Closed sign +integer back = 3; +integer front = 2; + + +default +{ + state_entry() + { + llSetTimerEvent(15); ///updates every 15 seconds + } + + timer() + { + list parcel = llGetAgentList(AGENT_LIST_PARCEL,[]); + key owner = llGetOwner(); + if(llListFindList(parcel, [owner]) != -1){ ///owner on parcel + llSetTexture(open, front); + llSetTexture(closed, back); + } + else { ///owner off parcel + llSetTexture(closed, front); + llSetTexture(open, back); + } + } +} \ No newline at end of file diff --git a/Automatic-Open-Close-Sign-SL/README.md b/Automatic-Open-Close-Sign-SL/README.md new file mode 100644 index 0000000..eefde0c --- /dev/null +++ b/Automatic-Open-Close-Sign-SL/README.md @@ -0,0 +1,4 @@ +# Automatic-Open-Close-Sign-SL +This script will change a sign to open when the owner of the object is on the parcel, and closed when the owner is not. Connected to the UUID of example images. +I'm open to people using this script on other objects and or with other textures. +This is available on the Second Life Marketplace on a mesh with simple textures [here](https://marketplace.secondlife.com/p/Automatic-Immersive-Open-Closed-Sign/22943124). diff --git a/HellhundHeadpatterScript/HellhundHeadPatter.lsl b/HellhundHeadpatterScript/HellhundHeadPatter.lsl new file mode 100644 index 0000000..3405aa6 --- /dev/null +++ b/HellhundHeadpatterScript/HellhundHeadPatter.lsl @@ -0,0 +1,139 @@ +key particle = "20bf0490-490d-0286-5b0d-1e9fb6d6eb64"; //heart particle effects, replace with different UUID for different effect +key sound = "5bf74a5d-26a2-a8f2-059b-926247edb26f"; //dog pant sound, replace with different UUID for different sound +string doggo = "Stella"; //change for different dog name +string bodyOne = "head"; //change for different body part, e.g. belly +//string bodyTwo = "belly"; //change for different body part, e.g. belly //not implemented +/* Do not change anything below this unless you know what you're doing! +Seriously!*/ +key self; +key toucher; +//integer touchedPrim; //not implemented +integer pets = 0; //for counter +integer waiter = 0; +integer active = FALSE; +integer spam = FALSE; +integer status = FALSE; +WhisperAlias(string alias, string message) { //this function is so the object can whisper under an alias + string orignialName = llGetObjectName(); //save orignal name in a variable + llSetObjectName(alias); //set object name to alias + llWhisper(0,message); // whisper the message input + llSetObjectName(orignialName); //set object name back to original name +} SetStatus() { //set the hover text + string text; + if (toucher == self) { //if touching self + text = "Silly "+(string)doggo+", you can't pet yourself."; + } else if (spam == TRUE) { //if spamming + text = "Let's give "+(string)doggo+" a break."; + } else if (active == TRUE) { //if not spamming and active + text = "Thank you for petting "+(string)doggo+"!"; + } else { //if not spamming and not active + text = "Pet "+(string)doggo+"'s "+(string)bodyOne+"!\n"; // default text + if(pets>0) text += (string)doggo+"'s "+(string)bodyOne+" has been pet "+(string)pets+" times."; //if any pets, add this counter + } llSetText(text,<1.0, 1.0, 1.0>,.9); + status = TRUE; +} FadeStatus() { + llSetText("",<1.0, 1.0, 1.0>,.9); //fade the text + status = FALSE; +} SpamPrevention(){ + // llWhisper(0, "SpamPrevention() running\nActive: "+(string)active+" Spam: "+(string)spam); //debug message + spam = TRUE; + active = TRUE; + SetStatus(); //set hover text to spam message + if (toucher != self) WhisperAlias(doggo,"You're petting too quickly, please calm down."); //if toucher isn't self, whisper anti spam message + if (toucher == self) WhisperAlias(doggo,"Stop trying to pet yourself, silly "+(string)doggo+"."); //if toucher is self, whisper differnt message + //llWhisper(0,"Sleeping for five seconds in SpamPrevention."); //debug message + llSleep(5.0); //wait five seconds. **Cannot recieve further touch!** + // llWhisper(0,"Awake in SpamPrevention"); //debug message + spam = FALSE; + waiter = 0; + llSetTimerEvent(3.0); +} SelfTouch(){ // response to owner's attempt to touch patter. + if (active == TRUE) { //if considered active, run spam prevention + SpamPrevention(); + } else { //if not active, set hover text to self touch dialogue + active = TRUE; //set to active for spam prevention + // llWhisper(0, "SelfTouch() running\nActive: "+(string)active+" Spam: "+(string)spam); //debug message + SetStatus(); //set hover text + waiter = 0; + llSetTimerEvent(3.0); //run timer() every three seconds + } +} PlaySound() { + llTriggerSound(sound,0.3); // sound at 30% volume +} Response() { //do the things test + active = TRUE; //set to active for spam prevention + SetStatus(); //set hover text + ++pets; //increase pets counter by one + llRequestPermissions(llDetectedOwner(0), PERMISSION_TRIGGER_ANIMATION); //load anim. permissions from object owner + if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) { // if permissions granted, play animations + llStartAnimation("Tail_Wag_High"); + llStartAnimation("TonguePanting"); + llStartAnimation("Jaw3"); + } PlaySound(); + llParticleSystem( [ //emit particles. This long block is just particle properties. + PSYS_PART_FLAGS, 0 + | PSYS_PART_WIND_MASK + | PSYS_PART_EMISSIVE_MASK + | PSYS_PART_FOLLOW_SRC_MASK + | PSYS_PART_INTERP_COLOR_MASK, + PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE, + PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>, + PSYS_PART_START_SCALE, <0.3, 0.3, 0.3>, + PSYS_PART_START_ALPHA, 1.0, //start completely opaque + PSYS_PART_END_ALPHA, 0.01, //end nearly transparent + PSYS_SRC_BURST_RATE,6.0, + PSYS_SRC_BURST_PART_COUNT,10, //spawn ten hearts + PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>, + PSYS_PART_MAX_AGE, 5.0, //last 5 seconds + PSYS_PART_START_GLOW, 0.01, //start lightly glowing + PSYS_PART_END_GLOW, 0.0, //end with no glow + PSYS_SRC_TEXTURE, particle + ] ); + waiter = 0; + llSetTimerEvent(3.0); //run timer() every 3 seconds +} StopEverything() { //remove toucher data, stop particle effects, stop animations. + toucher = NULL_KEY; //remove toucher info. Cannot set this to 0 due to type error + llParticleSystem([]); + if (pets>0) { //if more than zero pets, stop animations. when this isn't in there, it give an error bc it tries to stop animations that don't have permissions yet + llStopAnimation("Tail_Wag_High"); + llStopAnimation("TonguePanting"); + llStopAnimation("Jaw3"); + } active = FALSE; +} default { + state_entry() { //when the script starts, grab owner UUID, set the particle system up, and begin timer() + llParticleSystem([]); + llSetTimerEvent(3.0); //this is just to fade the starting hover text + self = llGetOwner(); //grab the UUID of object owner + } touch_start(integer toucherQuant) { //upon touch, grab the amount of people touching, usually one + // llWhisper(0, "touch_start\nActive: "+(string)active+" Spam: "+(string)spam); //debug message + if(toucherQuant == 1) { // if only one person is touching, grab their UUID + toucher = llDetectedKey(0); + //llWhisper(0, (string)toucher+" is touching "+(string)self); //debug message + if(toucher != self) { //if the toucher isn't the owner + string toucherName = llGetDisplayName(llDetectedKey(0)); //grab the name of whoever touched the patter + if(active == FALSE) { // if Response() is not going and someone other than the owner touches it, run Response() + WhisperAlias(doggo,(string)toucherName+" pets "+(string)doggo+" the dog's "+(string)bodyOne+"."); + Response(); //do sound and particles + } else if (active == TRUE) { //if Response() is running and someone touches it, begin spam prevention + SpamPrevention(); + } + } else { //if the owner has touched while Response was not running, run SelfTouch() + SelfTouch(); + } + } else { // if there are multiple touchers, begin spam prevention + SpamPrevention(); + } + } timer() { //stop everything, reset the hover text, and intiate a counter + StopEverything(); + SetStatus(); + ++waiter; + // llWhisper(0,(string)waiter+" in timer."); //debug message + if (status == TRUE && waiter > 4) { // if there's hover text (which there should be) and the counter is over four, fade the hover text and end the timer + FadeStatus(); + llSetTimerEvent(0.0); //end the timer + } + } changed(integer change) { //if the owner of the object changes, reset the script + WhisperAlias("Headpatter", "Object owner has changed."); //debug message + if(change & CHANGED_OWNER) llResetScript(); + } +} + diff --git a/HellhundHeadpatterScript/README.md b/HellhundHeadpatterScript/README.md new file mode 100644 index 0000000..3e8f372 --- /dev/null +++ b/HellhundHeadpatterScript/README.md @@ -0,0 +1,20 @@ +# HellhundHeadpatter +## Current Features +- Plays sound, particle effects, and animations specific to the Hellhund when touched. + - Unclear how animations will affect other avatars. +- End user customization such as adding their own texture for the particle effect, adding their own sounds, customizing the dog name, and customizing the dog part petted such as the head or the belly. +- Sets hover text to a number of dyanmic messages. +- Counts and displays the number of pets recieved. +- Whispers under alias so that all whisper messages are under the dog's name. +- Fades hover text after adjustable time as to not annoy others. +- Prevents spamming by owner or others. +- Resets script upon owner change. +## Planned Features +- Linked prim set up where each prim corresponds to a body part with a single script. + - Current system: Put script into each prim. +- More animations, perhaps randomized. +- More sounds, perhaps randomized. +- Animate the toucher with petting animation? + - Must verify that the toucher is biped. + - Might need to move toucher + - RLV? diff --git a/Super-Simple-Needs-HUD-SL/README.md b/Super-Simple-Needs-HUD-SL/README.md new file mode 100644 index 0000000..4dfb2e5 --- /dev/null +++ b/Super-Simple-Needs-HUD-SL/README.md @@ -0,0 +1,4 @@ +# Super Simple Needs HUD Second Life +This script creates a very simple way to roleplay natural needs in Second Life. + +**Update October 2022** - Overhauling the Super Simple Needs HUD from the ground up. Seeking collaboration on HUD design and features. diff --git a/Super-Simple-Needs-HUD-SL/Super Simple Needs.lsl b/Super-Simple-Needs-HUD-SL/Super Simple Needs.lsl new file mode 100644 index 0000000..c96729b --- /dev/null +++ b/Super-Simple-Needs-HUD-SL/Super Simple Needs.lsl @@ -0,0 +1,264 @@ +///Variables for needs decay +float sleep = 100; +float food = 100; +float hygiene = 100; +float bathroom = 100; +float sleepDecay = 0.104; +/* Calculating sleep decay rate: + One should be completely exhausted (0% sleep) after 16 hours + There are 960 minutes in 16 hours + 100 / 960 = 0.104 + In other words, to reach 0% sleep in 16 hours, the need must decay at a rate of 0.104 per minute. +*/ +float foodDecay = 0.208; +/* Calculating food decay rate: + One should eat three times a day, therefore every 8 hours + There are 480 minutes in 8 hours + 100 / 480 = 0.208 + In other words, to reach 0% food in 8 hours, the need must decay at a rate of 0.208 per minute +*/ +float hygieneDecay = 0.069; +/* Calculating food decay rate: + One should shower once a day, therefore every 24 hours. + There are 1440 minutes in 24 hours. + 100 / 1440 = 0.069 + In other words, in order to reach 0% hygiene in 24 hours, the need must decay at a rate of 0.069 per minnute +*/ +float bathroomDecay = 0.417; +/* Calculating bladder decay rate: + One should pee 6 times a day, therefore every 4 hours + There are 240 minutes in four hours + 100 / 240 = 0.417 + In other words, in order to reach 0% bathroom 6 times a day, the need must decay at a rate of 0.417 per minute +*/ +//vars for need increase buttons. These values reflect the link number of each prim button on the HUD. +integer sleep1Button = 26; //using numbers instead of '+' to avoid confusion +integer sleep2Button = 25; +integer sleep3Button = 24; +integer food1Button = 21; +integer food2Button = 22; +integer food3Button = 23; +integer hygiene1Button = 20; +integer hygiene2Button = 19; +integer hygiene3Button = 18; +integer bathroom3Button = 17; +//vars for menu buttons. these are the link number of each prim button referenced +integer resetButton = 14; +integer storeButton = 15; +integer bugButton = 16; +integer minButton = 13; +integer maxButton = 6; +integer detachMaxButton = 12; +integer detachMinButton = 7; +//vars for maximized bars. Again, the link number of the prim +integer sleepBarMax = 11; +integer foodBarMax = 10; +integer hygieneBarMax = 9; +integer bathroomBarMax = 8; +vector originalBarSizeMax = <0.015305, 0.345129, 0.046387>; +float originalBarWidthMax = 0.345129; //FIX THIS, this should be originalBarSizeMax.y, but that isn't working, argh. +//vars for minimized bars +integer sleepBarMin = 5; +integer foodBarMin = 4; +integer hygieneBarMin = 3; +integer bathroomBarMin = 2; +integer originalBarSizeMin; +integer originalBarWidthMin; +//other vars +key owner = NULL_KEY; //starts with a null value +integer update = 1; //how many seconds between updates, i.e., how often timer() runs +integer maxxed = TRUE; //tracking whether minimized or maximized +float displayFloor = 5.0; //minimum need value to display +vector black = <0.0, 0.0, 0.0>; +float opaque = 1.0; +vector maxxedRotation = <0.0, 0.0, 0.0>; //the rotation that the linkset is in to show the maximized view +vector minnedRotation = <0.0, 90.0, 0.0>; //the rotation that the linkset is in to show the minimized view +integer active; //for spam prevention +integer listenerID; +//functions +ResetEverything() { //LATER: add a dialogue box confirming you want to reset everything? + llOwnerSay("Reseting everything."); //debug, might keep it in + llSetTimerEvent(0.0); // pausing the timer + sleep = 100; + food = 100; + hygiene = 100; + bathroom = 100; + llSetTimerEvent(update); //continue the timer as normal +} +float DecayProcess(float need, float decay) { + integer updateDecay = 60 / update; //the decay rate above is in minutes, but update is often in seconds, thus we need a decay rate adjustment + if (need > 0 && need <= 100) { //if need is in normal range + //need -= (decay / updateDecay); //decay it + need -= decay; //faster normal decay for testing / debugging: this is one minute of decay per update + } else if (need > 100) { //if need is over normal range + need = 100; //set it to 100 + } else { //if need is below normal range + need = 0; //set it to zero + } return need; +} +DisplayUpdate(float need, integer barLink) { + if(need > displayFloor) { //if need above minimum size, do normal stuff + //llSetLinkPrimitiveParamsFast(barLink,[ PRIM_TEXT, "", ZERO_VECTOR, 0]); //remove any hover text + float bigBarWidth = originalBarWidthMax * (need / 100); //calculate size to proprotionally represent the need % + float smallBarWidth = originalBarSizeMin * (need / 100) //calc. size of minimized bars + llSetLinkPrimitiveParamsFast(barLink,[PRIM_SIZE, <0.015305, barWidth, 0.046387>]); //adjust size of need bar. LATER: adjust bar to always be left aligned + //set size of minimized bars + } else { //if need is at or below minimum size + //llSetLinkPrimitiveParamsFast(barLink,[ PRIM_TEXT, "!", black, opaque]); //set an alert hover text. Replace this with something else later? + float bigBarWidth = originalBarWidthMax * (displayFloor/100); //calculate minimum bar size + float smallBarWidth = originalBarSizeMin * (displayFloor/100); + llSetLinkPrimitiveParamsFast(barLink,[PRIM_SIZE, <0.015305, barWidth, 0.046387>]); //set bar width to that + //set size of minimized bars + } + // llOwnerSay("Just updated "+(string)need+" display. The width is now "+(string)barWidth+"."); //debug +} +SpamPrevention() { + llOwnerSay("Please wait for the HUD to update before pressing buttons again."); + llSleep(update * 3); +} +ChangeMinMax() { + if (maxxed == FALSE) { //if currently minimized but sent here, maximize + //set linkset rotation to maxxedRotation + //set maxxed to TRUE + } else if (maxxed == TRUE) { //if currently maximized but sent here, minimize + //set linkset rotation to minnedRotation + //set maxxed to FALSE + } +} +SleepButtons(integer button) { //thought process here is that while you're sleeping, you often wake up to use the bathroom or wake up hungry + if(button == sleep1Button) { //if sleep+ + sleep += 33; + bathroom -= 15; + food -= 15; + } else if(button == sleep2Button) { //if sleep++ + sleep += 66; + bathroom -= 20; + food -= 20; + hygiene -= 5; //if you're sleeping long enough, you might get sweaty, etc. + } else { //if sleep++ + sleep += 100; + bathroom -= 25; + food -= 25; + hygiene -= 10; + } +} +FoodButtons(integer button) { //thought process here is that eating definitely makes you have to use the br, if can often make you sleepy, and might be messy + if(button == food1Button) { //if food+ + food += 33; + bathroom -= 15; + sleep -= 5; + hygiene -= 5; + } else if(button == food2Button) { //if food++ + food += 66; + bathroom -= 20; + sleep -= 10; + hygiene -= 10; + } else { //if food+++ + food += 100; + bathroom -= 25; + sleep -= 15; + hygiene -= 15; + } +} +HygieneButtons(integer button) { //can't think of any other need effects of hygiene + if(button == hygiene1Button) { //if hygiene+ + hygiene += 33; + } else if (button == hygiene2Button) { //if hygiene++ + hygiene += 66; + } else { //if hygiene+++ + hygiene += 100; + } +} +BathroomButtons(integer button) { //obviously using the bathroom makes your hands and possibly body dirty + bathroom += 100; //only one button for bathroom + hygiene -= 33; +} +MenuButtons(integer button, key toucher) { + integer dialogResponse; + if(button == resetButton) { + dialogResponse = ConfirmDialog(button, toucher); + ResetEverything(); + } else if(button == storeButton) { + llLoadURL(toucher, "Here's the Littlepaws marketplace store!", "https://marketplace.secondlife.com/stores/244066"); + } else if(button == bugButton) { + llLoadURL(toucher, "Please report bugs here:", "https://github.com/ChaseLittlepaws/SuperSimpleNeedsHUD/issues"); + } else if (button == detachMaxButton || button == detachMinButton) { //later, add dialogue box confirming detach + dialogResponse = ConfirmDialog(button, toucher); + llOwnerSay("Fix DetachHUD()"); //this isn't working right now. run_time_permissions throws a syntax error + } else if(button == minButton || button = maxButton) { + ChangeMinMax(); + } +} +/*DetachHUD() { + llRequestPermissions(owner, PERMISSION_ATTACH); //request attachement permissions + run_time_permissions(integer perm) { + if(perm && PERMISSION_ATTACH) { + llOwnerSay("Detaching SSNeeds HUD"); + llDetachFromAvatar(); + } else { + llOwnerSay("I don't have permissions to do that."); + } + } +}*/ +integer ConfirmDialog(integer button, key toucher){ + integer dialogChannel = -1 - (integer)("0x" + llGetSubString( (string) llGetKey(), -7, -1) ); //generates a negative, semi-random, non-zero channel for dialog menus to speak in + list dialogOptions = ["Yes", "No"]; + if(button == resetButton) { + llDialog(toucher, "Do you really want to reset all of the values?", dialogOptions, dialogChannel); + listenId = llListen(dialogChannel, "", toucher, ""); + } else if(button == detachMaxButton || button == detachMinButton) { + llDialog(toucher, "Do you really want to detach the SSNeeds HUD?", dialogOptions, dialogChannel); + listenId = llListen(dialogChannel, "", toucher, ""); + } + listen(integer channel, string name, key id, string message) { + if(message == "Yes") { + return TRUE; + } else { + return FALSE; + } + } +} +default { + state_entry() { + ResetEverything(); //this is only here for debug purposes. Possibly remove later + owner = llGetOwner(); //to compare to toucher + } + timer () { + sleep = DecayProcess(sleep, sleepDecay); + food = DecayProcess(food, foodDecay); + hygiene = DecayProcess(hygiene, hygieneDecay); + bathroom = DecayProcess(bathroom, bathroomDecay); + DisplayUpdate(sleep, sleepBarMax); + DisplayUpdate(food, foodBarMax); + DisplayUpdate(hygiene, hygieneBarMax); + DisplayUpdate(bathroom, bathroomBarMax); //display updates after decay process so HUD will never display outside of normal ranges + llListenRemove(listenerID); + active = FALSE; + // llOwnerSay("Sleep: "+(string)sleep+"\nFood: "+(string)food+"\nHygiene: "+(string)hygiene+"\nBathroom: "+(string)bathroom); //debug message + } + touch_start(integer toucherQuant) { + if(active == TRUE) SpamPrevention(); + active = TRUE; + llListenRemove(listenerID); + key toucher = llDetectedKey(0); //grab the uuid of toucher + if(toucher != owner) { //if someone other than the owner touches the hud, that's weird. + llOwnerSay("That's weird, someone else touched your Super Simple Needs HUD?"); //debug message + } else { //if toucher is owner, good + integer touchedButton = llDetectedLinkNumber(0); //grab the link number of the touched prim + //llOwnerSay("That button is: "+(string)llGetLinkPrimitiveParams(touchedButton, [PRIM_SIZE])); //debug + llOwnerSay("You touched "+(string)touchedButton+". "); //debug message + if(touchedButton == sleep1Button || touchedButton == sleep2Button || touchedButton == sleep3Button) { //if touched button is one of the sleep buttons + SleepButtons(touchedButton); + } else if(touchedButton == food1Button || touchedButton == food2Button || touchedButton == food3Button) { //if touched button is one of the food buttons + FoodButtons(touchedButton); + } else if(touchedButton == hygiene1Button || touchedButton == hygiene2Button || touchedButton == hygiene3Button) { //if touched button is one of the hygiene buttons + HygieneButtons(touchedButton); + } else if(touchedButton == bathroom3Button) { //if touched button is the bathroom button + BathroomButtons(touchedButton); + } else { //otherwise, probably a menu button + MenuButtons(touchedButton, toucher); + } + //llOwnerSay("\nSleep: "+(string)sleep+"\nFood: "+(string)food+"\nHygiene: "+(string)hygiene+"\nBathroom: "+(string)bathroom); //debug message + } + } +}