View Single Post
  #3  
Old 03-13-2010, 08:46 PM
DustyPorViva DustyPorViva is offline
Will work for food. Maybe
DustyPorViva's Avatar
Join Date: Sep 2003
Location: Maryland, USA
Posts: 9,589
DustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond repute
Send a message via AIM to DustyPorViva Send a message via MSN to DustyPorViva
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.!= this.oldData[0] ||
      
player.!= this.oldData[1] ||
      (
player.freezetime == -&& 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 == 11player.movemode SWIM;
  else if (
undertile == 3player.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.actionspeedplayer.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 (!= player.dirplayer.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.+= vecx(k)*player.speed;
        
player.+= 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] == 1WallSlide(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 == nulltemp.speed player.speed;

  
// CREATE CHECK POSITION FOR BOX ONE
  
temp.checkOne = {
    
player..5 vecx(k)*(speed 2),
    
player.vecy(k)*(speed 2)
  };

  
// CREATE CHECK POSITION FOR BOX TWO
  
temp.checkTwo = {
    
player.1.5 vecx(k)*(speed 1),
    
player.vecy(k)*(speed 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.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 (== player.speed) return;

  
// IF DIRECTION IS LEFT OR RIGHT, MAKE CHANGES TO PLAYER'S X
  
if (k in {1,3}) {
    
player.+= 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.int(player.x)+.5;
  
// IF DIRECTION IS UP OR DOWN, MAKE CHANGES TO PLAYER'S Y
  
} else {
    
player.+= vecy(k)*i;       // ADD 'i' TO PLAYER'S X POSITION
    
player.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] == && player.wallcheck[1] == 0slidedir = (+ (k in {1,2} ? : -1))%4;
  
// OTHERWISE ASSUME BOX TWO IS HITTING A WALL, AND NOT BOX ONE
  
else slidedir = (+ (k in {1,2} ? -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.+= vecx(slidedir)*player.slidespeed;
  
player.+= vecy(slidedir)*player.slidespeed;
  
// ROUND OFF PLAYER'S POSITION TO NEAREST SLIDING SPEED
  // THIS GETS RID OF LONG FLOATING VALUES
  
player.int(player.x/player.slidespeed)*player.slidespeed;
  
player.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 == IDLEsetAni(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 == nullplayer.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..
Reply With Quote