Jump to content

KeeperS Karu

Resident
  • Posts

    354
  • Joined

  • Last visited

Everything 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. //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. 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.
  5. 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. 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. Thank you, so much, for clarifying! lol! I got the kit and just finished making a fit for Senra. Gonna upload it now!
  11. Ohhhhh! Thank you! I thought all clothing had to be approved by LL. So I can just upload it like usual and sell on my store like the other clothes?
  12. Thank you. Unfortunately, none of those links tell me who to submit my clothes to. I'm still confused as to how to submit my clothes.
  13. 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: 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)
  14. Heyla! Sent a friend request via Discord. Hopefully, we'll have an easier time talking there.
  15. All righty! Will keep that in mind! Thank you!
  16. 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.
  17. Yeah. I figured. But I thought I'd make sure. Who knows? Maybe an email got lost or something?
  18. 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
  19. 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!
  20. 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
  21. 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.
  22. 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. 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
  23. 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.
  24. Linden Lab wrote: Let us know your thoughts about the CEF - Media on a Prim project! For more context and information - please read our blog first! Will the new features also include the ability to read PDF files on a web site? At the moment, that's one of the things the current shared media technology lacks.
×
×
  • Create New...