03-28-2004 17:06
Howdy!

Here's a simple script I agreed to write up for someone. I have a policy now - if I decide to write a script for someone for free, I'll also post it here to the script library for all to use as they see fit.

I'll also explain what they do and how they work, on a basic level, so that the new folks (whom these scripts will be for anyway) can dissect them and perhaps learn something new in the process. I'm no master coder, and of course my *really good* scripts won't be posted here, but I do hope what I *can* do will at least help a few new people along the way.

The following script controls particle effects for what I call "Movie Monsters," but its practical use is limited only to imagination. What it allows the owner to do is fire three different particle effects on command. The owner can edit the constants in the script to define what those commands are. The owner can also change the particle effects, the things the "monster" says in response to commands, who to accept commands from, what channel to listen to, and other details for custom functionality.

To use this script for your own purposes, you'll want to use Ama's very handy particle script to generate your effects, and plug those effects (copy & paste) into the constants in my script below. Once you've plugged that data into my script, and changed some of the other constants to suit your needs, put the script in an object and off you go!

To issue commands to the "monster," type the prefix followed by the monster's name, further followed by a command. For example, to tell the monster defined by the script I've provided to breath fire, use this command:

!monster fire

You can change the prefix, monster name, and commands that it accepts to whatever you like. I'm forcing you to use a prefix to issue a command to this script because it's just good practice. Otherwise, the script might respond to commands you didn't intend to give. A prefix tells the monster (and possibly people in the vicinity!) that you're talking specifically to it. Couple that with name verification like I've provided here, and you can have multiple monsters in the same area all responding to their own names and/or prefixes. Prefixes to commands that scripts respond to is just good practice, as I said. Use them.

The comments I've added into the script should explain not only how it works, but how you can adapt it to work for your own specific applications. The script has tons of expansion room. Perhaps you also want your monster to move around as well as breath fire. Or maybe you want it to deal/take damage, or play sound effects. Maybe it turns its head when it shoots out its flames? Follow you around?

Whatever the case, as you add to this script you can tell the monster:

!monster memory (use your monster's name and prefix)

....to get an idea of how much memory your monster script has left. If you start to use too much, there are things you can do. First of all, this doesn't have to be the only script on the monster! Use some link message commands to build yourself a modular monster. Also, it's wise to put the values of my constants straight into their places in the code if you expect this script to be a *real* basis for your monster. It's not as efficient to use this script as is, just like it's not efficient to use Ama's particle script for a finished product. It's not really designed for that purpose.

Nonetheless, this script should give anyone new to scripting a solid base to work off of. Use it, abuse it, maybe mention my name in it somewhere just 'cuz?

Enjoy!

-JMonde

P.S. This script has plenty of optimization potential aside from plugging the constants directly in. I invite newer coders to post solutions to those issues. You gurus can (please) ignore! It sure makes a CASE for a well-deserved conditional statement, doesn't it? Not to mention arrays. ;)

CODE

// Movie Monster Particles v0.1 (MMP) by JMonde 03/28/04
// Donated to the public domain

// User adjustable attributes
string NAME = "monster"; // monster's name - will only respond when name is spoken

// particle effects for monster - you can use Ama's script
// to make them, and then plug the output into these lists:
list EFFECT1 = [0, 292, 1, <0.00,1.00,0.00>, 2, 1.00, 4, 1.00, 5, <1.00,1.00,1.00>, 7, 2.00, 8, <3.00,0.00,0.00>,
9, 8, 10, 0.10, 11, 0.80, 13, 0.10, 15, 50, 16, 1.00, 17, 1.00, 18, 1.00, 19, 0.00, 21, <0.00,0.00,0.00>];

list EFFECT2 = [0, 292, 1, <0.00,1.00,0.00>, 2, 0.40, 4, 1.00, 5, <1.00,1.00,1.00>, 7, 1.00, 8, <3.00,0.00,2.00>,
9, 8, 10, 0.10, 11, 0.80, 13, 0.30, 15, 20, 16, 1.00, 17, 1.00, 18, 1.00, 19, 0.00, 21, <0.00,0.00,0.00>];

list EFFECT3 = [0, 292, 1, <0.00,1.00,0.00>, 2, 0.40, 4, 1.00, 5, <1.00,1.00,1.00>, 7, 1.00, 8, <3.00,0.00,2.00>,
9, 2, 10, 0.10, 11, 0.80, 13, 0.30, 15, 50, 16, 1.00, 17, 1.00, 18, 1.00, 19, 0.00, 21, <0.00,0.00,0.00>];

string PREFIX = "!"; // the command prefix - many people like '!' or '/' i.e. '!monster fire'

string COMMAND1 = "fire"; // define the actual commands the monster responds to
string COMMAND2 = "roast"; // change these to suit your needs
string COMMAND3 = "simmer";

string SHUT_OFF = "off"; // the command to turn any stubborn effects off

string MESSAGE1 = "Roar!"; // when the monster shoots its particles, it also says these
string MESSAGE2 = "Growl!";
string MESSAGE3 = "Hiss!";

float DELAY1 = 2.0; // how many seconds should each effect run?
float DELAY2 = 2.0;
float DELAY3 = 2.0;

integer OFF_MESSAGE = TRUE; // do we want our monster to say anything when shutting particles off?
string OFF_TEXT = "Ok, boss!"; // ^ if true, here's what it says

string BOSS = "Justice Monde"; // listen only to this person (use "" to take orders from anyone)
integer CHANNEL = 0; // listens on this channel only (0 is public chat channel)

// System variables (do not adjust)
integer hearing;
string command;
string param;
integer prefix_length;

// parser function - simple algorithm for chopping
// up bulk input. Very handy for any application that
// accepts commands
parse(string bulk)
{
list chunks = llParseString2List(bulk, [" "], []);
command = llList2String(chunks, 0);
param = llList2String(chunks, 1);
command = llDeleteSubString(command, 0, prefix_length - 1);
}


default
{
state_entry()
{
prefix_length = llStringLength(PREFIX);
llParticleSystem([]);
llListenRemove(hearing);
hearing = llListen(CHANNEL, BOSS, "", "");
}

touch_start(integer total_number)
{
llParticleSystem([]);
}

listen(integer channel, string name, key id, string message)
{
// check to see if first character of the command is our PREFIX and
// exit listen event if not
if (llGetSubString(message, 0,prefix_length - 1) != PREFIX)
return;

// send the command to the parser for processing
parse(message);

// did boss call our name? if not, we leave the event without
// testing for any conditions
if (command != NAME)
{
return;
}

// otherwise test conditions and act upon commands
if (param == COMMAND1)
{
llSay(0, MESSAGE1);
llParticleSystem(EFFECT1);
llSleep(DELAY1);
}
if (param == COMMAND2)
{
llSay(0, MESSAGE2);
llParticleSystem(EFFECT2);
llSleep(DELAY2);
}
if (param == COMMAND3)
{
llSay(0, MESSAGE3);
llParticleSystem(EFFECT3);
llSleep(DELAY3);
}
if (param == SHUT_OFF)
{
if (OFF_MESSAGE)
llSay(0, OFF_TEXT);
llParticleSystem([]);
}
if (param == "memory")
{
llSay(0, "Free memory: " + (string)llGetFreeMemory());
}

// after all conditions have been tested and/or run, turn off particles
llParticleSystem([]);
}
}

_____________________
JMonde Boatworks - Period ships and bad-ass powerboats - Myrtle 118, 118