Change font size
It is currently Sat Sep 21, 2019 1:09 pm

Forum rules


{L_IMAGE}



Post a new topicPost a reply Page 1 of 2   [ 14 posts ]
Go to page 1, 2  Next
Author Message
 Post subject: monster attack avatar
PostPosted: Fri Aug 03, 2018 1:43 pm 
Furious Typer

Joined: Mon Feb 13, 2017 1:53 pm
Posts: 65
Hi!
I am trying to create a dragon / monster.
Here is how it is supposed to work:

1. The dragon guards a gate and, at a moderate speed, attacks any avatar approaching.
2. The avatars must get through the gate.
3. If the avatar is hit by the dragon, the avatar is supposed to get "hurt", i.e. affected in some way.
4. The dragon is only supposed to attack / follow the avatar within a certain range near the gate.
Then it is supposed to stop.
5. After some time standing idly, the dragon is supposed to get back to its starting position in front of the gate.


Here are my problems:

3. "Hurt" the avatar.
a) I tried "bullet" / "combat" scripts for the dragon.
They can inflict actual "damage" to an avatar and even "kill" the avatar.
However, the bullet prim disappears after impact, and I was not able to change that.
This is not very useful for a monster/ dragon.

b) I made the dragon teleport the avatar to a different location through a different script.
However, this is only a make-shift solution.
Is there maybe a better one?

4. How can the dragon stop and not follow the avatar beyond a certain distance from the gate?
5. How can the dragon get back to its original position in front of the gate when standing idly for some time?

Here is the script I used for the dragon "attacking" the avatar.
It is from: http://wiki.secondlife.com/wiki/LlMoveToTarget#Examples
The movement is not very smooth, though,
and I was not able to adjust the script so that the dragon goes back to its starting position after some time.
I assume LlMoveToTarget is in conflict with going back or something like that.
Here is the script

{L_CODE}:
default
{
    state_entry()
    {
        vector pos = llGetPos();
        llSetStatus(STATUS_PHYSICS, TRUE);
        // Little pause to allow server to make potentially large linked object physical.
        llSleep(1.0);
        llMoveToTarget(pos,5.0);
        // Look for avatar within 10 meters in 360 degree arc every 1 seconds.
        llSensorRepeat("", "", AGENT, 10.0, PI,1.0);
    }
    sensor(integer total_number)
    {
        // Get position of detected owner
        vector pos = llDetectedPos(0);
        // Offset back one meter in X and up one meter in Z based on world coordinates.
        vector offset =<0,0,1>;
        // offset = offset*llDetectedRot(0);  //Adding this line will orient the follower relative to the owner's position.
        pos+=offset;
        llMoveToTarget(pos,5.0);     
    }
}


I also used "follower" scripts, but I could not make the "follower" go back to its starting position, either.

Any ideas will be appreciated. :)


Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Sat Aug 04, 2018 2:54 pm 
Furious Typer
User avatar

Joined: Fri Mar 26, 2010 12:11 pm
Posts: 235
Location: Belgium / Brussels
Basically, here's what it looks like with an object, but it would probably be better with an NPC ...
{L_CODE}:
// Object Guardian v0.1 by djphil (CC-BY-NC-SA 4.0)

float radius = 5.0;
float damage = 1.0;
float rate = 1.0;
integer start_id;
vector start_pose;
key user_uuid;
string user_name;

initialisation()
{
    llSetStatus(STATUS_PHYSICS, FALSE);
    llSetRot(ZERO_ROTATION);
    llSetStatus(STATUS_RETURN_AT_EDGE | STATUS_PHYSICS, TRUE);
}

