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 onActionServerSide( cmd, p1, p2, p3, p4 ) {
//Spawn object back into level
switch ( cmd ) {
case "Spawn_Object":
temp.npc = putnpc2(p1, p2, "");
for (temp.c : p4) {
temp.npc.join(temp.c);
}
temp.npc.image = p3;
break;
}
}
//#CLIENTSIDE
function onCreated() {
ObjectCarry = this;
player.carrying = false;
}
function onActionClientSide( cmd, p1, p2, p3 ) {
//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(p1, p2, p3, p4) {
//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 - 1, p2, p3, this.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.x = player.x;
temp.y = player.y;
for (temp.i = 0; temp.i < 20; temp.i += 1) {
temp.x += temp.dx;
temp.y += temp.dy;
if (onWall(temp.x, temp.y)) {
return;
}
}
temp.XY = {player.x + vecx(player.dir), player.y + vecy(player.dir) - 1};
setshootparams(player.attr[20], player.account);
shoot(temp.XY[0], temp.XY[1], 1, pi/2 * (player.dir + 1), pi/4, 0.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.x = player.x + 2 * vecx(player.dir);
temp.y = player.y + 2 * vecy(player.dir);
triggerServer("weapon", this.name, "Spawn_Object", temp.x + 0.5, temp.y + 1, player.attr[20], this.classlist);
setani("YOUR PLACE GANI HERE", nil);
replaceani("idle", "idle");
replaceani("walk", "walk");
player.carrying = false;
}
function GraalControl.onKeyDown(keyCode, keyName) {
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(1, 32, 32);
function init(type) {
this.type = type;
this.grabbed = false;
}
function onActionStoppedGrabbing() {
if (!this.grabbed) {
this.grabbed = true;
player.triggerclient("weapon", "Carry", "Object_Carry", this.type, this.image, this.joinedclasses);
this.destroy();
}
}
//#CLIENTSIDE
function onCreated() setshape(1, 32, 32);
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!