There are 3 scripts involved in this :
The HUD (Hammer Thrower)
// Project: Hammer thrower
// Script: Hammer launcher
// Get avatar name, or target all.
// Rez objects giving them target avatar name
// add channel command
//Simple OpenSource Licence (I am trusting you to be nice)
//1. PLEASE SEND ME UPDATES TO THE CODE
//2. You can do what you want with this code and object including selling it in other objects and so on.
//You can sell it in closed source objects if you must, but please try to send any updates or
//improvements back to me for possible inclusion in the main trunk of development.
//3. You must always leave these instructions in any object created; notecard written; posting to
//any electronic medium such as Forum, Email &c. of the source code & generally be nice (as
//already requested!)
//4. You must not claim that anyone apart from sparti Carroll wrote the original version of this software.
//5. You can add and edit things below =THE LINE= but please try to keep it all making sense.
//Thank you for your co-operation
//sparti Carroll
key k_owner;
integer channel_bullet = 540123;
integer channel_hammer = 477591;
integer channel_owner = 324;
integer channel_count = 1;
string lookingfor;
integer HUDcenter2 = 31;
integer HUDtopright = 32;
integer HUDtop = 33;
integer HUDtopleft = 34;
integer HUDcenter = 35;
integer HUDbottomleft = 36;
integer HUDbottom = 37;
integer HUDbottomright = 38;
integer HUD_default = HUDtopleft;
set_hudpos(integer whereami) {
vector my_size = llGetScale();
vector v_atpos;
if (whereami == HUDbottomleft) v_atpos = <0,-my_size.y/2,my_size.z/2>;
else if (whereami == HUDtopleft) v_atpos = <0,-my_size.y/2,-my_size.z/2>;
else if (whereami == HUDbottom || whereami == HUDbottomright) v_atpos = <0,0,my_size.z/2>;
else if (whereami == HUDtop || whereami == HUDtopright) v_atpos = <0,0,-my_size.z/2>;
else if (whereami == HUDcenter || whereami == HUDcenter2) v_atpos = <0,0,0>;
llSetPos(v_atpos);
}
reset() {
k_owner = llGetOwner();
llOwnerSay("Activated on channel " + (string)channel_owner);
integer whereami = llGetAttached();
if (whereami == 0) {
llOwnerSay("Please wear on the HUD");
} else {
set_hudpos(whereami);
}
llListen(channel_owner,"",k_owner,"");
}
attack(string avname) {
llRezObject("Bullet",llGetPos() + <0,0,5>,<0,0,0>,<0,0,0,0>,channel_count);
llSay(channel_bullet + channel_count,"attack^" + avname);
channel_count++;
llOwnerSay("Now hammering " + avname);
}
default
{
on_rez(integer start_param) {
reset();
}
state_entry() {
reset();
}
listen(integer channel,string name,key id,string message) {
if (id == k_owner) {
lookingfor = llToLower(message);
llSensor("",NULL_KEY,AGENT,100,PI);
}
}
sensor(integer num_detected) {
integer k;
integer foundpos;
for (k=0;k
no_sensor() {
llOwnerSay("No matching AV names");
}
attach(key id) {
integer whereami = llGetAttached();
set_hudpos(whereami);
}
}
The Bullet
// Project: Hammer thrower
// Script: Bullet
// Fly to target and rez hammer. Tell hammer AV name
// Target named avatar with thor's hammer
// rezzed by Launcher and passed avatar name on control channel
// weights fly to 30m above avatar, then rez weight which is physical and drops onto them
// they delete themselves after 10 minutes
// ZZZ can be deleted by chat
// ZZZ orbit around sim for 3 minutes if cannot find AV named
// pass channel number offset in rez param
//Simple OpenSource Licence (I am trusting you to be nice)
//1. PLEASE SEND ME UPDATES TO THE CODE
//2. You can do what you want with this code and object including selling it in other objects and so on.
//You can sell it in closed source objects if you must, but please try to send any updates or
//improvements back to me for possible inclusion in the main trunk of development.
//3. You must always leave these instructions in any object created; notecard written; posting to
//any electronic medium such as Forum, Email &c. of the source code & generally be nice (as
//already requested!)
//4. You must not claim that anyone apart from sparti Carroll wrote the original version of this software.
//5. You can add and edit things below =THE LINE= but please try to keep it all making sense.
//Thank you for your co-operation
//sparti Carroll
key k_owner;
integer channel_bullet = 540123;
integer channel_hammer = 477591;
integer time_livefor = 120; // could live longer
vector bomb_offset = <0,0,10>;
string avname;
set_position(vector targetpos) {
// fly to position
while (llVecDist(llGetPos(),targetpos) > 0.001) llSetPos(targetpos);
}
reset() {
k_owner = llGetOwner();
llSetAlpha(0.0,ALL_SIDES);
}
fly_to_av(vector avpos) {
set_position(avpos + bomb_offset);
}
drop_hammer() {
llRezObject("Hammer",llGetPos() + <0,0,0>,<0,0,0>,<0,0,1,PI>,1);
llSay(channel_hammer,"attack^" + avname);
}
default
{
on_rez(integer start_param) {
reset();
llSetTimerEvent(time_livefor);
channel_bullet += start_param;
llListen(channel_bullet,"","","");
}
state_entry() {
}
listen(integer channel,string name,key id, string message) {
list cmdline = llParseString2List(message,"^",[]);
string cmd = llList2String(cmdline,0);
string par = llList2String(cmdline,1);
if (cmd == "attack") {
// par is the avatar name
avname = par;
llSensor(avname,NULL_KEY,AGENT,300,PI);
} else if (cmd == "die") {
llDie();
}
}
no_sensor() {
// fly around looking for them
}
sensor(integer num_detected) {
vector avpos = llDetectedPos(0);
fly_to_av(avpos);
drop_hammer();
llDie();
}
}
The Giant Hammer
// Project: Hammer thrower
// Script: The hammer
// die() after 10mins
// chase avatar around bashing them
// non physical object, but use damage if they collide
// particle system of little hammers/anvils/sparks/lightning?
//Simple OpenSource Licence (I am trusting you to be nice)
//1. PLEASE SEND ME UPDATES TO THE CODE
//2. You can do what you want with this code and object including selling it in other objects and so on.
//You can sell it in closed source objects if you must, but please try to send any updates or
//improvements back to me for possible inclusion in the main trunk of development.
//3. You must always leave these instructions in any object created; notecard written; posting to
//any electronic medium such as Forum, Email &c. of the source code & generally be nice (as
//already requested!)
//4. You must not claim that anyone apart from sparti Carroll wrote the original version of this software.
//5. You can add and edit things below =THE LINE= but please try to keep it all making sense.
//Thank you for your co-operation
//sparti Carroll
integer FLAGdebug = FALSE;
integer channel_bullet = 540123;
integer channel_hammer = 477591;
// working
key hammer_avkey;
vector hammer_avpos; // current position of AV being attacked
string hammer_targetting; // name of AV being attacked
integer hammer_attacks; // how many attacks left
// configuration
integer hammer_new_attacks_on_touch = 3;
float hammer_attack_timeout = 120.0; // how long before die if in attack mode
// how long before start attack again in resting mode
float hammer_resting_timeout_min = 15.0; // minimum
float hammer_resting_timeout_range = 50.0; // range
set_position(vector targetpos) {
// fly to position
while (llVecDist(llGetPos(),targetpos) > 0.001) llSetPos(targetpos);
}
// can have several of these
animate_bash() {
//spin around to an arbitrary attack angle
//bash the av a random number of times
//do particle effects
//go to rest position
//set orientation
if (FLAGdebug) llOwnerSay("attack starts");
llSetPrimitiveParams(PRIM_PHYSICS,FALSE);
vector v_random_rot = <0,0,llFrand(360)> * DEG_TO_RAD;
rotation random_rot = llEuler2Rot(v_random_rot);
vector anim_blow_ready = <0,9,0> * random_rot;
anim_blow_ready += <0,0,9>;
vector nowpos = hammer_avpos + anim_blow_ready;
set_position(nowpos);
vector v_base_rotation = <45,0,0> * DEG_TO_RAD;
vector v_swipe_down_rotation = <135,0,0> * DEG_TO_RAD;
vector v_finish_rotation= <95,llFrand(90),llFrand(90)> * DEG_TO_RAD;
rotation hammer_base_rotation = llEuler2Rot(v_base_rotation);
rotation hammer_swipe_down_rotation = llEuler2Rot(v_swipe_down_rotation);
rotation hammer_finish_rotation = llEuler2Rot(v_finish_rotation);
hammer_base_rotation *= random_rot;
hammer_swipe_down_rotation *= random_rot;
hammer_finish_rotation *= random_rot;
llSetRot(hammer_base_rotation);
llSleep(1.0);
// pound on AV!
integer c_swipe;
float swipes_random = 10.0;
float swipes_base = 4.0;
integer num_swipes = (integer)(llFrand(swipes_random) + swipes_base);
for (c_swipe=0;c_swipe
animate_resting() {
llSetPrimitiveParams(PRIM_PHYSICS,TRUE);
}
reset() {
hammer_attacks = (integer)(llFrand(10.0) + 5.0);
llSetTimerEvent(120.0); // time to init
}
default {
on_rez(integer start_param) {
llListen(channel_hammer,"","","");
reset();
llSetPrimitiveParams(PRIM_PHYSICS,TRUE);
}
state_entry() {
if (FLAGdebug) llOwnerSay("Starting up");
reset();
}
listen(integer channel,string name,key id, string message) {
list cmdline = llParseString2List(message,"^",[]);
string cmd = llList2String(cmdline,0);
string par = llList2String(cmdline,1);
if (cmd == "attack") {
hammer_targetting = par;
state attack;
} else if (cmd == "die") {
llDie();
}
}
touch_start(integer num_detected) {
key k_touch = llDetectedKey(0);
if (k_touch == hammer_avkey) {
//start attack now and add some more attacks
hammer_attacks += (integer)llFrand(hammer_new_attacks_on_touch);
state attack;
} else {
string name = llKey2Name(k_touch);
float dowhat = llFrand(3.0);
if (dowhat < 2.0) {
llSay(0,"I have not come for you " + name + " so don't tempt me!");
} else {
llSay(0,"I had not come for you " + name);
llSleep(3.0);
llSay(0,"But I have changed my mind !!!");
hammer_targetting = name;
state attack;
}
}
}
timer() {
// failed to init
llOwnerSay("failed to initialise hammer: llDie");
}
}
state attack {
on_rez(integer start_param) {
// should not rez in this state
llDie();
}
state_entry() {
// find them (again) and attack
// turn off phys
hammer_attacks--;
llSensor(hammer_targetting,NULL_KEY,AGENT,300,PI);
llSetTimerEvent(hammer_attack_timeout);
}
no_sensor() {
// fly around looking for them
// die if not found after N seconds
}
sensor(integer num_detected) {
hammer_avkey = llDetectedKey(0);
hammer_avpos = llDetectedPos(0);
animate_bash();
// finshed attacking ?
if (hammer_attacks <= 0) {
llDie();
} else {
state resting;
}
}
touch_start(integer num_detected) {
// advertise ?
}
timer() {
llDie();
}
}
state resting {
// wait before attacking av again
on_rez(integer start_param) {
// should not be rezzed in this state
llDie();
}
state_entry() {
animate_resting();
llSetTimerEvent(hammer_resting_timeout_min + llFrand(hammer_resting_timeout_range));
}
touch_start(integer num_detected) {
key k_touch = llDetectedKey(0);
if (k_touch == hammer_avkey) {
//start attack now and add some more attacks
hammer_attacks += (integer)llFrand(hammer_new_attacks_on_touch);
state attack;
} else {
string name = llKey2Name(k_touch);
float dowhat = llFrand(3.0);
if (dowhat < 2.0) {
llSay(0,"I have not come for you " + name + " so don't tempt me!");
} else {
llSay(0,"I had not come foo you " + name);
llSleep(3.0);
llSay(0,"But I have changed my mind !!!");
hammer_targetting = name;
state attack;
}
}
}
timer() {
state attack;
}
}
Putting it together:
- put the Giant Hammer script in a hammer shaped object, maybe adjust params depending on hammer size, centre of rotation etc.
- put the Hammer in the Bullet object (any prim will do, but I use a tiny invisible one!) and add the Bullet script
- put the Bullet (now containing the Hammer) in the HUD object
When you wear the HUD it will tell you what to do.
You might want to pick up the complete thing in Chessport for free (near the telehub) or from SLX for L$1, that way you get the prim for the Giant Hammer and will see how the thing is put together.
Any updates/enhancements to this weapon gratefully received. Perhaps you can think of a way to make it actually dangerous ? or dangerous _sometimes_ !?
Coming soon the
100 Ton Weight Dropper !