default
{
    state_entry()
    {
        initialisation();
        start_pose = llGetPos();
        llSensorRepeat("", "", AGENT, radius, PI, rate);
    }

    sensor(integer n)
    {
        user_name = llDetectedName(0);
        user_uuid = llDetectedKey(0);
        vector user_pose = llDetectedPos(0);
        vector offset = <0.5, 0.0, 0.5>;
        offset = offset * llDetectedRot(0);
        user_pose += offset;
        llMoveToTarget(user_pose, 0.5);
        llSetText("[GUARDIAN]\nI see you " + user_name, <1.0, 1.0, 1.0>, 1.0);
       
        if (llVecDist(start_pose, user_pose) > radius)
        {
            llMoveToTarget(start_pose, 0.5);
            initialisation();
            llSetText("[GUARDIAN]\nToo far " + user_name, <1.0, 1.0, 1.0>, 1.0);
        }
    }

    no_sensor()
    {
        if (llVecDist(llGetPos(), start_pose) > 0.5)
        {
            llMoveToTarget(start_pose, 0.5);
            initialisation();
            user_uuid = NULL_KEY;
            llSetText("[GUARDIAN]\nStandby ...", <1.0, 1.0, 1.0>, 1.0);
        }
    }

    collision(integer n)
    {
        if (llDetectedName(0) == user_name)
        {
            llSetText("[GUARDIAN]\nToo close " + user_name, <1.0, 1.0, 1.0>, 1.0);
            osCauseDamage(user_uuid, damage);
        }
    }
}

Enjoy! :)

_________________
Webmaster @ digitalconcepts.free.fr & digigrids.free.fr


Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Sun Aug 05, 2018 10:54 am 
Furious Typer

Joined: Mon Feb 13, 2017 1:53 pm
Posts: 65
Hi again!
Thank you very much for your amazing script again!
It works fabulously! :)

This opens a whole range of new opportunities.

I might come back in case I happen to have some detailed questions.

Maybe one thing, since we're at it
and in case it's not too annoying to explain:
How do you add this or a comparable script to an NPC?


Since I haven't found any scripts even closely like this one online
and other users might be interested in this script,
I also added two other scripts which can additionally be used for the dragon, below.
They can simply be added into the dragon
(I used a 1-prim one):

Here is a teleport script (from you, too, thanks again),
by which the dragon casts an avatar off to a different location,
when it reaches the avatar.


{L_CODE}:
// Sensor Teleporter v0.1 by djphil (CC-BY-NC-SA 4.0)

string  dest = "my island";
vector  land = <128.0, 128.0, 25.0>;
vector  look = <1.0, 1.0, 1.0>;
float   scan = 3.0;
float   temp = 5.0;

default
{   
    state_entry()
    {
        llSetSitText("Teleport");
        llOwnerSay("OS Teleportal Active ...");
        llSensorRepeat("", "", AGENT, scan, TWO_PI, temp);
    }

    sensor (integer number)
    {
        key user = llDetectedKey(0);
        llInstantMessage(user, "Bye, bye!");
        osTeleportAgent(user, dest, land, look);
    }

    changed(integer change)
    {
        if (change & CHANGED_OWNER) llResetScript();
        if (change & CHANGED_REGION) llResetScript();
        if (change & CHANGED_REGION_START) llResetScript();
        if (change & CHANGED_REGION_RESTART) llResetScript();
    }

    on_rez(integer param)
    {
        llResetScript();
    }
}



Here is a script which makes the dragon rotate to the avatar,
so it does not move sideways toward the avatar:

{L_CODE}:
//This rotation script works! It only rotates on the z-axis to face the detected avatar. The other axes are locked.
// The key part of this came from Herkimer Highmist via the Google+ group Opensim Technology (3 Nov 2014).

vector vTarget;
float strength = 0.1;//KAYLEE NOTES: for the llRotLookAt
float damping = 1.0;//KAYLEE NOTES: for the llRotLookAt
integer link_message_channel = 35;//Kaylee notes: this is listening for messages from the llMoveToTarget + llSensor script. (14 March 2015)

