function move_init() { moveable = false; // can be pushed or carried can_push = false; // can push things can_carry = false; // can carry things carry_dist = {l:0, r:0} // how far the object has been carried left or right subpixel=[0,0]; collision_at = function(xp,yp) { // can override for custom collision behaviour return !place_free(xp,yp); } } // call this in begin step, it should run every frame before calls to move function move_bstep() { if moveable { carry_dist = {l:0,r:0} } } // internal function for resetting positions after a push fails function _move_reset(reset) { if is_array(reset) { for(var i=0; i 0) and can_push and !moveable) { // or pushing an object below us // clear the reset data reset = []; // we temporarily toggle our moveableness off // it's to avoid infinite loops (the thing we push tries to push us, etc.) var moveable_restore = moveable; moveable = false; // gather all souls in our path and push them souls = instance_place_array(x+xa*s,y+ya*s,oSoul); for(var i=0; i carry_dist.l { carry_dist.l++; move(s,axis); } } else { if dist > carry_dist.r { carry_dist.r++; move(s,axis); } } } else if ya { // only triggers if we're carrying downwards (an upwards carry is a push) move(s,axis); } } } } // restore moveable status moveable = moveable_restore; } } // we're out of the while loop which means we moved the full target distance without hitting anything return true; }