
   /* AMX Mod script.
   *
   *  Jedi Force Grab
   *  by SpaceDude
   *  email: eayumns@nottingham.ac.uk
   *  MSN: eayumns@nottingham.ac.uk
   *  ICQ: 1615758
   *  IRC: Quakenet, nickname: "SpaceDude"
   *
   *  Description:
   *
   *  Another plugin for those admins who like to abuse their players and
   have a little fun.
   *  With  this  plugin  you  can  literally  pick players up, drag them
   around in the air and then
   *  depending on your mood either slam them into the ground or let them
   go free.
   *
   *  In  order to use this plugin you will need the xtrafun module which
   can be found here:
   *
   *  http://amxmod.net/forums/viewtopic.php?t=10714
   *
   *  Server Side Cvars:
   *
   *    sv_grabforce  -  sets  the  amount  of  force  used when grabbing
   players, default is 8
   *
   *  Client Side Commands:
   *
   *    +grab - bind a key to +grab like this: bind <key> +grab, once you
   have done that
   *            hold the key down and look at someone. Once you see their
   ID pop-up on
   *            the  screen  you  will  be able to drag them around, just
   look in the direction
   *            you  want  them  to  go  and  they will be dragged there.
   requires level ADMIN_SLAY.
   *
   *    grab_toggle  -  works  in  the  same  way as +grab except it is a
   toggle press once to grab
   *                  press a second time to release.
   *
   *
   *  Revision History:
   *
   *
   *   v1.1 - Added a red glow
   *        - Added a grab_toggle as an alternative to +grab
   *        - Added notify messages
   *        -  Made  it possible to grab people while dead (works best in
   Free View mode)
   *
   *   v1.0 - Initial Release
   */
   #include <amxmod>
   #include <xtrafun>
   new grabbed[33]
   new grablength[33]
   new bool:grabmodeon[33]
   new velocity_multiplier
   public grabtask(parm[])
   {
       new id = parm[0]
       new targetid, body
       if (!grabbed[id])
       {
           get_user_aiming(id, targetid, body)
           if (targetid)
           {
               set_grabbed(id, targetid)
           }
       }
       if (grabbed[id])
       {
           new     origin[3],     look[3],    direction[3],    moveto[3],
   grabbedorigin[3], velocity[3], length
           if (!is_user_alive(grabbed[id]))
           {
               release(id)
               return
           }
           get_user_origin(id, origin, 1)
           get_user_origin(id, look, 3)
           get_user_origin(grabbed[id], grabbedorigin)
           direction[0]=look[0]-origin[0]
           direction[1]=look[1]-origin[1]
           direction[2]=look[2]-origin[2]
           length = get_distance(look,origin)
           if (!length) length=1                // avoid division by 0
           moveto[0]=origin[0]+direction[0]*grablength[id]/length
           moveto[1]=origin[1]+direction[1]*grablength[id]/length
           moveto[2]=origin[2]+direction[2]*grablength[id]/length
           velocity[0]=(moveto[0]-grabbedorigin[0])*velocity_multiplier
           velocity[1]=(moveto[1]-grabbedorigin[1])*velocity_multiplier
           velocity[2]=(moveto[2]-grabbedorigin[2])*velocity_multiplier
           set_user_velocity(grabbed[id], velocity)
       }
   }
   public grab_toggle(id)
   {
       if (grabmodeon[id])
           release(id)
       else
           grab(id)
       return PLUGIN_HANDLED
   }
   public grab(id)
   {
       if (!(get_user_flags(id)&ADMIN_SLAY))
       {
           client_print(id,print_notify,"[AMX] You have no access to that
   command")
           return PLUGIN_HANDLED
       }
       if (!grabmodeon[id])
       {
           new targetid, body
           new parm[1]
           parm[0] = id
           velocity_multiplier = get_cvar_num("sv_grabforce")
           grabmodeon[id]=true
           set_task(0.1, "grabtask", 100+id, parm, 1, "b")
           get_user_aiming(id, targetid, body)
           if (targetid)
           {
               set_grabbed(id, targetid)
           }
           else
           {
               client_print(id,print_notify,"[AMX]    Searching   for   a
   target")
           }
       }
       return PLUGIN_HANDLED
   }
   public release(id)
   {
       if (!(get_user_flags(id)&ADMIN_SLAY))
       {
           client_print(id,print_notify,"[AMX] You have no access to that
   command")
           return PLUGIN_HANDLED
       }
       if (grabmodeon[id])
       {
           grabmodeon[id]=false
           if (grabbed[id])
           {
               new targname[32]
               set_user_gravity(grabbed[id])
               set_user_rendering(grabbed[id])
               get_user_name(grabbed[id],targname,31)
               client_print(id,print_notify,"[AMX] You have released %s",
   targname)
           }
           else
           {
               client_print(id,print_notify,"[AMX] No target found")
           }
           grabbed[id]=0
           remove_task(100+id)
       }
       return PLUGIN_HANDLED
   }
   public spec_event(id)
   {
       new targetid = read_data(2)
       if (targetid < 1 || targetid > 32)
           return PLUGIN_CONTINUE
       if (grabmodeon[id] && !grabbed[id])
       {
           set_grabbed(id, targetid)
       }
       return PLUGIN_CONTINUE
   }
   public set_grabbed(id, targetid)
   {
       new origin1[3], origin2[3], targname[32]
       get_user_origin(id, origin1)
       get_user_origin(targetid, origin2)
       grabbed[id]=targetid
       grablength[id]=get_distance(origin1,origin2)
       set_user_gravity(targetid,0.001)
       set_user_rendering(targetid,kRenderFxGlowShell,50,0,0,
   kRenderNormal, 16)
       get_user_name(targetid,targname,31)
       client_print(id,print_notify,"[AMX]  You  have  grabbed  onto %s",
   targname)
   }
   public plugin_init()
   {
       register_plugin("Jedi Force Grab","1.1","SpaceDude")
       register_cvar("sv_grabforce","8")
       register_clcmd("grab_toggle","grab_toggle",ADMIN_SLAY,"press  once
   to grab and again to release")
       register_clcmd("+grab","grab",ADMIN_SLAY,"bind a key to +grab")
       register_clcmd("-grab","release",ADMIN_SLAY)
       register_event("StatusValue","spec_event","be","1=2")
   }