default
{
    state_entry()
    {
        llOwnerSay("NPC automatic rotation script activated");
        llSensorRepeat("",NULL_KEY,AGENT,65.0,PI,5.0);
         
    }
    link_message(integer sender_num, integer num, string message, key id)
    {
        if(num == link_message_channel)
        {
            if(message == "activate_rotation")
            {
                llSensorRepeat("",NULL_KEY,AGENT,65.0,PI,5.0);
            }
            else if(message == "deactivate_rotation")
            {
                llSensorRemove();
            }
        }
    }
     sensor( integer det )
     {
        integer st = (integer) llFrand((float)det);
        vTarget = llDetectedPos(st);
        vector vPos= llGetPos();
        llRotLookAt(llRotBetween(<0.45,-10.45,0>,llVecNorm(<vTarget.x - vPos.x,vTarget.y - vPos.y,0>)),strength,damping);
    } 
}




Thank you very much for your help again! :-)


Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Sun Aug 05, 2018 7:46 pm 
Furious Typer
User avatar

Joined: Fri Mar 26, 2010 12:11 pm
Posts: 235
Location: Belgium / Brussels
It is not advisable to cumulate these scripts because there is a sensor in each of them but it is better to add these options in the main script directly.

The script below does the following job:
• Move guardian (TRUE/FALSE)
• Point avatar (TRUE/FALSE)
• Float on ground/water (TRUE/FALSE) + level
• Hemisphere/Full Sphere Scan
• Return at edge (TRUE/FALSE)
• Cause damage (0.0 = disabled)
• Kill avatar (TRUE/FALSE)
• Restore health (TRUE/FALSE)
• Display text over (TRUE/FALSE)
• Display text health (TRUE/FALSE)
• Adjustable initial rotation

And to prevent default behavrious:
• Push the avatar (TRUE/FALSE)
• Teleport avatar at home (TRUE/FALSE)
• Teleport avatar anywhere (TRUE/FALSE)
• Eject avatar (no recommended) (TRUE/FALSE)

Object Guardian v0.3 by djphil (CC-BY-NC-SA 4.0)
{L_CODE}:
// Object Guardian v0.3 by djphil (CC-BY-NC-SA 4.0)

integer mover = TRUE;   // Move guarian (TRUE/FALSE)
integer point = TRUE;   // Point avatar (TRUE/FALSE)
integer atrot = TRUE;   // Combined with point = TRUE

integer hover = TRUE;   // Float ground/water (TRUE/FALSE)
integer water = FALSE;  // Combined with hover = TRUE
float level = 1.0;      // Combined with hover = TRUE

integer kiler = FALSE;  // Kill avatar (like default behavrious)
integer drive = TRUE;   // Push avatar out of radius.
integer telep = FALSE;  // Teleport avatar.
integer ahome = FALSE;  // Teleport at home (like default behavrious)
integer eject = FALSE;  // Eject avatar (not recommended)
integer there = FALSE;  // Teleport avatar there
string dest = "";       // If empty, default is: this region
vector pose = "";       // If empty, default is: <128.0, 128.0, 128.0>
vector look = "";       // If empty, default is: <1.0, 1.0, 1.0>

integer texte = TRUE;   // Display text over
integer healt = TRUE;   // Combined with texte = TRUE
integer resto = TRUE;   // Restore avatar life to 100
integer edges = TRUE;   // Return at edge
integer bytwo = FALSE;  // Hemisphere/Full Sphere Scan
float radius = 5.0;     // Scan range
float rate = 1.0;       // Scan rate
float damage = 1.0;     // Damage to avatar
integer start_id;
vector start_pose;
key user_uuid;
string user_name;

reset_rotation()
{
    llSetStatus(STATUS_PHYSICS, FALSE);
    llSetRot(llEuler2Rot(<0.0, 0.0, 0.0> * DEG_TO_RAD));
    llSetStatus(STATUS_PHYSICS, TRUE);
}

