|
Will work for food. Maybe
|
 |
Join Date: Sep 2003
Location: Maryland, USA
Posts: 9,589
|
|
PHP Code:
//#CLIENTSIDE enum { IDLE,WALK,GRAB,PULL,PUSH,SIT,SWIM }
function onCreated() { /* CUSTOMIZABLES */ // AN ARRAY OF GANIS, REFLECTIVE OF THE ABOVE ENUMERATOR player.ganis = {"idle","walk","grab","pull","push","sit","swim"}; player.speed = .6; // THE PLAYER'S MOVEMENT SPEED player.slidespeed = .25; // THE SPEED THE PLAYER MOVES WHEN SLIDING player.actionspeed = 1; // SPEED ACTIONS ARE EXECUTED(PUSH,PULL) /* NO MORE CUSTOMIZABLES :( */
noplayerkilling(); // NO PLAYER KILLING = PLAYERS NOT BLOCKING! disabledefmovement(); // DISABLE DEFAULT MOVEMENT this.defaultganis = player.ganis; // MAKE A COPY OF GANIS FOR DEFAULT COMPARISON(replaceGani()) player.wallcheck = new[2]; // CREATE WALL CHECK ARRAY player.notpush = timevar2; // KEEP TRACK OF WHEN PLAYER IS NOT PUSHING ReturnIdle(); // RETURN PLAYER TO IDLE POSITION
setTimer(0.05); }
function onTimeout() { Main(); // CALL MAIN FUNCTION
// RECORD LAST FRAME OF DATA, USED FOR NEXT FRAME DATA COMPARISON this.oldData = {player.x,player.y,player.freezetime,player.movemode,player.level.name};
setTimer(.05); // ERR, }
function Main() { // DETERMINE WHETHER THE PLAYER'S GANI SHOULD BE UPDATED temp.updateGani = player.x != this.oldData[0] || player.y != this.oldData[1] || (player.freezetime == -1 && this.oldData[2] >=0);
// IF PLAYER IS FROZEN(freezeplayer()), RETURN(STOP THE FUNCTION) if (player.freezetime >= 0) return; ReturnIdle(true); // ALWAYS RETURN THE PLAYER TO IDLE, true = DO NOT SET THE GANI Movement(); // DO MOVEMENT FUNCTIONS
// FIND THE TILE TYPE UNDER THE PLAYER, APPLY MODES APPROPRIATELY temp.undertile = tiletype(player.x+1.5,player.y+2); if (undertile == 11) player.movemode = SWIM; else if (undertile == 3) player.movemode = SIT;
// IF PLAYER IS NOT SWIMMING... if (player.movemode != SWIM) { // IF A WALL IS IN FRONT OF PLAYER... if (@player.wallcheck == @{1,1}) { // IF PLAYER HOLDS 'A'... if (keydown(6)) { // AND PLAYER IS HOLDING OPPOSITE DIRECTION KEY, PULL if (keydown((player.dir+2)%4)) player.movemode = PULL; // OTHERWISE THEY ARE GRABBING else player.movemode = GRAB; } // IF THEY'RE HOLDING THE SAME KEY THEY ARE FACING if (keydown(player.dir)) { // AFTER TIMEVAR2 EXCEEDS THE LAST TIME THE PLAYER WAS NOT PUSHING, // PLUS THEIR ACTION SPEED, SET MODE TO PUSH if (timevar2 > player.notpush + player.actionspeed) player.movemode = PUSH; } else player.notpush = timevar2; // WHEN NOT HOLDING KEY, RECORD TIME } }
Actions(); // PERFORM ACTIONS(GRABBING/PUSHING/PULLING...) Animate(updateGani); // ANIMATE THE PLAYER, SEND WHETHER IT SHOULD BE UPDATED }
function Movement() { // IF PLAYER IS GRABBING OR PULLING, DO NO MOVEMENT(RETURN) if (player.movemode in {GRAB,PULL}) return;
for (temp.k=0;k<4;k++) { if (keydown(k)) { // IF PLAYER MOVES, STOP THE PLAYER FROM PUSHING ANYMORE if (k != player.dir) player.notpush = timevar2;
player.dir = k; // CHECK FOR WALL IN PLAYER'S NEW DIRECTION player.wallcheck = CheckWall(k); // IF ABSOLUTELY NO WALL, PROCEED WITH MOVEMENT! // DO THIS BY COMPARING TWO ARRAYS if (@player.wallcheck == @{0,0}) { player.x += vecx(k)*player.speed; player.y += vecy(k)*player.speed; } else { ClearGap(k); // IF PLAYER HITS WALL, RUN ClearGap() TO RUN PRECISION CHECK // IF PLAYER IS HITTING WALL ON ONLY ONE SIDE, SLIDE THE PLAYER AROUND if (player.wallcheck[0] + player.wallcheck[1] == 1) WallSlide(k); }
player.movemode = WALK; // SET MODE TO WALK } } }
// CheckWall(direction[,speed]), SPEED IS OPTIONAL PARAMETER function CheckWall(k,speed) { // IF SPEED IS NOT GIVEN, DO CHECK AT PLAYER'S DEFAULT SPEED if (temp.speed == null) temp.speed = player.speed;
// CREATE CHECK POSITION FOR BOX ONE temp.checkOne = { player.x + .5 + vecx(k)*(k < 2 ? speed : 2), player.y + 1 + vecy(k)*(k < 2 ? speed : 2) };
// CREATE CHECK POSITION FOR BOX TWO temp.checkTwo = { player.x + 1.5 + vecx(k)*(k < 2 ? speed + 1 : 2 - 1), player.y + 2 + vecy(k)*(k < 2 ? speed + 1 : 2 - 1) };
// CREATE AN ARRAY, AND DO WALL CHECKS // DETERMINE SIZE OF ONWALL2 IN RELATION TO PLAYER'S SPEED, TO DO ACCURATE CHECKS // AT HIGHER SPEEDS(NO WALL HOPPING) temp.hitwall = { onwall2(checkOne[0],checkOne[1],(k in {1,3} ? speed : 1)-1/16,(k in {0,2} ? speed : 1)-1/16), onwall2(checkTwo[0],checkTwo[1],(k in {1,3} ? speed : 1)-1/16,(k in {0,2} ? speed : 1)-1/16), };
return hitwall; // RETURN WALL COLLISION CHECK }
function ClearGap(k) { temp.i = 0; // INITIATE 'i' OUTSIDE OF LOOP, SO IT IS ACCESSIBLE AFTERWARDS // INITIATE FOR LOOP AT 1/16, WHICH IS THE EQUIVALENT OF A SINGLE PIXEL // THIS AVOIDS SENDING WALL CHECK AT SPEED 0, WHICH WOULD MAKE THE FUNCTION // CHECK FOR THE PLAYER'S DEFAULT SPEED(0 = NULL) // // FOR LOOP IS THE SIZE OF PLAYER'S SPEED, INCREMENTING AT 1/16 // THIS CHECKS EVERY PIXEL BETWEEN THE PLAYER AND WHERE THEY HIT THE WALL // FOR PRECISION ACCURACY for (temp.i=1/16;i<player.speed;i+=1/16) { temp.CheckGap = CheckWall(k,i); // IF WALL IS DETECTED, STOP THE LOOP TO RETAIN IMPORTANT PIXEL DATA if (@CheckWall(k,i) != @{0,0}) break; } // IF LOOP COMPLETES FULLY, THEN THERE IS NO WALL. STOP CHECKING if (i == player.speed) return;
// IF DIRECTION IS LEFT OR RIGHT, MAKE CHANGES TO PLAYER'S X if (k in {1,3}) { player.x += vecx(k)*i; // ADD 'i' TO PLAYER'S X POSITION // THEN GET RID OF DIRTY FLOATING VALUES // AND ADD .5, SINCE THE PLAYER'S GANI X IS OFFSET .5 FROM POSITION player.x = int(player.x)+.5; // IF DIRECTION IS UP OR DOWN, MAKE CHANGES TO PLAYER'S Y } else { player.y += vecy(k)*i; // ADD 'i' TO PLAYER'S X POSITION player.y = int(player.y+.5); // ROUND OFF PLAYER'S Y TO CLEAN FLOATING VALUE } }
function WallSlide(k) { temp.slidedir = 0; // INITIATE TEMPORARY SLIDE DIRECTION
// IF CHECK BOX ONE IS HITTING WALL, AND NOT BOX TWO... if (player.wallcheck[0] == 1 && player.wallcheck[1] == 0) slidedir = (k + (k in {1,2} ? 1 : -1))%4; // OTHERWISE ASSUME BOX TWO IS HITTING A WALL, AND NOT BOX ONE else slidedir = (k + (k in {1,2} ? -1 : 1))%4;
// CHECKK FOR WALL IN SLIDING DIRECTION temp.slidewall = CheckWall(slidedir,player.slidespeed); if (@slidewall != @{0,0}) return; // HIT WALL? RETURN AND STOP SLIDING // MOVE PLAYER IN SLIDING DIRECTION player.x += vecx(slidedir)*player.slidespeed; player.y += vecy(slidedir)*player.slidespeed; // ROUND OFF PLAYER'S POSITION TO NEAREST SLIDING SPEED // THIS GETS RID OF LONG FLOATING VALUES player.x = int(player.x/player.slidespeed)*player.slidespeed; player.y = int(player.y/player.slidespeed)*player.slidespeed; }
function Actions() { // PERFORM CHECKS TO MAKE SURE ACTIONS ARE NOT BEING PERFORMED if (player.movemode == GRAB) { // IF GRABBING... if (this.hasgrabbed == false) { // AND NOT KNOWN TO BE GRABBING BEFORE... // TRIGGERACTION 'grab' IN FRONT OF PLAYER triggerAction(player.x+1.5+vecx(player.dir)*2, player.y+2+vecy(player.dir)*2, "grab",null); this.hasgrabbed = true; // LET SCRIPT KNOW PLAYER IS GRABBING } } else this.hasgrabbed = false; // IF NOT GRABBING, STOP RECORDING THAT PLAYER IS
// DO SIMILAR CHECKS FOR PUSH AND PULL, EXCEPT ONLY EVERY N SECONDS(player.actionspeed) if (player.movemode == PULL) { if ((timevar2 - this.startpull) > player.actionspeed) { triggerAction(player.x+1.5+vecx(player.dir)*2, player.y+2+vecy(player.dir)*2, "pulled",(player.dir+2)%4); this.startpull = timevar2; } } else this.startpull = timevar2;
if (player.movemode == PUSH) { if ((timevar2 - this.startpush) > player.actionspeed) { triggerAction(player.x+1.5+vecx(player.dir)*2, player.y+2+vecy(player.dir)*2, "pushed",player.dir); this.startpush = timevar2; } } else this.startpush = timevar2; }
function Animate(update) { // IF PLAYER'S MODE HAS CHANGED, OR FORCED UPDATE IS TRUE, UPDATE GANI if (player.movemode != this.oldData[3] || update == true) { setani(player.ganis[player.movemode],null); } }
// A CONVENIENT FUNCTION TO RUN CHECKS TO RETURN PLAYER TO IDLE POSITION // MADE PUBLIC SO EXTERNAL SCRIPTS CAN CALL IT. // INSTEAD OF SETTING GANI TO IDLE, USE THIS FUNCTION INSTEAD // omitgani PARAMETER TELLS FUNCTION TO NOT SET THE GANI, ONLY SET THE MODE public function ReturnIdle(omitgani) { // DO NOT CONTINUE TO IDLE IF... if (player.movemode == SWIM) return; // SWIMMING if (player.movemode in {GRAB,PULL} && keydown(6)) return; // GRABBING OR PULLING if (player.movemode == PUSH && keydown(player.dir)) return; // PUSHING
// SET MODE AS IDLE. HERE YOU CAN DO MORE CHECKS TO PROPERLY ASSIGN IDLE MODE // FOR EXAMPLE, IS PLAYER CARRYING SOMETHING? IF SO, SET MODE TO CARRYIDLE // INSTEAD OF IDLE. player.movemode = IDLE;
if (omitgani == true) return; // IF OMIT GANI, STOP FUNCTION BEFORE SETTING GANI if (player.movemode == IDLE) setAni(player.ganis[player.movemode],null);
// RECORD LAST FRAME DATA IN CASE IT'S NEEDED this.olddata = {player.x,player.y,player.freezetime,player.act}; }
public function ReplaceGani(defgani,newgani) { // FIND INSTANCE OF DEFAULT GANI IN LIST OF CUSTOM GANI'S temp.ganifound = this.defaultganis.index(defgani);
// IF newgani IS NOT PROVIDED, RESET GANI TO DEFAULT if (newgani == null) player.ganis[ganifound] = this.defaultganis[ganifound]; // OTHERWISE REPLACE THE GANI WITH NEW GANI else player.ganis[ganifound] = newgani; }
|
Last edited by DustyPorViva; 03-13-2010 at 10:15 PM..
|