Jump to content

KeeperS Karu

Resident
  • Posts

    354
  • Joined

  • Last visited

Posts posted by KeeperS Karu

  1. All righty! Thanks to help from someone (I need to ask them permission to mention them specifically), I was able to modify the melee weapon script so that by clicking the weapon, the player can choose which control scheme they want to use: Standard or mine. Here's the modified script. As usual, I'd love for some feedback on it. Eventually, I'm going to ask questions on what it means to "optimize" a script and how I can go about doing that for this script. But right now, I want to make sure it all works the way it's supposed to. And if it does, is there a better way to approach the situation? I have a way of complicating things more than they need to be. xD

     

    //PREAMBLE: Module Names
    //Module 1: Defining Global String Variables - Animation Names
    //Module 2: Defining Global String Variables - Sound Effect Names
    //Module 3: Defining Global String Variables - Bloodsplatter Object Name
    //Module 4: Defining Global Variables - MISC
         //Module 4A: Attack Types
         //Module 4B: Weapon Safety Variables
         //Module 4C: Weapon Control Scheme Variables
    //Module 5: The Safety & Release/Reset Functions
        //Module 5A: Safety On
        //Module 5B: Safety Off
        //Module 5C: Release Controls and Reset Script
    //Module 6: The Double Tap Code
        //Module 6A: Defining the Double-Tap Global Vairables
        //Module 6B: Obtaining the Time the Key Was Pressed
        //Module 6C: Comparing the Time Between Key Presses
        //Module 6D: Resetting the storedTime Variable
        //Module 6E: Double Tap
    //Module 7: The Sword Script
        //Module 7A: The Default State of the Sword Object When the Script Is First Executed
            //Module 7Aa: The Sword's Status When the Script is Reset - It Cannot Be Grabbed and Physically Dragged; Instruct Owner To Touch Sword For Options
            //Module 7Ab: Touch Weapon To Choose Control Scheme
            //Module 7Ac: Actions to Take When the Sword is Attached and Detached From the Avatar
            //Module 7Ad: If Permission Has Been Given, Take Over Keyboard Functions
            //Module 7Ae: Menu Choices
            //Module 7Af: Actions to Perform When the Timer Event is Triggered
        //Module 7B: When In The Keeper State, Use Keeper's Third Person Control Scheme
            //Module 7Ba: Actions To Take When The Weapon Is Attached/Detached    
            //Module 7Bb: Preliminary Actions On Entering State
            //Module 7Bc: What To Do When The Weapon Is Drawn & Sheathed
            //Module 7Bd: The Control Scheme, Keeper's Third Person    
            //Module 7Be: What To Do When The Object Changes Owner
        //Module 7C: When In State Standard, Use Standard Control Scheme
            //Module 7Ca: Actions To Take When The Weapon Is Attached/Detached    
            //Module 7Cb: Preliminary Actions On Entering State
            //Module 7Cc: What To Do When The Weapon Is Drawn & Sheathed
            //Module 7Cd: The Control Scheme, Standard Controls
            //Module 7Ce: What To Do When The Object Changes Owner
        //Module 7D: What To Do When When The Weapon Controls Are Used
            //Module 7Da: Setting The Timers    
            //Module 7Db: What Happens When The Timers Go Off    
            //Module 7Dc: Actions to Perform if There's a Valid Target within the Predefined Sensor Range
            //Module 7Dd: Actions To Take When There Is No Target Within Range
    
    //Module 1: Defining Global String Variables - Animation Names
    string fwdanim = "overhead_strike_exaggerated P6";
    string bckanim = "high_kick P6";
    string rotrightanim = "diagonal_left_strike_exag P6";
    string rotleftanim = "diagonal_right_strike_exag P6";
    string straferightanim = "upward_left_strike_exag";
    string strafeleftanim = "upward_right_strike_exag";
    string pgdwnanim = "basic_angle_block";
    string pgupanim = "backflip";
    
    //Module 2: Defining Global String Variables - Sound Effects Names
    string swdswing = "swordswing01";
    string swdconnectflsh = "sword_flesh_01";
    //string block swing; - If different from the other sound effects, enter them, here, as well as in the appropriate area of the code, below
    string blockconnect = "sword05";
    //string kick swing; - If different from the other sound effects, enter them, here, as well as in the appropriate area of the code, below
    string kickconnect = "Punch04";
    
    //Module 3: Defining Global String Variables - Bloodsplatter Object Name
    string bloodsplatter = "!bloodsplatter";
    
    //Module 4: Defining Global Variables - MISC
    
        //Module 4A: Attack Types
        integer SWORDFWD = 1;
        integer SWORDRGT = 2;
        integer SWORDLFT = 3;
        integer BLOCK = 4;
        integer KICK = 5;
        integer SPECIALATK = 6;
        integer strike_type;
        
        //Module 4B: Weapon Safety Variables
        
        string g_message;
        integer listen_handle;
        integer SAFETY_ON = TRUE;
        integer perm;
        
        //Module 4C: Weapon Control Scheme Variables
        
        integer gListener;
        string menuText = "\nChoose the movement controls you wish to use."; // you can change this to say whatever you want
        list menuButtons = ["Keeper","Standard","Cancel"]; // these are the buttons that will appear in the menu, you can change these
        integer menuChan; // channel that the dialog box talks on, will make this some large random negative number later on
        integer menuUsed = FALSE;
        integer KeeperS = FALSE;
        integer standardS = FALSE;
        
    //Module 5: The Safety & Release/Reset Functions
    
        //Module 5A: Safety On
        SAFETYON()
        {
            SAFETY_ON = TRUE; // switch the safety on
            llSay(0, "releasing controls");
            llReleaseControls();
        }
    
        //Module 5B: Safety Off
        SAFETYOFF()
        {
            SAFETY_ON = FALSE; // switch the safety off
            llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS|PERMISSION_TRIGGER_ANIMATION); // request permissions
            integer perm = llGetPermissions();
                
                if (perm != (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION))
                {
                    llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS|PERMISSION_TRIGGER_ANIMATION); // request permissions
                }
                else
                {
                    llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT, TRUE, TRUE);
                }
        }
        
        //Module 5C: Release Controls and Reset Script
        ReleaseReset()
        {
            llSay(0, "releasing controls");
            llReleaseControls();
            llResetScript();
        }
        
    //Module 6: The Double Tap Code
    
        //Module 6A: Defining the Double-Tap Global Vairables
        float strTime;
        float time;
        float storedTime;               
        float recentTime; 
        float interval = 1.25;
    
        //Module 6B: Obtaining the Time the Key Was Pressed
        getSeconds()
        {
            string timestamp    = llGetTimestamp();
            string subTime      = llGetSubString(timestamp, 19, 25);
            float wallclock     = llGetWallclock();
            strTime = (float)subTime + wallclock;
        }
        
        //Module 6C: Comparing the Time Between Key Presses              
        compareTimes(float stored, float recent)
        {
            time = recent - stored;
        }
        
        //Module 6D: Resetting the storedTime Variable
        resetStored()
        {
        storedTime = 0;
        }
        
        //Module 6E: Double Tap
        
        FStrike()
        {
            if (KeeperS == TRUE)
            {
            if ( time <= interval | time > interval )
            {
                llStartAnimation(fwdanim);
                strike_type = SWORDFWD;
            }
            }
            else if (standardS = TRUE)
            {
                llStartAnimation(fwdanim);
                strike_type = SWORDFWD;
            }
        }
        
        BStrike()
        {
            if ( time >= interval )
            {
                llStartAnimation(bckanim);
                strike_type = KICK;
            }
            else
            {
                llStartAnimation(fwdanim);
                strike_type = KICK;
            }
        }
        
        RLeft()
        {
            if ( time <= interval )
            {
                llStartAnimation(rotleftanim);
                strike_type = SWORDLFT;
            }
            else
            {
                llStartAnimation(strafeleftanim);
                strike_type = SWORDLFT;
            }
        }
        SLeft()
        {
            if ( time <= interval )
            {
                llStartAnimation(strafeleftanim);
                strike_type = SWORDLFT;
            }
            else
            {
                llStartAnimation(rotleftanim);
                strike_type = SWORDLFT;
            }
        }
        RRight()
        {
            if( time <= interval)
            {
                llStartAnimation(rotrightanim);
                strike_type = SWORDRGT;
            }
            else
            {
                llStartAnimation(straferightanim);
                strike_type = SWORDRGT;
            }
        }
        SRight()
        {
            if ( time <= interval )
            {
                llStartAnimation(straferightanim);
                strike_type = SWORDRGT;
            }
            else
            {
                llStartAnimation(rotrightanim);
                strike_type = SWORDRGT;
            }
        }
    
    //Module 7: The Sword Script
    
    
    //Module 7A: The Default State of the Sword Object When the Script Is First Executed
    default
    {
        //Module 7Aa: The Sword's Status When the Script is Reset - It Cannot Be Grabbed and Physically Dragged; Instruct Owner To Touch Sword For Options
        state_entry()
        {
            llSetStatus(STATUS_BLOCK_GRAB, TRUE);
            llOwnerSay("Touch the weapon to choose which movement controls you would like to use.");
        }
        
        //Module 7Ab: Touch Weapon To Choose Control Scheme
        touch_end(integer num_detected)
        {
            menuChan = (integer)(llFrand(999999.0) * -1);  // this just comes up with some big random negative number to use as the channel for the menu to work on
            llListenRemove(gListener);
            gListener = llListen(menuChan,"",llGetOwner(),"");   
            llDialog(llGetOwner(),menuText,menuButtons,menuChan);
            llSetTimerEvent(30.0); // just in case the person does not make a selection after clicking the weapon   
        }
        
        //Module 7Ac: Actions to Take When the Sword is Attached and Detached From the Avatar
        attach(key on)
        {
            if (on != NULL_KEY)
            {
                integer perm = llGetPermissions();
                
                if (perm != (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION))
                {
                    llRequestPermissions(on, PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
                }
                else
                {
                    llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT, TRUE, TRUE);
                }
                
            }
            else
            {
                //llSay(0, "releasing controls");
                //llReleaseControls();
                ReleaseReset();           
            }
        }
        
        //Module 7Ad: If Permission Has Just Been Given, Take Over Keyboard Functions
        run_time_permissions(integer perm)
        {
            if (perm)
            {
                llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT | CONTROL_DOWN, TRUE, TRUE);
            }
        }
        
        //Module 7Ae: Menu Choices
        
        listen(integer channel, string name, key id, string message)
            {   
                if(channel == menuChan)
                {
                    if(message == "Cancel") // give the user an opportunity to cancel out of the menu
                    {
                        menuUsed = TRUE;
                        return;
                    }
                    if(message == "Keeper") // if you change what the button name is on line 3, change this to match
                    {
                        menuUsed = TRUE;
                        state Keeper; // go to the keeper state
                    }
                    if(message == "Standard") // if you change what the button name is on line 3, change this to match
                    {
                        menuUsed = TRUE;
                        state standard; // go to the 'usual' movement state
                    }
                }
            }  
        
        //Module 7Af: Actions to Perform When the Timer Event is Triggered
        timer()
        {
            if (menuUsed == TRUE)
            {
            }
            else
            {
                llListenRemove(gListener);
                llResetScript();
            }
            llSetTimerEvent(0.0);
        }
        
    }
    
    //Module 7B: When In The Keeper State, Use Keeper's Third Person Control Scheme
    state Keeper
    {
        //Module 7Ba: Actions To Take When The Weapon Is Attached/Detached
        attach (key on)
        {
            if(on)
            {
            }
            else
            {
                ReleaseReset();
            }
        }
        
        //Module 7Bb: Preliminary Actions On Entering State
        state_entry()
        {   
            llListenRemove(listen_handle);
            listen_handle = llListen(5, "", llGetOwner(), "");
            SAFETYOFF();
            KeeperS = TRUE;
        }
        
        //Module 7Bc: What To Do When The Weapon Is Drawn & Sheathed
        listen(integer channel, string name, key id, string message)
            {   
            if(channel == 5)
            {
                g_message = llToLower(message);
    
                if( g_message == "hdraw" )
                {
                    SAFETYOFF();
                }
                if( g_message == "sdraw" )
                {
                    SAFETYOFF();
                }
                else if(g_message == "hsheathe") 
                {
                    SAFETYON();
                }
                else if(g_message == "ssheathe") 
                {
                    SAFETYON();
                }
            }
        }
        
        //Module 7Bd: The Control Scheme, Keeper's Third Person
        control(key owner, integer held, integer change)
        {
    
                if (held & (CONTROL_ML_LBUTTON | CONTROL_FWD))
                {
                    if (change & held & CONTROL_UP)
                    {
                        llApplyImpulse(<0,0,3.5>,FALSE);
                        llStartAnimation(pgupanim);
                        strike_type = SPECIALATK;
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_FWD)
                    {
        
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;   
                        FStrike();                          
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_ROT_LEFT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime; 
                        SLeft();
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_LEFT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;
                        RLeft();                            
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_ROT_RIGHT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime; 
                        SRight();                            
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_RIGHT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;  
                        RRight();                            
                        state WeaponStrike;
                    }
                     if (change & held & CONTROL_BACK)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;   
                        BStrike();                            
                        state WeaponStrike;
                    }
                }
                if (~held & change & (CONTROL_ML_LBUTTON | CONTROL_FWD))
                {
                    llStopAnimation(pgdwnanim);
                }
                if (held & change & CONTROL_DOWN)
                    {   
                        llStartAnimation(pgdwnanim);
                        llTriggerSound(swdswing, 1.0);
                        llSetTimerEvent(0.01);
                        strike_type = BLOCK;
                        llMoveToTarget(llGetPos(), 0.25);
                        llSleep(1.0);
                        llStopMoveToTarget();
                    }
                if (~held & change & CONTROL_DOWN)
                    {   
                        llStopAnimation(pgdwnanim);
                    }
    
        }
        
        //Module 7Be: What To Do When The Object Changes Owner
        changed(integer change)
        {
            if(change & CHANGED_OWNER) // reset the script when a new person owns the weapon
            {
                llResetScript();
            }
        }
    }
    
    //Modeul 7C: When In State Standard, Use Standard Control Scheme
    state standard
    {
        //Module 7Ca: Actions To Take When The Weapon Is Attached/Detached
        attach (key on)
        {
            if(on)
            {
            }
            else
            {
                ReleaseReset();
            }
        }
        
        //Module 7Cb: Preliminary Actions On Entering State
        state_entry()
        {   
            llListenRemove(listen_handle);
            listen_handle = llListen(5, "", llGetOwner(), "");
            SAFETYOFF();
            standardS = TRUE;
        }
        
        //Module 7Cc: What To Do When The Weapon Is Drawn & Sheathed
        listen(integer channel, string name, key id, string message)
            {   
            if(channel == 5)
            {
                g_message = llToLower(message);
    
                if( g_message == "hdraw" )
                {
                    SAFETYOFF();
                }
                if( g_message == "sdraw" )
                {
                    SAFETYOFF();
                }
                else if(g_message == "hsheathe") 
                {
                    SAFETYON();
                }
                else if(g_message == "ssheathe") 
                {
                    SAFETYON();
                }
            }
        }
        
        //Module 7Cd: The Control Scheme, Standard Controls
        control(key owner, integer held, integer change)
        {
    
                if (held & (CONTROL_ML_LBUTTON | CONTROL_LBUTTON))
                {
                    if (change & held & CONTROL_UP)
                    {
                        llApplyImpulse(<0,0,3.5>,FALSE);
                        llStartAnimation(pgupanim);
                        strike_type = SPECIALATK;
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_FWD)
                    {
        
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;   
                        FStrike();
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_ROT_LEFT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;   
                        SLeft();
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_LEFT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;   
                        RLeft();
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_ROT_RIGHT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;   
                        SRight();
                        state WeaponStrike;
                    }
                    if (change & held & CONTROL_RIGHT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;   
                        RRight();
                        state WeaponStrike;
                    }
                     if (change & held & CONTROL_BACK)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);
                        storedTime = recentTime;   
                        BStrike();                            
                        state WeaponStrike;
                    }
                }
                if (~held & change & (CONTROL_ML_LBUTTON | CONTROL_LBUTTON))
                {
                    llStopAnimation(pgdwnanim);
                }
                if (held & change & CONTROL_DOWN)
                    {   
                        llStartAnimation(pgdwnanim);
                        llTriggerSound(swdswing, 1.0);
                        llSetTimerEvent(0.01);
                        strike_type = BLOCK;
                        llMoveToTarget(llGetPos(), 0.25);
                        llSleep(1.0);
                        llStopMoveToTarget();
                    }
                if (~held & change & CONTROL_DOWN)
                    {   
                        llStopAnimation(pgdwnanim);
                    }
    
        }
        changed(integer change)
        {
            if(change & CHANGED_OWNER) // reset the script when a new person owns the weapon 
            {
                llResetScript();
            }
        }
    }
    
    //Module 7D: What To Do When When The Weapon Controls Are Used
    state WeaponStrike
    {
        //Module 7Da: Setting The Timers
        state_entry()
        {
            if (strike_type == KICK | strike_type == SPECIALATK)
            {
                llSetTimerEvent(0.25);
            }
            else
            {
                llSetTimerEvent(0.75);
            }
            //llOwnerSay("Test");
        }
        
        //Module 7Db: What Happens When The Timers Go Off
        timer()
        {
            if (strike_type == SWORDFWD)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            if (strike_type == SWORDRGT)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO);
            }
            if (strike_type == SWORDLFT)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO);
            }
            if (strike_type == BLOCK)
            {
                llSensor("", "", ACTIVE | AGENT, 2.0, PI_BY_TWO);
            }
            if (strike_type == KICK)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            if (strike_type == SPECIALATK)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            llSetTimerEvent(0.0);
        }
        
        //Module 7Dc: Actions to Perform if There's a Valid Target within the Predefined Sensor Range
        sensor(integer tnum)
        {
            vector dir = llDetectedPos(0) - llGetPos();
            dir.z = 0.0;
            dir = llVecNorm(dir);
            rotation rot = llGetRot();
            
            if (strike_type == SWORDFWD)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir += llRot2Up(rot);
                dir *= 200.0;
            }
            else if (strike_type == SWORDRGT)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir += dir;
                dir *= 100.0;
            }
            else if (strike_type == SWORDLFT)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir -= llRot2Left(rot);
                dir *= 100.0;
            }
            else if (strike_type == KICK)
            {
                llTriggerSound(kickconnect, 1.0);
                dir += dir;
                dir *= 100.0;
            }
            else if (strike_type == BLOCK)
            {
                llTriggerSound(blockconnect, 1.0);
            }
            else if (strike_type == SPECIALATK)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
            }
            strike_type= 0;
            if (standardS == TRUE)
            {
                state standard;
            }
            else if (KeeperS == TRUE)
            {
                state Keeper;
            }
        }
        
        //Module 7Dd: Actions To Take When There Is No Target Within Range
        no_sensor()
        {
            if (standardS == TRUE)
            {
                state standard;
            }
            else if (KeeperS == TRUE)
            {
                state Keeper;
            }
        }
    }

     

  2. Okay. So I discovered some flaws in my draw/sheathe scripts. The alphas weren't being applied correctly. Fixed the problem I was having, so here are the scripts.

     

    The Draw/Sheathe Script For the Sheath:

     

    //PREAMBLE: Module Names
    //Module 1: Defining Global String Variables - String Parameters
    //Module 2: Defining Global Integer Variable - Integer Parameters
    //Module 3: The Draw/Sheathe Script
                //Module 3A: Reset the Script Whenever the Object is Rezzed
                //Module 3B: Listen for Commands From the Avatar
                //Module 3C: Actions to Take When the Avatar Delivers the Draw and Sheathe Commands Via Chat
                //Module 3D: Trigger the Sword Draw Sound Effect and Render the Sword Visible or Invisible, As Appropriate
    
    
    //Module 1: Defining Global String Variables - String Parameters
    string g_message;
    
    //Module 2: Defining Global Integer Variable - Integer Parameters
    integer listen_handle;
    
    //Module 3: The Draw/Sheathe Script
    default
    {
        //Module 3A: Reset the Script Whenever the Object is Rezzed
        on_rez(integer start_param)
        {
            llResetScript();
        }
        
        //Module 3B: Listen for Commands From the Avatar
        state_entry()
        {
            llListenRemove(listen_handle);
            listen_handle = llListen(5, "", llGetOwner(), "");
        }
        
        //Module 3C: Actions to Take When the Avatar Delivers the Draw and Sheathe Commands Via Chat  
        listen(integer channel, string name, key id, string message)
            {
                
                g_message = llToLower(message);
    
                if(g_message == "hdraw")
                {
                    llSetTimerEvent(0.25);
                }
                if(g_message == "sdraw")
                {
                    llSetTimerEvent(0.25);
                }
                else if(g_message == "hsheathe") 
                {
                    llSetTimerEvent(0.75);
                }
                else if(g_message == "ssheathe") 
                {
                    llSetTimerEvent(0.75);
                }
            }
        
        //Module 3D: Render the Sword Hilt Visible or Invisible, As Appropriate
        timer()
        {   
        
            if( g_message == "hdraw" )
            {
                llSetAlpha(0.0, ALL_SIDES);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, ALL_SIDES, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 0, 1, 1, 0]);
                
            }
            if( g_message == "sdraw" )
            {
                llSetAlpha(0.0, ALL_SIDES);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, ALL_SIDES, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 0, 1, 1, 0]);
                
            }
            else if( g_message == "hsheathe" )
            {
                llSetAlpha(1.0, 1);
                llSetAlpha(1.0, 2);
                llSetAlpha(1.0, 3);
                llSetAlpha(1.0, 4);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 1, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 2, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 3, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 4, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
            }
            else if( g_message == "ssheathe" )
            {
                llSetAlpha(1.0, 1);
                llSetAlpha(1.0, 2);
                llSetAlpha(1.0, 3);
                llSetAlpha(1.0, 4);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 1, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 2, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 3, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 4, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
            }
            
            llSetTimerEvent(0);
        }
        
    }

     

     

    And here's the Draw/Sheathe Script for the Melee Weapon:

     

    //PREAMBLE: Module Names
    //Module 1: Defining Global String Variables - String Parameters
    //Module 2: Defining Global Integer Variable - Integer Parameters
    //Module 3: The Draw/Sheathe Script
                //Module 3A: Reset the Script Whenever the Object is Rezzed
                //Module 3B: Listen for Commands From the Avatar
                //Module 3C: Actions to Take When the Avatar Delivers the Draw and Sheathe Commands Via Chat
                //Module 3D: Trigger the Sword Draw Sound Effect and Render the Sword Visible or Invisible, As Appropriate
    
    
    //Module 1: Defining Global String Variables - String Parameters
    string g_message;
    
    //Module 2: Defining Global Integer Variable - Integer Parameters
    integer listen_handle;
    
    //Module 3: The Draw/Sheathe Script
    default
    {
        //Module 3A: Reset the Script Whenever the Object is Rezzed
        on_rez(integer start_param)
        {
            llResetScript();
        }
        
        //Module 3B: Listen for Commands From the Avatar
        state_entry()
        {
            llListenRemove(listen_handle);
            listen_handle = llListen(5, "", llGetOwner(), "");
        }
        
        //Module 3C: Actions to Take When the Avatar Delivers the Draw and Sheathe Commands Via Chat  
        listen(integer channel, string name, key id, string message)
            {
                
                g_message = llToLower(message);
    
                if(g_message == "hdraw")
                {
                    llSetTimerEvent(0.25);
                }
                if(g_message == "sdraw")
                {
                    llSetTimerEvent(0.25);
                }
                else if(g_message == "hsheathe") 
                {
                    llSetTimerEvent(0.75);
                }
                else if(g_message == "ssheathe") 
                {
                    llSetTimerEvent(0.75);
                }
            }
        
        //Module 3D: Render the Sword Hilt Visible or Invisible, As Appropriate
        timer()
        {   
        
            if( g_message == "hdraw" )
            {
                llSetAlpha(0.0, ALL_SIDES);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, ALL_SIDES, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 0, 1, 1, 0]);
                
            }
            if( g_message == "sdraw" )
            {
                llSetAlpha(0.0, ALL_SIDES);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, ALL_SIDES, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 0, 1, 1, 0]);
                
            }
            else if( g_message == "hsheathe" )
            {
                llSetAlpha(1.0, 1);
                llSetAlpha(1.0, 2);
                llSetAlpha(1.0, 3);
                llSetAlpha(1.0, 4);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 1, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 2, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 3, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 4, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
            }
            else if( g_message == "ssheathe" )
            {
                llSetAlpha(1.0, 1);
                llSetAlpha(1.0, 2);
                llSetAlpha(1.0, 3);
                llSetAlpha(1.0, 4);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 1, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 2, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 3, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
                llSetPrimitiveParams([PRIM_GLTF_BASE_COLOR, 4, "", <1,1,1>, ZERO_VECTOR, 0, <1,1,1>, 1, 0, 1, 0]);
            }
            
            llSetTimerEvent(0);
        }
        
    }

    Haven't fiddled with the main melee weapon script in a while.

  3. 2 hours ago, PheebyKatz said:

    Okay, the nametag thingy is super neato. I get it now. I've never seen combat stuff made with that in mind, like, at all. That I know of.

    When you get this working in anything like a satisfactory fashion, please let us know how you made it go. Even if it's just adding a different key to press in the control event or something, to trigger the attack/strike.

    This sort of thing is waaay up my alley, and I would love to see it work.

    Make it so that it's optional, and can be switched from "normal" mode to mouse steering mode, and I bet you five bucks it catches on somewhere out there. It's a neato idea, and a worthy project, IMO.

    Ah! Okay! I'll work on it being an optional mode!

     

    Right now, things operate so that holding down the forward key in combination with the other directional keys will activate the strikes. I actually like it and find it super comfortable. I decided against using the crouch or jump keys because I wanted to have those available. The crouch key is usually used for blocking, and I want to give my players the ability to jump when they need to. So that left the forward key, and things worked out pretty well. I'm comfortable with it. Now, I'm just trying to see if others are comfortable with it.

  4. You know, I just realized I'm making a big assumption here. I've talked to at least 4 friends recently and found out that, after all these years, they didn't know that Avatar Mouse Steering was a thing. So for people who may not know what in the world I'm referring to, Avatar Mouse Steering is the following:

     

     

     

    A quick thing I'd like to share: Avatar Mouse Steering works if you left click and hold on your avatar name tag. So if you have things on you that you might end up clicking if you clicked directly on your avatar, click your name tag instead. If you find you need your name tag to be higher, you can set your name tag higher above you by going (on Firestorm, at least) to Preferences-->Colors-->Name Tags-->Name Tag Z-Offset.

    • Thanks 1
  5. 2 hours ago, ItHadToComeToThis said:

    I make all my melee work via left click in general that Includes both standard and mouse look clicking. A good method I found was to use gestures. Use left click for your base rotation of moves and use gestures to activate more complex attacks on your next click.

    If you really want to do multi key combos. I posted something a while back that was a VERY rough draft of exactly that. I managed to achieve quite a significant number of combinations and there were still more that could be done. If you go back through this forum you will find it. It’s very rough though and not even remotely polished. More of code dump brain storming session.

    If you wanted avoid sensors and raycast. You could use llGetRegionList. Then loop through and detect how many avatars are around you, and how many of those are in front of you within X angle.

    It works just as well as a sensor and just as quickly.

    Hm. How'd you solve the problem of needing Mouse Steering at the same time of needing to Left Click? Because the way it's described, you have to stop Mouse Steering in order to make the attack, and the opponent could have already moved away by the time you attack, and you can't react fast enough to go back to Mouse Steering.

  6. On 3/4/2024 at 9:54 PM, PheebyKatz said:

    Using a short-range sensor is probably fine, as long as it can communicate somehow with any combat meter you might want to employ. I just have my stuff message them on a negative-numbered channel (to avoid snooping/cheating), and tell the meter they've been hit. Of course, I made the meter to go with it, so it'd always work.

    As for invisible bullets, think like a slat of board being thrown at them, that dies on contact, or by the time it's gone out of melee range, whichever comes sooner. Not naming any names, but a lot of fantasy combat sword makers use this approach.

    I'd love to see it just come down to having the weapon touch the opponent and registering hits, but attachments are all phantom, just to keep people from getting their eyes poked out at marshmallow roasts and stuff. ^-^;

    And despite my edging on snarky with my first reply, because I was like, why is it this old thing again, I agree that making it do what you want is a worthy goal. Even if you end up not liking it as much as the way it worked before, you tried and made it go. And besides, it could actually turn out to be a big improvement.

    So yeah, keep us updated and stuff!

     Well, I hadn't intended to build a whole combat system. Like I said, I was just trying to see if the controls feel okay enough in Third Person Mode for others to adopt the control scheme in their systems. I like the idea of SL combat, but it's all done in First Person, and I can't really do First Person. While the combat system supposedly works in Third Person, the problem is that the strikes are activated by holding down the left mouse button along with the directional keys. This takes away the ability to use Mouse Steering (where you left click on your avatar and drag the mouse left and right to rotate it), which is essential for smooth navigation in Third Person. So my hope is to come up with a control scheme that works in Third Person and lets you use Mouse Steering while still activating the strikes. I'm hoping people like this enough to want to see it in popular combat systems.

  7. Thank you, very much, for your feedback. Yeah. I've been playing around with the old freebie swordfighting script for years. It's the basis of the script. I've had this script since I started SL in 2008. lol

     

    Where are the misspellings in the draw/sheathe script? I'll get those sorted.

     

    Yeah. Like I said, for the most part, I've been trying to figure out a third person control scheme that works well while in Third Person Mode. Having to left click and use the movement keys (I use WASD for movement) takes away the ability to use Mouse Steering, which makes moving the avie awkward. I wanted a control scheme that lets you use Mouse Steering while activating the sword strikes in a way that feels comfortable for most players. I'm eager to see what people think of the control scheme.

     

    I'm not sure how I feel about the bullet system for melee weapons. I've played with a few that used it. Not quite sure how I felt about it. But I'll definitely consider it. As for pushing, yeah. That's just something that never got changed, as I was focused on the controls, rather than the means of dealing actual damage. I'll be honest, I've been more focused on the controls than in the combat system as a whole. lol! I know I'm not good enough to put together a *real* combat system. I just want to see if I can set up a control scheme that people like and are willing to incorporate into their own combat systems. If I could participate in combat using others' systems, that'd be great. As it stands, it's all Mouselook, which, due to reasons, means I can't participate in the combat. Hence why I've been scratching my head trying to think of a system that will work well in Third Person.

     

    I really, really hope that people like the control scheme, or better yet, help me improve on it so it's comfortable for most people to use in Third Person!

  8. Heyla!

     

    I've tweaked the script again. Tweak 2 works in conjunction with the draw/sheathe scripts I've made to go with the main melee weapon script. In it, if the user draws their weapon, their weapon becomes active and ready for use. If the user sheathes their weapon, the weapon becomes inactive, releasing controls so the user doesn't accidentally use their weapon when they expect it to be inactive. (I wish I could say that I was brilliant and came up with the code, myself. Instead, it was code I learned while studying the Myriad Lite script-set, a free and open-source combat system. Credit where credit is due.)

     

    I'm also including in this post the draw/sheathe scripts for examination and feedback. I am especially hoping for feedback on how to better go about making the sword and hilt visible and invisible when they use PBR materials. Right now, as it stands, it's not very flexible. To become invisible, it removes the PBR material, and to become visible, it adds the specific material back to the weapon. I'm hoping there's an alpha function for PBR materials that I just haven't seen yet.

     

    Thanks for reading, and I look forward to your feedback and advice!

    Keeper S. Karu (KeeperS Karu)

     

    The Melee Weapon Script, Tweak #2:

    //PREAMBLE: Module Names
    //Module 1: Defining Global String Variables - Animation Names
    //Module 2: Defining Global String Variables - Sound Effect Names
    //Module 3: Defining Global String Variables - Bloodsplatter Object Name
    //Module 4: Defining Global Variables - MISC
         //Module 4A: Attack Types
         //Module 4B: Weapon Safety Variables
    //Module 5: The Safety Functions
        //Module 5A: Safety On
        //Module 5B: Safety Off
    //Module 6: The Double Tap Code
        //Module 6A: Defining the Double-Tap Global Vairables
        //Module 6B: Obtaining the Time the Key Was Pressed
        //Module 6C: Comparing the Time Between Key Presses
        //Module 6D: Resetting the storedTime Variable
        //Module 6E: Double Tap
    //Module 7: The Sword Script
        //Module 7A: The Default State of the Sword Object When the Script Is First Executed
            //Module 7a: The Sword's Status When the Script is Reset - It Cannot Be Grabbed and Physically Dragged
            //Module 7b: Actions to Take When the Sword is Attached and Detached From the Avatar
            //Module 7c: If Permission Has Been Given, Take Over Keyboard Functions
            //Module 7d: Is The Safety On?
            //Module 7e: Defining the Keyboard Controls
            //Module 7f: Actions to Perform When the Timer Event is Triggered
            //Module 7g: Actions to Perform if There's a Valid Target within the Predefined Sensor Range
    
    //Module 1: Defining Global String Variables - Animation Names
    string fwdanim = "overhead_strike_exaggerated";
    string bckanim = "high_kick";
    string rotrightanim = "diagonal_left_strike_exag";
    string rotleftanim = "diagonal_right_strike_exag";
    string straferightanim = "upward_left_strike_exag";
    string strafeleftanim = "upward_right_strike_exag";
    string pgdwnanim = "basic_angle_block";
    string pgupanim = "backflip";
    
    //Module 2: Defining Global String Variables - Sound Effects Names
    string swdswing = "swordswing01";
    string swdconnectflsh = "sword_flesh_01";
    //string block swing; - If different from the other sound effects, enter them, here, as well as in the appropriate area of the code, below
    string blockconnect = "sword05";
    //string kick swing; - If different from the other sound effects, enter them, here, as well as in the appropriate area of the code, below
    string kickconnect = "Punch04";
    
    //Module 3: Defining Global String Variables - Bloodsplatter Object Name
    string bloodsplatter = "!bloodsplatter";
    
    //Module 4: Defining Global Variables - MISC
    
        //Module 4A: Attack Types
        integer SWORDFWD = 1;
        integer SWORDRGT = 2;
        integer SWORDLFT = 3;
        integer BLOCK = 4;
        integer KICK = 5;
        integer SPECIALATK = 6;
        integer strike_type;
        
        //4Module 4B: Weapon Safety Variables
        
        string g_message;
        integer listen_handle;
        integer SAFETY_ON = TRUE;
        
    //Module 5: The Safety Functions
    
        //Module 5A: Safety On
        SAFETYON()
        {
            SAFETY_ON = TRUE; // switch the safety on
            llSay(0, "releasing controls");
            llReleaseControls();
        }
    
        //Module 5B: Safety Off
        SAFETYOFF()
        {
            SAFETY_ON = FALSE; // switch the safety off
            llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS|PERMISSION_TRIGGER_ANIMATION); // request permissions
        }
    
    //Module 6: The Double Tap Code
    
        //Module 6A: Defining the Double-Tap Global Vairables
        float strTime;
        float time;
        float storedTime;               
        float recentTime; 
        string anim = "hover";
        float interval = 1.0;
    
        //Module 6B: Obtaining the Time the Key Was Pressed
        getSeconds()
        {
            string timestamp    = llGetTimestamp();
            string subTime      = llGetSubString(timestamp, 19, 25);
            float wallclock     = llGetWallclock();
            strTime = (float)subTime + wallclock;
        }
        
        //Module 6C: Comparing the Time Between Key Presses              
        compareTimes(float stored, float recent)
        {
            time = recent - stored;
        }
        
        //Module 6D: Resetting the storedTime Variable
        resetStored()
        {
        storedTime = 0;
        }
        
        //Module 6E: Double Tap
        
        FStrike()
        {
            if ( time <= interval | time > interval )
            {
                llStartAnimation(fwdanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDFWD;
            }
        }
        
        BStrike()
        {
            if ( time <= interval )
            {
                llStartAnimation(bckanim);
                llSetTimerEvent(0.25);
                strike_type = KICK;
            }
            else
            {
                llStartAnimation(fwdanim);
                llSetTimerEvent(0.25);
                strike_type = KICK;
            }
        }
        
        RLeft()
        {
            if ( time <= interval )
            {
                llStartAnimation(rotleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
            else
            {
                llStartAnimation(strafeleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
        }
        SLeft()
        {
            if ( time <= interval )
            {
                llStartAnimation(strafeleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
            else
            {
                llStartAnimation(rotleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
        }
        RRight()
        {
            if( time <= interval)
            {
                llStartAnimation(rotrightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
            else
            {
                llStartAnimation(straferightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
        }
        SRight()
        {
            if ( time <= interval )
            {
                llStartAnimation(straferightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
            else
            {
                llStartAnimation(rotrightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
        }
    
    //Module 7: The Sword Script
    
    //Module 7A: The Default State of the Sword Object When the Script Is First Executed
    default
    {
        //Module 7a: The Sword's Status When the Script is Reset - It Cannot Be Grabbed and Physically Dragged
        state_entry()
        {
            llSetStatus(STATUS_BLOCK_GRAB, TRUE);
            llListenRemove(listen_handle);
            listen_handle = llListen(5, "", llGetOwner(), "");
        }
        
        //Module 7b: Actions to Take When the Sword is Attached and Detached From the Avatar        
        attach(key on)
        {
            if (on != NULL_KEY)
            {
                integer perm = llGetPermissions();
                
                if (perm != (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION))
                {
                    llRequestPermissions(on, PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
                }
                else
                {
                    llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT, TRUE, TRUE);
                }
                
            }
            else
            {
                llSay(0, "releasing controls");
                llReleaseControls();
            }
        }
        
        //Module 7c: If Permission Has Just Been Given, Take Over Keyboard Functions
        run_time_permissions(integer perm)
        {
            if (perm)
            {
                llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT | CONTROL_DOWN, TRUE, TRUE);
            }
        }
        
        //Module 7d: Is The Safety On?
        
        listen(integer channel, string name, key id, string message)
            {   
                g_message = llToLower(message);
    
                if( g_message == "hdraw" )
                {
                    SAFETYOFF();
                }
                if( g_message == "sdraw" )
                {
                    SAFETYOFF();
                }
                else if(g_message == "hsheathe") 
                {
                    SAFETYON();
                }
                else if(g_message == "ssheathe") 
                {
                    SAFETYON();
                }
            }
        
        //Module 7e: Defining the Keyboard Controls   
        control(key owner, integer held, integer change)
        {
    
                if (held & (CONTROL_ML_LBUTTON | CONTROL_FWD))
                {
                    if (change & held & CONTROL_UP)
                    {
                        llApplyImpulse(<0,0,3.5>,FALSE);
                        llStartAnimation(pgupanim);
                        llSetTimerEvent(0.25);
                        strike_type = SPECIALATK;
                    }
                    if (change & held & CONTROL_FWD)
                    {
        
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);   
                        FStrike();                            
                        storedTime = recentTime;
                    }
                    if (change & held & CONTROL_ROT_LEFT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);   
                        SLeft();                            
                        storedTime = recentTime;
                    }
                    if (change & held & CONTROL_LEFT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);   
                        RLeft();                            
                        storedTime = recentTime;
                    }
                    if (change & held & CONTROL_ROT_RIGHT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);   
                        SRight();                            
                        storedTime = recentTime;
                    }
                    if (change & held & CONTROL_RIGHT)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);   
                        RRight();                            
                        storedTime = recentTime;
                    }
                     if (change & held & CONTROL_BACK)
                    {
                        getSeconds();
                        recentTime = strTime;                                                    
                        compareTimes(storedTime, recentTime);   
                        BStrike();                            
                        storedTime = recentTime;
                    }
                }
                if (~held & change & (CONTROL_ML_LBUTTON | CONTROL_FWD))
                {
                    llStopAnimation(pgdwnanim);
                }
                if (held & change & CONTROL_DOWN)
                    {   
                        llStartAnimation(pgdwnanim);
                        llTriggerSound(swdswing, 1.0);
                        llSetTimerEvent(0.01);
                        strike_type = BLOCK;
                        llMoveToTarget(llGetPos(), 0.25);
                        llSleep(1.0);
                        llStopMoveToTarget();
                    }
                if (~held & change & CONTROL_DOWN)
                    {   
                        llStopAnimation(pgdwnanim);
                    }
    
        }
        
        //Module 7f: Actions to Perform When the Timer Event is Triggered
        timer()
        {
            if (strike_type == SWORDFWD)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            if (strike_type == SWORDRGT)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO);
            }
            if (strike_type == SWORDLFT)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO);
            }
            if (strike_type == BLOCK)
            {
                llSensor("", "", ACTIVE | AGENT, 2.0, PI_BY_TWO);
            }
            if (strike_type == KICK)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            if (strike_type == SPECIALATK)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            llSetTimerEvent(0.0);
        }
        
        //Module 7g: Actions to Perform if There's a Valid Target within the Predefined Sensor Range
        sensor(integer tnum)
        {
            vector dir = llDetectedPos(0) - llGetPos();
            dir.z = 0.0;
            dir = llVecNorm(dir);
            rotation rot = llGetRot();
            
            if (strike_type == SWORDFWD)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir += llRot2Up(rot);
                dir *= 200.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == SWORDRGT)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir += dir;
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == SWORDLFT)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir -= llRot2Left(rot);
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == KICK)
            {
                llTriggerSound(kickconnect, 1.0);
                dir += dir;
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == BLOCK)
            {
                llTriggerSound(blockconnect, 1.0);
            }
            else if (strike_type == SPECIALATK)
            {
                llTriggerSound(swdswing, 1.0);
                llPushObject(llDetectedKey(0), <0,0,150>, ZERO_VECTOR, FALSE);
            }
            strike_type= 0;
        }
    }

     

    The Draw/Sheathe Script for the weapon:

    //PREAMBLE: Module Names
    //Module 1: Defining Global String Varaibles - Animation Names
    //Module 2: Defining Global String Variables - Sound Effects Names
    //Module 3: Defining Global String Variables - String Parameters
    //Module 4: Defining Global Integer Variable - Integer Parameters
    //Module 5: The Draw/Sheathe Script
                //Module 5A: Reset the Script Whenever the Object is Rezzed
                //Module 5B: Obtain Permission to Animate the Avatar & Listen for Commands From the Avatar
                //Module 5C: If Permission Has Been Given, Then Letthe Following Conditions Be True
                //Module 5D: Actions to Take When the Avatar Delivers the Draw and Sheathe Commands Via Chat
                //Module 5E: Trigger the Sword Draw Sound Effect and Render the Sword Visible or Invisible, As Appropriate
    
    
    //Module 1: Defining Global String Varaibles - Animation Names
    string hdraw = "hip_draw";
    string hsheathe = "hip_sheathe";
    string sdraw = "Draw - .7 Seconds";
    string ssheathe = "Sheathe - 0.77 Sec";
    string stance = "basic_stance";
    
    //Module 2: Defining Global String Variables - Sound Effects Names
    string sworddraw = "swordraw";
    
    //Module 3: Defining Global String Variables - String Parameters
    string g_message;
    
    //Module 4: Defining Global Integer Variable - Integer Parameters
    integer listen_handle;
    integer permissions;
    
    //Module 5: The Draw/Sheathe Script
    default
    {
        //Module 5A: Reset the Script Whenever the Object is Rezzed
        on_rez(integer start_param)
        {
            llResetScript();
        }
        
        //Module 5B: Obtain Permission to Animate the Avatar & Listen for Commands From the Avatar
        state_entry()
        {
            if( llGetAttached() );
            {
                llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
            }        
            llListenRemove(listen_handle);
            listen_handle = llListen(5, "", llGetOwner(), "");
        }
        
        //Module 5C: If Permission Has Been Given, Then Let The Following Conditions Be True
        run_time_permissions(integer perms)
            {
                if( perms & PERMISSION_TRIGGER_ANIMATION )
                {
                    permissions = TRUE;
                }
            }
        
        //Module 5D: Actions to Take When the Avatar Delivers the Draw and Sheathe Commands Via Chat
        listen(integer channel, string name, key id, string message)
            {   
                g_message = llToLower(message);
    
                if( g_message == "hdraw" )
                {
                    if(permissions)
                    {
                        llStartAnimation(hdraw);
                        llStartAnimation(stance);
                        llSetTimerEvent(0.25);
                    }
                }
                if( g_message == "sdraw" )
                {
                    if(permissions)
                    {
                        llStartAnimation(sdraw);
                        llStartAnimation(stance);
                        llSetTimerEvent(0.25);
                    }
                }
                else if(g_message == "hsheathe") 
                {
                    if(permissions)
                    {
                        llStartAnimation(hsheathe);
                        llStopAnimation(stance);
                        llSetTimerEvent(0.75);
                    }
                }
                else if(g_message == "ssheathe") 
                {
                    if(permissions)
                    {
                        llStartAnimation(ssheathe);
                        llStopAnimation(stance);
                        llSetTimerEvent(0.75);
                    }
                }
            }
            
        //Module 5E: Trigger the Sword Draw Sound Effect and Render the Sword Visible or Invisible, As Appropriate
        timer()
        {   
            if( g_message == "hdraw")
            {
                if( permissions )
                {
                    llTriggerSound(sworddraw, 1.0);
                    llSetLinkAlpha(LINK_SET,1.0, ALL_SIDES);
                    llSetPrimitiveParams([PRIM_RENDER_MATERIAL, ALL_SIDES, "Texture UUID Here"]);
                }
            }
            if( g_message == "sdraw")
            {
                if( permissions )
                {
                    llTriggerSound(sworddraw, 1.0);
                    llSetLinkAlpha(LINK_SET,1.0, ALL_SIDES);
                    llSetPrimitiveParams([PRIM_RENDER_MATERIAL, ALL_SIDES, "Texture UUID Here"]);
                }
            }
            else if( g_message == "hsheathe")
            {
                if( permissions )
                    {
                        llTriggerSound(sworddraw, 1.0);
                        llSetLinkAlpha(LINK_SET,0, ALL_SIDES);
                        llSetPrimitiveParams([PRIM_RENDER_MATERIAL, ALL_SIDES, NULL_KEY]);
                    }
            }
            else if( g_message == "ssheathe")
            {
                if( permissions )
                    {
                        llTriggerSound(sworddraw, 1.0);
                        llSetLinkAlpha(LINK_SET,0, ALL_SIDES);
                        llSetPrimitiveParams([PRIM_RENDER_MATERIAL, ALL_SIDES, NULL_KEY]);
                    }
            }
            
            llSetTimerEvent(0);
        }
        
    }
    

     

    The Draw/Sheathe Script for the Sheath:

    //PREAMBLE: Module Names
    //Module 1: Defining Global String Variables - String Parameters
    //Module 2: Defining Global Integer Variable - Integer Parameters
    //Module 3: The Draw/Sheathe Script
                //Module 3A: Reset the Script Whenever the Object is Rezzed
                //Module 3B: Listen for Commands From the Avatar
                //Module 3C: Actions to Take When the Avatar Delivers the Draw and Sheathe Commands Via Chat
                //Module 3D: Trigger the Sword Draw Sound Effect and Render the Sword Visible or Invisible, As Appropriate
    
    
    //Module 1: Defining Global String Variables - String Parameters
    string g_message;
    
    //Module 2: Defining Global Integer Variable - Integer Parameters
    integer listen_handle;
    
    //Module 3: The Draw/Sheathe Script
    default
    {
        //Module 3A: Reset the Script Whenever the Object is Rezzed
        on_rez(integer start_param)
        {
            llResetScript();
        }
        
        //Module 3B: Listen for Commands From the Avatar
        state_entry()
        {
            llListenRemove(listen_handle);
            listen_handle = llListen(5, "", llGetOwner(), "");
        }
        
        //Module 3C: Actions to Take When the Avatar Delivers the Draw and Sheathe Commands Via Chat  
        listen(integer channel, string name, key id, string message)
            {
                
                g_message = llToLower(message);
    
                if(g_message == "hdraw")
                {
                    llSetTimerEvent(0.25);
                }
                if(g_message == "sdraw")
                {
                    llSetTimerEvent(0.25);
                }
                else if(g_message == "hsheathe") 
                {
                    llSetTimerEvent(0.75);
                }
                else if(g_message == "ssheathe") 
                {
                    llSetTimerEvent(0.75);
                }
            }
        
        //Module 3D: Render the Sword Hilt Visible or Invisible, As Appropriate
        timer()
        {   
        
            if( g_message == "hdraw" )
            {
                llSetAlpha(0.0, ALL_SIDES);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, ALL_SIDES, NULL_KEY]);
                
            }
            if( g_message == "sdraw" )
            {
                llSetAlpha(0.0, ALL_SIDES);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, ALL_SIDES, NULL_KEY]);
                
            }
            else if( g_message == "hsheathe" )
            {
                llSetAlpha(1.0, ALL_SIDES);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, 1, "Texture UUID Here"]);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, 2, "Texture UUID Here"]);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, 3, "Texture UUID Here"]);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, 4, "Texture UUID Here"]);
            }
            else if( g_message == "ssheathe" )
            {
                llSetAlpha(1.0, ALL_SIDES);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, 1, "Texture UUID Here"]);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, 2, "Texture UUID Here"]);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, 3, "Texture UUID Here"]);
                llSetPrimitiveParams([PRIM_RENDER_MATERIAL, 4, "Texture UUID Here"]);
            }
            
            llSetTimerEvent(0);
        }
        
    }
    

     

  9. Heyla and good evening!

     

    So I'm not the biggest fan of first person mode, otherwise known as mouselook mode on SL. Unfortunately, every melee weapon script I've found tends to only be truly effective in mouselook mode, as it requires you to hold the left mouse button down while also pressing the directional keys to swing the weapon. In third person mode, you need that button for mouse steering, or movement will be awkward. Because I haven't been able to find a script that made the use of melee weapons in third person mode viable, I decided to mess around with a freebie melee weapon script and see if I can find something that works. And I think I did. In third person mode, instead of holding down the left mouse button in combination with the directional keys to activate the weapon swings, the player will hold down the forward button in conjunction with the left, right, and back movement buttons to swing the weapon. The left mouse button, of course, is reserved for mouse steering. It wasn't my first choice of key combos. I wanted to hold down the right mouse button instead of the left mouse button to activate the swings in third person mode, but the right mouse button isn't available (unless that's changed since last I checked?). Anyhow, I thought I'd post the modified script on here and get some feedback on how the controls feel in third person, see if there are any tweaks and suggestions you all might have to make third person melee combat a viable option for those who hate being in mouselook mode.

     

    I do want to make note of the fact that I am very much a newbie in scripting. I know just enough to get by and am using what I learned in my QBASIC class over 20 years ago to organize things to the best of my ability. This is not going to be a brilliant script by any means. If you have suggestions to make this into something good enough to be passed around to others who could use it, I'm definitely all ears.

     

    Thanks for reading and your feedback,

    Keeper S. Karu (KeeperS Karu)

     

    P.S.

    Contact me in-world for a copy of the dummy melee weapon if you don't want to mess with putting something together. It's put together with my own animations and ready for playing around with.

     

    The Controls:

    Forward Double-Tapped --> Forward Strike

    Forward + Left --> Left Strike

    Forward + Left Double-Tapped --> Alternate Left Strike

    Forward + Right --> Right Strike

    Forward + Right Double-Tapped --> Alternate Right Strike

    Forward + Back --> My dummy weapon uses a kick animation for this one; could probably use another strike animation for this

    Forward + Back Double-Tapped --> Uh, I didn't realize I never took that into account; might be my first tweak to the script

     

    Tweak 1:

    Forward + Back --> Forward Strike

    Forward + Back Double-Tapped --> Kick

     

    The Script (Tweak 1):

    //PREAMBLE: Module Names
    //Module 1: Defining Global String Variables - Animation Names
    //Module 2: Defining Global String Variables - Sound Effect Names
    //Module 3: Defining Global String Variables - Bloodsplatter Object Name
    //Module 4: Defining Global Integer Variables - Attack Types
    //Module 5: The Double Tap Code
        //Module 5A: Defining the Double-Tap Global Vairables
        //Module 5B: Obtaining the Time the Key Was Pressed
        //Module 5C: Comparing the Time Between Key Presses
        //Module 5D: Resetting the storedTime Variable
        //Module 5E: Double Tap
    //Module 6: The Sword Script
        //Module 6A: The Default State of the Sword Object When the Script Is First Executed
            //Module 6a: The Sword's Status When the Script is Reset - It Cannot Be Grabbed and                           Physically Dragged
            //Module 6b: Actions to Take When the Sword is Attached and Detached From the Avatar
            //Module 6c: If Permission Has Been Given, Take Over Keyboard Functions
            //Module 6d: Defining the Keyboard Controls
            //Module 6e: Actions to Perform When the Timer Event is Triggered
            //Module 6f: Actions to Perform if There's a Valid Target within the Predefined Sensor                        Range
    
    //Module 1: Defining Global String Variables - Animation Names
    string fwdanim = "overhead_strike_exaggerated";
    string bckanim = "high_kick";
    string rotrightanim = "diagonal_left_strike_exag";
    string rotleftanim = "diagonal_right_strike_exag";
    string straferightanim = "upward_left_strike_exag";
    string strafeleftanim = "upward_right_strike_exag";
    string pgdwnanim = "basic_angle_block";
    string pgupanim = "backflip";
    
    //Module 2: Defining Global String Variables - Sound Effects Names
    string swdswing = "swordswing01";
    string swdconnectflsh = "sword_flesh_01";
    //string block swing; - If different from the other sound effects, enter them, here, as well as in the appropriate area of the code, below
    string blockconnect = "sword05";
    //string kick swing; - If different from the other sound effects, enter them, here, as well as in the appropriate area of the code, below
    string kickconnect = "Punch04";
    
    //Module 3: Defining Global String Variables - Bloodsplatter Object Name
    string bloodsplatter = "!bloodsplatter";
    
    //Module 4: Defining Global Integer Variables - Attack Types
    integer SWORDFWD = 1;
    integer SWORDRGT = 2;
    integer SWORDLFT = 3;
    integer BLOCK = 4;
    integer KICK = 5;
    integer SPECIALATK = 6;
    integer strike_type;
    
    //Module 5: The Double Tap Code
    
        //Module 5A: Defining the Double-Tap Global Vairables
        float strTime;
        float time;
        float storedTime;               
        float recentTime; 
        string anim = "hover";
        float interval = 1.0;
    
        //Module 5B: Obtaining the Time the Key Was Pressed
        getSeconds()
        {
            string timestamp    = llGetTimestamp();
            string subTime      = llGetSubString(timestamp, 19, 25);
            float wallclock     = llGetWallclock();
            strTime = (float)subTime + wallclock;
        }
        
        //Module 5C: Comparing the Time Between Key Presses              
        compareTimes(float stored, float recent)
        {
            time = recent - stored;
        }
        
        //Module 5D: Resetting the storedTime Variable
        resetStored()
        {
        storedTime = 0;
        }
        
        //Module 5E: Double Tap
        
        FStrike()
        {
            if ( time <= interval | time > interval )
            {
                llStartAnimation(fwdanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDFWD;
            }
        }
        
        BStrike()
        {
            if ( time <= interval )
            {
                llStartAnimation(bckanim);
                llSetTimerEvent(0.25);
                strike_type = KICK;
            }
            else
            {
                llStartAnimation(fwdanim);
                llSetTimerEvent(0.25);
                strike_type = KICK;
            }
        }
        
        RLeft()
        {
            if ( time <= interval )
            {
                llStartAnimation(rotleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
            else
            {
                llStartAnimation(strafeleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
        }
        SLeft()
        {
            if ( time <= interval )
            {
                llStartAnimation(strafeleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
            else
            {
                llStartAnimation(rotleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
        }
        RRight()
        {
            if( time <= interval)
            {
                llStartAnimation(rotrightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
            else
            {
                llStartAnimation(straferightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
        }
        SRight()
        {
            if ( time <= interval )
            {
                llStartAnimation(straferightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
            else
            {
                llStartAnimation(rotrightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
        }
    
    //Module 6: The Sword Script
    
    //Module 6A: The Default State of the Sword Object When the Script Is First Executed
    default
    {
        //Module 6a: The Sword's Status When the Script is Reset - It Cannot Be Grabbed and Physically Dragged
        state_entry()
        {
            llSetStatus(STATUS_BLOCK_GRAB, TRUE);
        }
        
        //Module 6b: Actions to Take When the Sword is Attached and Detached From the Avatar        
        attach(key on)
        {
            if (on != NULL_KEY)
            {
                integer perm = llGetPermissions();
                
                if (perm != (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION))
                {
                    llRequestPermissions(on, PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
                }
                else
                {
                    llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT, TRUE, TRUE);
                }
                
            }
            else
            {
                llSay(0, "releasing controls");
                llReleaseControls();
            }
        }
        
        //Module 6c: If Permission Has Just Been Given, Take Over Keyboard Functions
        run_time_permissions(integer perm)
        {
            if (perm)
            {
                llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT | CONTROL_DOWN, TRUE, TRUE);
            }
        }
        
        //Module 6d: Defining the Keyboard Controls   
        control(key owner, integer held, integer change)
        {
            if (held & (CONTROL_ML_LBUTTON | CONTROL_FWD))
            {
                if (change & held & CONTROL_UP)
                {
                    llApplyImpulse(<0,0,3.5>,FALSE);
                    llStartAnimation(pgupanim);
                    llSetTimerEvent(0.25);
                    strike_type = SPECIALATK;
                }
                if (change & held & CONTROL_FWD)
                {
    
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    FStrike();                            
                    storedTime = recentTime;
                }
                if (change & held & CONTROL_ROT_LEFT)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    SLeft();                            
                    storedTime = recentTime;
                }
                if (change & held & CONTROL_LEFT)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    RLeft();                            
                    storedTime = recentTime;
                }
                if (change & held & CONTROL_ROT_RIGHT)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    SRight();                            
                    storedTime = recentTime;
                }
                if (change & held & CONTROL_RIGHT)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    RRight();                            
                    storedTime = recentTime;
                }
                 if (change & held & CONTROL_BACK)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    BStrike();                            
                    storedTime = recentTime;
                }
            }
            if (~held & change & (CONTROL_ML_LBUTTON | CONTROL_FWD))
            {
                llStopAnimation(pgdwnanim);
            }
            if (held & change & CONTROL_DOWN)
                {   
                    llStartAnimation(pgdwnanim);
                    llTriggerSound(swdswing, 1.0);
                    llSetTimerEvent(0.01);
                    strike_type = BLOCK;
                    llMoveToTarget(llGetPos(), 0.25);
                    llSleep(1.0);
                    llStopMoveToTarget();
                }
            if (~held & change & CONTROL_DOWN)
                {   
                    llStopAnimation(pgdwnanim);
                }
        }
        
        //Module 6e: Actions to Perform When the Timer Event is Triggered
        timer()
        {
            if (strike_type == SWORDFWD)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            if (strike_type == SWORDRGT)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO);
            }
            if (strike_type == SWORDLFT)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO);
            }
            if (strike_type == BLOCK)
            {
                llSensor("", "", ACTIVE | AGENT, 2.0, PI_BY_TWO);
            }
            if (strike_type == KICK)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            if (strike_type == SPECIALATK)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            llSetTimerEvent(0.0);
        }
        
        //Module 6f: Actions to Perform if There's a Valid Target within the Predefined Sensor Range
        sensor(integer tnum)
        {
            vector dir = llDetectedPos(0) - llGetPos();
            dir.z = 0.0;
            dir = llVecNorm(dir);
            rotation rot = llGetRot();
            
            if (strike_type == SWORDFWD)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir += llRot2Up(rot);
                dir *= 200.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == SWORDRGT)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir += dir;
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == SWORDLFT)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir -= llRot2Left(rot);
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == KICK)
            {
                llTriggerSound(kickconnect, 1.0);
                dir += dir;
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == BLOCK)
            {
                llTriggerSound(blockconnect, 1.0);
            }
            else if (strike_type == SPECIALATK)
            {
                llTriggerSound(swdswing, 1.0);
                llPushObject(llDetectedKey(0), <0,0,150>, ZERO_VECTOR, FALSE);
            }
            strike_type= 0;
        }
    }

     

    The Script:

    //PREAMBLE: Module Names
    //Module 1: Defining Global String Variables - Animation Names
    //Module 2: Defining Global String Variables - Sound Effect Names
    //Module 3: Defining Global String Variables - Bloodsplatter Object Name
    //Module 4: Defining Global Integer Variables - Attack Types
    //Module 5: The Double Tap Code
        //Module 5A: Defining the Double-Tap Global Vairables
        //Module 5B: Obtaining the Time the Key Was Pressed
        //Module 5C: Comparing the Time Between Key Presses
        //Module 5D: Resetting the storedTime Variable
        //Module 5E: Double Tap
    //Module 6: The Sword Script
        //Module 6A: The Default State of the Sword Object When the Script Is First Executed
            //Module 6a: The Sword's Status When the Script is Reset - It Cannot Be Grabbed and Physically Dragged
            //Module 6b: Actions to Take When the Sword is Attached and Detached From the Avatar
            //Module 6c: If Permission Has Been Given, Take Over Keyboard Functions
            //Module 6d: Defining the Keyboard Controls
            //Module 6e: Actions to Perform When the Timer Event is Triggered
            //Module 6f: Actions to Perform if There's a Valid Target within the Predefined Sensor Range
    
    //Module 1: Defining Global String Variables - Animation Names
    string fwdanim = "overhead_strike_exaggerated";
    string bckanim = "high_kick";
    string rotrightanim = "diagonal_left_strike_exag";
    string rotleftanim = "diagonal_right_strike_exag";
    string straferightanim = "upward_left_strike_exag";
    string strafeleftanim = "upward_right_strike_exag";
    string pgdwnanim = "basic_angle_block";
    string pgupanim = "backflip";
    
    //Module 2: Defining Global String Variables - Sound Effects Names
    string swdswing = "swordswing01";
    string swdconnectflsh = "sword_flesh_01";
    //string block swing; - If different from the other sound effects, enter them, here, as well as in the appropriate area of the code, below
    string blockconnect = "sword05";
    //string kick swing; - If different from the other sound effects, enter them, here, as well as in the appropriate area of the code, below
    string kickconnect = "Punch04";
    
    //Module 3: Defining Global String Variables - Bloodsplatter Object Name
    string bloodsplatter = "!bloodsplatter";
    
    //Module 4: Defining Global Integer Variables - Attack Types
    integer SWORDFWD = 1;
    integer SWORDRGT = 2;
    integer SWORDLFT = 3;
    integer BLOCK = 4;
    integer KICK = 5;
    integer SPECIALATK = 6;
    integer strike_type;
    
    //Module 5: The Double Tap Code
    
        //Module 5A: Defining the Double-Tap Global Vairables
        float strTime;
        float time;
        float storedTime;               
        float recentTime; 
        string anim = "hover";
        float interval = 1.0;
    
        //Module 5B: Obtaining the Time the Key Was Pressed
        getSeconds()
        {
            string timestamp    = llGetTimestamp();
            string subTime      = llGetSubString(timestamp, 19, 25);
            float wallclock     = llGetWallclock();
            strTime = (float)subTime + wallclock;
        }
        
        //Module 5C: Comparing the Time Between Key Presses              
        compareTimes(float stored, float recent)
        {
            time = recent - stored;
        }
        
        //Module 5D: Resetting the storedTime Variable
        resetStored()
        {
        storedTime = 0;
        }
        
        //Module 5E: Double Tap
        
        FStrike()
        {
            if ( time <= interval | time > interval )
            {
                llStartAnimation(fwdanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDFWD;
            }
        }
        
        RLeft()
        {
            if ( time <= interval )
            {
                llStartAnimation(rotleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
            else
            {
                llStartAnimation(strafeleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
        }
        SLeft()
        {
            if ( time <= interval )
            {
                llStartAnimation(strafeleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
            else
            {
                llStartAnimation(rotleftanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDLFT;
            }
        }
        RRight()
        {
            if( time <= interval)
            {
                llStartAnimation(rotrightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
            else
            {
                llStartAnimation(straferightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
        }
        SRight()
        {
            if ( time <= interval )
            {
                llStartAnimation(straferightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
            else
            {
                llStartAnimation(rotrightanim);
                llSetTimerEvent(0.75);
                strike_type = SWORDRGT;
            }
        }
    
    //Module 6: The Sword Script
    
    //Module 6A: The Default State of the Sword Object When the Script Is First Executed
    default
    {
        //Module 6a: The Sword's Status When the Script is Reset - It Cannot Be Grabbed and Physically Dragged
        state_entry()
        {
            llSetStatus(STATUS_BLOCK_GRAB, TRUE);
        }
        
        //Module 6b: Actions to Take When the Sword is Attached and Detached From the Avatar        
        attach(key on)
        {
            if (on != NULL_KEY)
            {
                integer perm = llGetPermissions();
                
                if (perm != (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION))
                {
                    llRequestPermissions(on, PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
                }
                else
                {
                    llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT, TRUE, TRUE);
                }
                
            }
            else
            {
                llSay(0, "releasing controls");
                llReleaseControls();
            }
        }
        
        //Module 6c: If Permission Has Just Been Given, Take Over Keyboard Functions
        run_time_permissions(integer perm)
        {
            if (perm)
            {
                llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT | CONTROL_DOWN, TRUE, TRUE);
            }
        }
        
        //Module 6d: Defining the Keyboard Controls   
        control(key owner, integer held, integer change)
        {
            if (held & (CONTROL_ML_LBUTTON | CONTROL_FWD))
            {
                if (change & held & CONTROL_UP)
                {
                    llApplyImpulse(<0,0,3.5>,FALSE);
                    llStartAnimation(pgupanim);
                    llSetTimerEvent(0.25);
                    strike_type = SPECIALATK;
                }
                if (change & held & CONTROL_FWD)
                {
    
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    FStrike();                            
                    storedTime = recentTime;
                }
                if (change & held & CONTROL_ROT_LEFT)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    SLeft();                            
                    storedTime = recentTime;
                }
                if (change & held & CONTROL_LEFT)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    RLeft();                            
                    storedTime = recentTime;
                }
                if (change & held & CONTROL_ROT_RIGHT)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    SRight();                            
                    storedTime = recentTime;
                }
                if (change & held & CONTROL_RIGHT)
                {
                    getSeconds();
                    recentTime = strTime;                                                    
                    compareTimes(storedTime, recentTime);   
                    RRight();                            
                    storedTime = recentTime;
                }
                 if (change & held & CONTROL_BACK)
                {
                    llStartAnimation(bckanim);
                    llSetTimerEvent(0.25);
                    strike_type = KICK;
                }
            }
            if (~held & change & (CONTROL_ML_LBUTTON | CONTROL_FWD))
            {
                llStopAnimation(pgdwnanim);
            }
            if (held & change & CONTROL_DOWN)
                {   
                    llStartAnimation(pgdwnanim);
                    llTriggerSound(swdswing, 1.0);
                    llSetTimerEvent(0.01);
                    strike_type = BLOCK;
                    llMoveToTarget(llGetPos(), 0.25);
                    llSleep(1.0);
                    llStopMoveToTarget();
                }
            if (~held & change & CONTROL_DOWN)
                {   
                    llStopAnimation(pgdwnanim);
                }
        }
        
        //Module 6e: Actions to Perform When the Timer Event is Triggered
        timer()
        {
            if (strike_type == SWORDFWD)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            if (strike_type == SWORDRGT)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO);
            }
            if (strike_type == SWORDLFT)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO);
            }
            if (strike_type == BLOCK)
            {
                llSensor("", "", ACTIVE | AGENT, 2.0, PI_BY_TWO);
            }
            if (strike_type == KICK)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            if (strike_type == SPECIALATK)
            {
                llTriggerSound(swdswing, 1.0);
                llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
            }
            llSetTimerEvent(0.0);
        }
        
        //Module 6f: Actions to Perform if There's a Valid Target within the Predefined Sensor Range
        sensor(integer tnum)
        {
            vector dir = llDetectedPos(0) - llGetPos();
            dir.z = 0.0;
            dir = llVecNorm(dir);
            rotation rot = llGetRot();
            
            if (strike_type == SWORDFWD)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir += llRot2Up(rot);
                dir *= 200.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == SWORDRGT)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir += dir;
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == SWORDLFT)
            {
                llTriggerSound(swdconnectflsh, 1.0);
                llRezObject(bloodsplatter,llDetectedPos(0),<0,0,0>,ZERO_ROTATION,TRUE);
                dir -= llRot2Left(rot);
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == KICK)
            {
                llTriggerSound(kickconnect, 1.0);
                dir += dir;
                dir *= 100.0;
                llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
            }
            else if (strike_type == BLOCK)
            {
                llTriggerSound(blockconnect, 1.0);
            }
            else if (strike_type == SPECIALATK)
            {
                llTriggerSound(swdswing, 1.0);
                llPushObject(llDetectedKey(0), <0,0,150>, ZERO_VECTOR, FALSE);
            }
            strike_type= 0;
        }
    }

     

  10. Heyla and good afternoon!

    I'm not even sure I'm posting this in the right area, so apologies if this turns out to be the wrong forum for it. But I just finished fitting an outfit I had made to Senra Jamie. According to the license agreement:

    image.thumb.png.0ee4f7af6c5c117a27a26669c8c094d8.png

     

    My question is, exactly who am I supposed to submit my outfit to?

     

    Thank you to anyone who can solve this mystery for me!

    KeeperS Karu (Keeper S. Karu)

  11. Quote

    One could always have contacted one of the Moles who are in the lead of the Shop & Hop organization if there has been a hick up or something. Or ask for an explanation about why one wasn't approved. One can learn from that.
    At least that is what I would have done.

    Ah. I don't know anything about the Moles or who's in charge of the shop and hop organization. But yeah. I guess it's safe to say that I wasn't a successful applicant. I returned to SL in November and only just learned about the Senra bodies. I've still yet to hear about getting ahold of the devkit.

    • Like 1
  12. Heyla and good evening!

     

    I didn't know where else to post this question, so I decided to post here. I applied for the shop and hop event about a few days before the application deadline. I've been waiting for word one way or another whether or not I get to participate. Who do I contact to make certain of my status in the event?

     

    Thank you!

    KeeperS Karu

    • Like 1
  13. Thank you, so much! The model still imports in on its side, but both the mesh and the armature orients itself, properly, when I go into edit mode, now, instead of just the mesh . By sheer accident, I made an additional discovery when trying to see if clearing user transforms would make the armature go into the default T-Pose: while it didn't go into the T-Pose like I'd hoped, it did completely orient everything along the z-axis, so it's like that even in object mode. This definitely made things a lot easier for me to work with. In all, your instructions helped me to successfully bring the model into Blender. Thank you, again!

    • Like 1
  14. Heyla & Good Evening!

    I'd like to make some clothes that fit DreamCrawler Martin's weredog avatar (https://marketplace.secondlife.com/p/DC-NG-WereWolf-Series-WereDog-Starter-Pack-Custos/12364077). While DreamCrawler had left a download link for a dev kit (https://www.dropbox.com/s/ew1bife6t1stw5y/NG_WW_Dummies.zip?dl=0), it's only available in FBX and Maya format, rather than Collada format, and the software I use is Blender. Blender doesn't seem to be able to import Maya files, and while Blender has an option to import FBX files, I get an error when I try to use this option. Is there anyone experienced with both Maya and Blender who might be able to make a Blender-compatible version of this person's dev kit? And before you ask, according to their ReadMe file, the maker isn't familiar with Blender and had exported the files as FBX, because they had heard that Blender was able to handle this format. Also, I have tried to contact the creator, with no success. So I'm hoping that someone, here, might be able to help with this.

    I've tried a few things before I decided to simply ask for help: First, I found an FBX converter utility by Autodesk and tried to convert the FBX file to both collada and obj formats, with no success (either it won't convert, or it won't convert, properly, for some reason). When using the FBX importer for Blender, I finally noticed that the error was stating that it didn't support the ASCII version of the FBX file format, so I went back to the converter to see if I could convert it to a non-ASCII FBX file. Amazingly enough, I was able to do exactly that, converting the FBX file to binary, instead of ASCII. Blender was able to import this version, but there are some oddities with this file. When importing it, it imports the model so that its upright form is along the y-axis, instead of the z-axis.  Also, it's very tiny. I didn't see this as a problem, as I figured I could simply resize and rotate the model. Resizing was no problem: I resized the figure to match the size of the base SL figure I use to model my clothing around. Rotating produced the aforementioned oddities: in Object mode, the model is clearly on its side along the y-axis. However, when I go into edit mode to rotate the figure and armature properly it... snaps to the z-axis? Not quite sure how to describe it. It's just suddenly oriented in the manner I want it in. But when I go back to Object mode, the model is back on its side. While this is fine for modeling my clothes around the avatar, this seems like a problem if I want to copy its rigging to the clothes I make, and if the clothes are going to fit, properly, I need to be able to successfully copy the rigging to my clothing models. So I consider the use of the FBX importer a partial success, but I'd really like to find a way to reliably preserve the rigging of the dummy mesh, so I can use it for my clothes.

    The second thing I tried to do was download a trial version of Maya and simply export the Maya file in Collada format. Perhaps because I'm unfamiliar with the software, this attempt was unsuccessful. (Or maybe the trial version isn't able to export in other formats? I'm really not sure.)

    So at this point, I'm frustrated enough that I'll simply ask someone with more experience with help in successfully getting the files, with the rigging intact, into Blender.

     

    Thanks for the help,

    KeeperS Karu

  15. So I played around, further, with shared media in the project viewer. As one person noted, while I'm still having trouble loading up pdfs from other sites, I can kind of see pdf files from google drive. I had uploaded a pdf file and navigated to that link. While it displays the first page, it won't let me scroll to the other pages. So the ability to view pdf files is very much still rough and needs to be smoothed out, quite a bit.


  16. KeeperS Karu wrote:


    ObviousAltIsObvious wrote:

    the new browser is still a little rough yet, but PDF viewing is working here.
     

    Oh, awesome! This solves a dilemma I had encountered, a few days ago, concerning the issue of getting my PDF book into SL, for the convenience of Residents. Because of the charts and tables in the book, simply copying and pasting into a notecard was not a solution. The only one I'd been able to find was using shared media, but then I found that PDFs simply didn't load, correctly, on it, which was incredibly frustrating. I'm so happy that this is now a viable solution! Or, at least, that it will be, when it's official. I hope that's soon! Until then.... I think I'm going to have to download this viewer, because I'm not sure I can wait.
    :D

    So I downloaded the viewer, and I immediately checked a few random web sites to see if I can read PDF files. For me, now matter how many times I reloaded the page, the PDF pages just wouldn't load.

     

    Here are my system specs, if it will help:

    Operating System: Windows 10 Home 64-bit (10.0, Build 10240) (10240.th1.150930-1750)

    Language: English (Regional Setting: English)

    System Manufacturer: Gigabyte Technology Co., Ltd.

    System Model: GA-A55M-DS2

    BIOS: Award Modular BIOS v6.00PG

    Processor: AMD A8-3850 APU with Radeon HD Graphics (4 CPUs), ~2.9GHz

    Memory: 8192MB RAM

    Available OS Memory: 7678MB RAM

    Page File: 4701MB used, 4639MB available

    Windows Dir: C:\WINDOWS

    DirectX Version: 11.1

    DX Setup Parameters: Not found

    User DPI Setting: 144 DPI (150 percent)

    System DPI Setting: 96 DPI (100 percent)

    DWM DPI Scaling: Enabled

    Miracast: Not Available

    Microsoft Graphics Hybrid: Not Supported

    DxDiag Version: 10.00.10240.16384 64bit Unicode


  17. ObviousAltIsObvious wrote:

    the new browser is still a little rough yet, but PDF viewing is working here.
     

    Oh, awesome! This solves a dilemma I had encountered, a few days ago, concerning the issue of getting my PDF book into SL, for the convenience of Residents. Because of the charts and tables in the book, simply copying and pasting into a notecard was not a solution. The only one I'd been able to find was using shared media, but then I found that PDFs simply didn't load, correctly, on it, which was incredibly frustrating. I'm so happy that this is now a viable solution! Or, at least, that it will be, when it's official. I hope that's soon! Until then.... I think I'm going to have to download this viewer, because I'm not sure I can wait. :D

×
×
  • Create New...