default
{
    state_entry()
    {
        start_pose = llGetPos();
        if (edges) llSetStatus(STATUS_RETURN_AT_EDGE, TRUE);
        if (!texte) llSetText("", <1.0, 1.0, 1.0>, 1.0);
        if (bytwo) llSensorRepeat("", "", AGENT, radius, PI_BY_TWO, rate);
        else llSensorRepeat("", "", AGENT, radius, PI, rate);
    }

    sensor(integer n)
    {
        user_name = llDetectedName(0);
        user_uuid = llDetectedKey(0);
        vector user_pose = llDetectedPos(0);
        vector offset = <0.5, 0.0, 0.5>;
        offset = offset * llDetectedRot(0);
        user_pose += offset;

        if (mover) llMoveToTarget(user_pose, 0.5);

        if (point)
        {
            if (atrot) llRotLookAt(llRotBetween(<0.45, -10.45, 0.0>, llVecNorm(<user_pose.x - start_pose.x, user_pose.y - start_pose.y, 0.0>)), 0.5, 1.0);
            else llLookAt(user_pose, 0.5, 1.0);
        }

        if (texte)
        {
            if (healt) llSetText("[GUARDIAN]\nI see you " + user_name + " (" + (integer)osGetHealth(user_uuid) + "% ♥)", <1.0, 1.0, 1.0>, 1.0);
            else llSetText("[GUARDIAN]\nI see you " + user_name, <1.0, 1.0, 1.0>, 1.0);
        }

        if (llVecDist(start_pose, user_pose) > radius)
        {
            if (mover) llMoveToTarget(start_pose, 0.5);
            if (!point) reset_rotation();

            if (texte)
            {
                if (healt) llSetText("[GUARDIAN]\nToo far " + user_name + " (" + (integer)osGetHealth(user_uuid) + "% ♥)", <1.0, 1.0, 1.0>, 1.0);
                else llSetText("[GUARDIAN]\nToo far " + user_name, <1.0, 1.0, 1.0>, 1.0);
            }
        }
    }

    no_sensor()
    {
        if (llVecDist(llGetPos(), start_pose) > 0.25)
        {
            if (mover) llMoveToTarget(start_pose, 0.5);
            if (resto) osCauseHealing(user_uuid, 100.0);
            reset_rotation();
            user_uuid = NULL_KEY;
            if (texte) llSetText("[GUARDIAN]\nStandby ...", <1.0, 1.0, 1.0>, 1.0);
        }

        if (hover)
        {
            float upto = llGround(ZERO_VECTOR);
            if (water) upto = llWater(ZERO_VECTOR);
            start_pose = <start_pose.x, start_pose.y, upto + level>;
            llMoveToTarget(start_pose + <0.0, 0.0, -0.25 + llFrand(0.5)>, 0.5);
        }
    }

    collision(integer n)
    {
        if (llDetectedName(0) == user_name)
        {
            if (texte)
            {
                if (healt) llSetText("[GUARDIAN]\nToo ready " + user_name + " (" + (integer)osGetHealth(user_uuid) + "% ♥)", <1.0, 1.0, 1.0>, 1.0);
                else llSetText("[GUARDIAN]\nToo ready " + user_name, <1.0, 1.0, 1.0>, 1.0);
            }

            if (kiler && damage)
            {
                osCauseDamage(user_uuid, damage);
                return;
            }
           
            else if (osGetHealth(user_uuid) > damage + 1 && damage)
            {
                osCauseDamage(user_uuid, damage);
            }
           
            else
            {
                if (drive)
                {
                    vector push = <100.0, 100.0, 0.0> * llDetectedRot(0);
                    llPushObject(user_uuid, push, push, TRUE);
                }

                else if (telep)
                {
                    if (eject)
                    {
                        llEjectFromLand(user_uuid);
                        return;
                    }

                    if (ahome)
                    {
                        llTeleportAgentHome(user_uuid);
                        return;
                    }

                    if (there)
                    {
                        if (dest == "") dest = llGetRegionName();
                        if (pose == "") pose = <128.0, 128.0, 128.0>;
                        if (look == "") look = <1.0, 1.0, 1.0>;
                        osTeleportAgent(user_uuid, dest, pose, look);
                        return;
                    }
                }
                else {return;}
            }
        }
    }
}
And a little utility to get some region flags:
{L_CODE}:
// Get region flags v0.1 by djphil (CC-BY-NC-SA 4.0)

