this is a set of scripts i worked up to give some candles a "melting" effect. it basically shrinks the candle along the z axis and keeps the bottom fixed (the way it should be lol). the second 2 scripts are for the wick (if it's a seperate prim). it listens for a link message from the candle and moves to keep it's position relative to the candle. and the last is just a basic candle flame that i got from another thread. i'm providing 2 scripts for the wick movement because they act slightly different depending if the candle is the root prim or not
Melt Script
//Melting Candle Script
//Written by Ruthven Willenov
//Use as desired
//all the owner say calls are for testing and debugging purposes, remove or comment out if you don't want them there
integer on = 1;
vector startscale;
vector startpos;
float meltpercent = 0.05;
float melt;//calculated in the default state entry, this is the result of the percent from above from the scale of the candle IE: 5% of 0.200 is 0.010, if the result is smaller, it will not function correctly. raise/lower the percent accordingly
float delay = 1.0;//how many seconds between each "melt" 1 second is for testing, i recommend 60 seconds between each melt
startover(){//puts the candle back where it started
llOwnerSay("scale and positon reset"
;llSetScale(startscale);
llSetPos(startpos);
llMessageLinked(LINK_SET,0, "startover",""
;//tells the wick the candle has restarted}
default {
state_entry() {
startscale = llGetScale();
startpos = llGetLocalPos();
melt = startscale.z * meltpercent;//this is how much it will shrink along the z axis for each "melt", it will also be the ending scale on the z axis before the candle restarts
llMessageLinked(LINK_SET, 0,"candlereset",""
;//tells the wick the candle has been resetllOwnerSay("new start scale and position saved"
;llOwnerSay("melt amount is " + (string) melt + ". if it is smaller than 0.010, the script will not function correctly"
;}
touch_start(integer total_number) {
if (on) {
llSetTimerEvent(delay);//turns on the timer for the melt action
llOwnerSay("melt on"
;}
else {
llOwnerSay("melt off"
;llSetTimerEvent(0.0);//turns off the timer
startover();//puts candle back where it started
}
on = !on;
}
timer() {
vector scale = llGetScale();
if (scale.z <= melt) {
startover();//start over if the scale on the z axis is smaller than the melt amount
}
else {//otherwise continue melting
llSetScale(llGetScale() - <0.0,0.0,melt>
;//shrinks the z axis by the melt amountllSetPos(llGetLocalPos() - <0.0,0.0,melt/2> * llGetLocalRot());//moves the candle down the z axis by half of the melt amount
llMessageLinked(LINK_SET,0, "melted " + (string)melt,""
;//tells the wick the candle has melted and how muchllOwnerSay("melted"
;}
}
changed(integer change)
{
if (change & CHANGED_LINK)//used for testing between candle being the root or a child prim, remove this event if desired
llResetScript();
}
}
Wick Script 1
//this one is for when the candle is NOT the root prim
//IE: if you have the candle on a base
vector startpos;
startover(){
llOwnerSay("moved back to start pos"
;llSetPos(startpos);
}
default {
state_entry()
{
startpos = llGetLocalPos();
llOwnerSay("new start position saved"
;}
link_message(integer sender_num,integer num, string str, key id)
{
if (llGetSubString(str,0,5) == "melted"
//if the beginning of the message is "melted"{
llSetPos(llGetLocalPos() - <0.0,0.0,(float) llGetSubString(str,7,-1)> * llGetLocalRot());//moves the wick down the z axis by the amount given at the end of the message
}
else if (str == "startover"

{
startover();//if the candle says it start over, the wick needs to start over as well
}
else if (str == "candlereset"
//reset this script if the candle script has reset (in case the candle was moved or a link was changed){
llResetScript();
}
}
}
Wick Script 2
//this one acts the same was as the one above except it moves the wick by half of the amount given to it.
//this is for when the candle is the root prim
vector startpos;
startover(){
llOwnerSay("moved back to start pos"
;llSetPos(startpos);
}
default {
state_entry()
{
startpos = llGetLocalPos();
llOwnerSay("new start position saved"
;}
link_message(integer sender_num,integer num, string str, key id)
{
if (llGetSubString(str,0,5) == "melted"
//if the beginning of the message is "melted"{
llSetPos(llGetLocalPos() - <0.0,0.0,(float) llGetSubString(str,7,-1)/2> * llGetLocalRot());//moves the wick down the z axis by half of the amount given at the end of the message
}
else if (str == "startover"

{
startover();//if the candle says it start over, the wick needs to start over as well
}
else if (str == "candlereset"
//reset this script if the candle script has reset (in case the candle was moved or a link was changed){
llResetScript();
}
}
}
Candle Flame Script
default
{
state_entry()
{
llParticleSystem([
PSYS_PART_FLAGS, 0x103,
PSYS_SRC_PATTERN, 0x004,
PSYS_PART_START_ALPHA, 1.00,
PSYS_PART_END_ALPHA, 0.500,
PSYS_PART_START_COLOR, <1.00,1.00,0.00>,
PSYS_PART_END_COLOR, <1.00,0.00,0.00>,
PSYS_PART_START_SCALE, <0.06,0.08,0.00>,
PSYS_PART_END_SCALE, <0.01,0.01,0.00>,
PSYS_PART_MAX_AGE, 0.70,
PSYS_SRC_MAX_AGE, 0.00,
PSYS_SRC_ACCEL, <0.00,0.00,0.04>,
PSYS_SRC_ANGLE_BEGIN, 0.00,
PSYS_SRC_ANGLE_END, 0.09,
PSYS_SRC_BURST_PART_COUNT, 1,
PSYS_SRC_BURST_RADIUS, 0.001,
PSYS_SRC_BURST_RATE, 0.05,
PSYS_SRC_BURST_SPEED_MIN, 0.09,
PSYS_SRC_BURST_SPEED_MAX, 0.13,
PSYS_SRC_OMEGA, <0.00,0.00,0.00>,
PSYS_SRC_TEXTURE, "b708e484-aeef-8cc9-3896-dd661d4e6807"
]);
}
}
