I finished a carry/throw/place system for various objects the other day, and wanted to post it here again as reference for people looking to learn scripting. As a note, a lot of the functionality from this isn't just plug and play; for example, you would need to add checks if the player is carrying anything in a custom combat implementation/etc. Likewise you will need your own grab implementation for this code to work, here it is though, much of it will still be useful even though parts may require modification; also, credit where credit is due, some of the Carryable object was not written by me, basically all aside from onActionStoppedGrabbing and init;

Carry (Weapon)
PHP Code:
function onActionServerSidecmdp1p2p3p4 ) {
  
//Spawn object back into level
  
switch ( cmd ) {
    case 
"Spawn_Object":
      
temp.npc putnpc2(p1p2"");
      for (
temp.p4) {
        
temp.npc.join(temp.c);
      }
      
temp.npc.image p3;
    break;
  }
}

//#CLIENTSIDE
function onCreated() {
  
ObjectCarry this;
  
player.carrying false;
}
  
function 
onActionClientSidecmdp1p2p3 ) {
  
//Set player/weapon attributes and carry object
  
switch ( cmd ) {
    case 
"Object_Carry":
      
this.objectType p1;
      
this.classlist p3;
      
player.attr[20] = p2;
      
this.onCarryObject();
    break;
  }
}

function 
onCarryObject() {
  
freezeplayer(1);
  
setani("YOUR LIFT GANI HERE"nil);
  
replaceani("idle""YOUR IDLE GANI HERE");
  
replaceani("walk""YOUR WALK GANI HERE");
  
player.carrying true;
}

function 
onActionProjectile2(p1p2p3p4) {
  
//When player object projectile reaches end of path, spawn an npc on the level
  
if (p4 != player.account ) return;
  
triggerServer("gui"this.name"Spawn_Object"p1 1p2p3this.classlist);
}

public function 
onThrowObject() {
 
//Make sure the player isn't throwing on a wall before throwing.
  
temp.dx = (9.91 vecx(player.dir) + 0.5) / 20;
  
temp.dy = (9.91 vecy(player.dir) + 1) / 20;
  
temp.player.x;
  
temp.player.y;
  
  for (
temp.0temp.20temp.+= 1) {
    
temp.+= temp.dx;
    
temp.+= temp.dy;
    
    if (
onWall(temp.xtemp.y)) {
      return;
    }
  }
  
temp.XY = {player.vecx(player.dir), player.vecy(player.dir) - 1};


  
setshootparams(player.attr[20], player.account);
  
shoot(temp.XY[0], temp.XY[1], 1pi/* (player.dir 1), pi/40.9"YOUR PROJECTILE GANI HERE"player.attr[20]);

  
setani("YOUR THROW GANI HERE"nil);
  
replaceani("idle""idle");
  
replaceani("walk""walk");
  
player.carrying false;
}

public function 
onPlaceObject() {
  
//Place the object instead of throwing
  
temp.player.vecx(player.dir);
  
temp.player.vecy(player.dir);
  
triggerServer("weapon"this.name"Spawn_Object"temp.0.5temp.1player.attr[20], this.classlist);
  
setani("YOUR PLACE GANI HERE"nil);
  
replaceani("idle""idle");
  
replaceani("walk""walk");
  
player.carrying false;
}

function 
GraalControl.onKeyDown(keyCodekeyName) {
  if ( 
keyName == "A" ) {
    if ( 
player.carrying ) {
     
//Throw the object in front of the player.
      
this.onThrowObject();
    }
  } else
  if ( 
keyName == "S" ) {
    if ( 
player.carrying ) {
     
//Place object in front of player.
      
this.onPlaceObject();
    }
  }

Carryable (Class)
PHP Code:
function onPlayerChats() {
  if ( !
clientr.isStaff ) return;
  if ( 
player.chat == ":killobjects" 
    
this.destroy();
}

function 
onCreated() setshape(13232);
  
function 
init(type) {
  
this.type type;
  
this.grabbed false;
}

function 
onActionStoppedGrabbing() {
  if (!
this.grabbed) {
    
this.grabbed true;
    
player.triggerclient("weapon""Carry""Object_Carry"this.typethis.imagethis.joinedclasses);
    
this.destroy();
  }
}

//#CLIENTSIDE
function onCreated() setshape(13232); 
To elaborate a bit on what's going on. This is a system to define NPC objects as carryable. NPC's, when initiated, should have a type parameter (so you can select gani's of different sizes for objects of varying sizes). Replace "YOUR X GANI HERE" with "YOUR GANI PREFIX" @ this.type to achieve that effect. Likewise, make sure gani's use player attribute 20, and the projectile gani's use attr1. Also, onActionGrabbed and onActionStoppedGrabbing are custom events specified in your grab implementation. Hope someone finds this useful, feel free to comment questions/crtiticism!