get_region_flags()
{
    if (llGetRegionFlags() & REGION_FLAG_ALLOW_DAMAGE)
        llOwnerSay("This Region Allow Damage");
    else llOwnerSay("This Region DON'T Allow Damage");
    if (llGetRegionFlags() & REGION_FLAG_DISABLE_PHYSICS)
        llOwnerSay("This Region DON'T Allow Physics");
    else llOwnerSay("This Region Allow Physics");
    if (llGetRegionFlags() & REGION_FLAG_DISABLE_COLLISIONS)
        llOwnerSay("This Region DON'T Allow Collisions");
    else llOwnerSay("This Region Allow Collisions");
    if (llGetRegionFlags() & REGION_FLAG_RESTRICT_PUSHOBJECT)
        llOwnerSay("This Region DON'T Allow Push Object");
    else llOwnerSay("This Region Allow Push Object");
}

default
{
    state_entry() {get_region_flags();}
    on_rez(integer p) {get_region_flags();}
    touch_start(integer n){get_region_flags();}
}
Enjoy! :)

_________________
Webmaster @ digitalconcepts.free.fr & digigrids.free.fr


Last edited by dj phil on Sat Mar 16, 2019 8:10 am, edited 7 times in total.

Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Mon Aug 06, 2018 12:38 pm 
Furious Typer

Joined: Mon Feb 13, 2017 1:53 pm
Posts: 65
Hi and thanks again for your amazing work.
I have already had a lot of fun playing with this script. :-)

There are only two little things I couldn't figure out,
but only reply if it's not too annoying.
You have already helped me greatly, either way.

The first thing is,
my avatars do not get teleported, neither the owner, nor others.
Do I have to make some more adjustments in the script?

Second, the avatars do not actually "die",
but the last health points always remain intact.
The risk of "dying" would make it still a bit more exciting.

Is there a way to make an avatar actually "die" with this script?


Thanks again! :)


Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Mon Aug 06, 2018 1:39 pm 
Furious Typer
User avatar

Joined: Fri Mar 26, 2010 12:11 pm
Posts: 235
Location: Belgium / Brussels
Hi, for teleportation you need to set DRIVE = FALSE and TELEP = TRUE.
Then you choose one between these 3 options (not cumulative):
{L_CODE}:
integer ahome = FALSE;  // Teleport at home (like default behavrious)
integer eject = FALSE;  // Eject avatar (not recommended)
integer there = FALSE;  // Teleport avatar there

And finaly if your choice is there = TRUE, then you can cumulate with:
{L_CODE}:
string dest = "";       // If empty, default is: this region
vector pose = "";       // If empty, default is: <128.0, 128.0, 25.0>
vector look = "";       // If empty, default is: <1.0, 1.0, 1.0>

For dead, the script prevent default dead behavrious with this line:
{L_CODE}:
if (osGetHealth(user_uuid) > damage + 1 && damage)

This mean the avatar health never go to 0% of health.
Else, either he push or teleport or eject or do nothing.
You can also restore health (or not) with resto = TRUE.
I hope you understand and you can teleport now.
Otherwise do not hesitate to ask questions.

Edit: I add new option in the script Object Guardian v0.3
{L_CODE}:
integer kiler = FALSE;  // Kill avatar (like default behavrious)

That mean if you set the value to TRUE then your avatar will be killed exactly like the default behavrious and in this case, other options will be ignored.

_________________
Webmaster @ digitalconcepts.free.fr & digigrids.free.fr


Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Tue Aug 07, 2018 7:32 am 
Furious Typer

Joined: Mon Feb 13, 2017 1:53 pm
Posts: 65
Hi again and thank you very much.
It works now. :D

I might come back for detail questions at some point,
but so far it is looking great.

Thanks again! :)


Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Tue Aug 07, 2018 5:37 pm 
Furious Typer
User avatar

Joined: Fri Mar 26, 2010 12:11 pm
Posts: 235
Location: Belgium / Brussels
Basically, here's what it looks like with an NPC but of course you can add sounds, animations, etc ...
{L_CODE}:
// NPC Guardian v0.1 by djphil (CC-BY-NC-SA 4.0)

integer point = TRUE;
integer flyer = TRUE;
integer kiler = FALSE;
integer resto = TRUE;
float damage = 10.0;
float radius = 5.0;

vector start_pose;
integer detected;
integer power;
key guardian;
key agent_uuid;

default
{
    state_entry()
    {
        if (llGetInventoryName(INVENTORY_NOTECARD, 0) != "appearance")
            osOwnerSaveAppearance("appearance");
        start_pose = llGetPos() + <0.5, 0.0, 1.0>;
    }

    touch_start(integer n)
    {
        if (power =! power)
        {
            guardian = osNpcCreate("NPC", "Guardian", start_pose, "appearance");
            osNpcSetRot(guardian, llGetRot() * llEuler2Rot(<0.0, 0.0, 0.0> * DEG_TO_RAD));
            llSensorRepeat("", "", AGENT, radius, PI, 1.0);
        } 

        else
        {
            osNpcRemove(guardian);
            llResetScript();
        }
    }

    sensor(integer n)
    {
        vector agent_pose = llDetectedPos(0);
        rotation agent_rote = llDetectedRot(0);
        agent_uuid = llDetectedKey(0);
        vector offset = <1.0, 0.0, 0.0>;
        offset = offset * agent_rote;
        agent_pose += offset;
        if (agent_pose.z > llGround(ZERO_VECTOR) + 1.5 && flyer) osNpcMoveToTarget(guardian, agent_pose, OS_NPC_FLY);
        else osNpcMoveToTarget(guardian, agent_pose, OS_NPC_NO_FLY);
        if (point) osNpcSetRot(guardian, agent_rote * llEuler2Rot(<0.0, 0.0, 180.0> * DEG_TO_RAD));
        if (kiler && damage) {osCauseDamage(agent_uuid, damage); return;}
        if (osGetHealth(agent_uuid) > damage + 1 && damage) osCauseDamage(agent_uuid, damage);

        else
        {
            vector push = <100.0, 100.0, 0.0> * llDetectedRot(0);
            llPushObject(agent_uuid, push, push, TRUE);
        }
    }

    no_sensor()
    {
        if (llVecDist(osNpcGetPos(guardian), start_pose) > 0.5)
        {
            osNpcMoveToTarget(guardian, start_pose, OS_NPC_NO_FLY);
            llSleep(1.0);
            osNpcSetRot(guardian, llGetRot() * llEuler2Rot(<0.0, 0.0, 0.0> * DEG_TO_RAD));
            if (resto) osCauseHealing(agent_uuid, 100.0);
        }
    }
}
Enjoy! :)

_________________
Webmaster @ digitalconcepts.free.fr & digigrids.free.fr


Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Wed Aug 08, 2018 11:05 am 
Furious Typer

Joined: Mon Feb 13, 2017 1:53 pm
Posts: 65
Just tried it out.
That NPC guard is awesome. :)
Thank you so much.
Yet another door is opening.
I love it. :D


Top
 Profile  
 
 Post subject: Re: monster attack avatar
PostPosted: Sun Feb 10, 2019 6:26 am 

Joined: Sun Jan 27, 2019 3:18 pm
Posts: 7
Sorry for bumping this thread again, but im having trouble making the object guardian do actual damage to my avatar!?

Everything is set accordingly in both the opensim.ini and osslenable.ini.

In world im able to damage my avatar by drag throwing a physical prim against him. (Health drops by 2-3 ticks).
osCauseDamage wont damage him tho.
The get region flags utility states everything is allowed.

What am i doing wrong?

Thank you! :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post a new topicPost a reply Page 1 of 2   [ 14 posts ]
Go to page 1, 2  Next


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
610nm Style by Daniel St. Jules of Gamexe.net