Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   NPC Scripting (https://forums.graalonline.com/forums/forumdisplay.php?f=8)
-   -   [tutorial]How to script a movement system (https://forums.graalonline.com/forums/showthread.php?t=134258376)

jkldogg 03-14-2010 11:53 PM

Congrats on typing all that stuff for the world. That's very helpful. Rep+ later

Cubical 10-18-2010 10:04 PM

I'm currently having a problem where it won't set the players animation back to whatever mode after it's completed. For instance I use the sword gani while walking and it will set the animation to idle while I'm moving. I know it's probably just 1 line that I need but I'm kinda having a brainfart. Could anyone help me with it. I figured this would be the thread to post for help in since I pretty much used this as a base.

PHP Code:

enum {
  
blah,blah,blah
}
function 
onCreated(){
  
setTimer(0.05);
}
function 
onTimeout(){
  
doStuff();
}
function 
doStuff(){
  
onSetIdle();
  
//do movement and action checks
  
onAnimate();
  
setTimer(0.05);
}
function 
onSetIdle(){
  
this.movemode IDLE;
}
function 
onAnimate(){
  if (!(
this.oldmode == this.movemode)){
    
player.chat player.ani;
    
setani(this.defaultganis[this.movemode], null);
    
this.oldmode this.movemode;
  }   



ffcmike 10-18-2010 10:16 PM

Quote:

Originally Posted by Cubical (Post 1607177)
I'm currently having a problem where it won't set the players animation back to whatever mode after it's completed. For instance I use the sword gani while walking and it will set the animation to idle while I'm moving. I know it's probably just 1 line that I need but I'm kinda having a brainfart. Could anyone help me with it. I figured this would be the thread to post for help in since I pretty much used this as a base.

PHP Code:

enum {
  
blah,blah,blah
}
function 
onCreated(){
  
setTimer(0.05);
}
function 
onTimeout(){
  
doStuff();
}
function 
doStuff(){
  
onSetIdle();
  
//do movement and action checks
  
onAnimate();
  
setTimer(0.05);
}
function 
onSetIdle(){
  
this.movemode IDLE;
}
function 
onAnimate(){
  if (!(
this.oldmode == this.movemode)){
    
player.chat player.ani;
    
setani(this.defaultganis[this.movemode], null);
    
this.oldmode this.movemode;
  }   



From the looks of that script it would seem like the sword gani would only last 1 frame before idle kicks back in, have you considered making a function/variable such as pauseGanis(time); to accompany such things as slashing?

Cubical 10-18-2010 10:20 PM

Quote:

Originally Posted by ffcmike (Post 1607180)
From the looks of that script it would seem like the sword gani would only last 1 frame before idle kicks back in, have you considered making a function/variable such as pauseGanis(time); to accompany such things as slashing?

It last the full duration, I have thought about doing something along the lines of that but I'm sure there's another way. I just can't think of it. It's like in the back of my mind.
http://www.youtube.com/watch?v=xlJmM1KnQ4M

DustyPorViva 10-18-2010 10:48 PM

Using that method will create that problem, yes. If you look at my demo script you'll notice early on I compare values such as x/y to determine whether the player's animation should be updated. Changes in certain values will force an update regardless, such as the player's position, which is then passed on to the animation function.
PHP Code:

  temp.updateGani player.!= this.oldData[0] ||
      
player.!= this.oldData[1] ||
      (
player.freezetime == -&& this.oldData[2] >=0); 

this.oldData is an array of values saved at the end of the movement to be compared on the next frame.

Only comparing modes is an unreliable method and cripples functionality as eventually you'll notice you can't set animations outside of the default set under their circumstances, even from outside scripts(such as making the player sit with a "/sit" command).

Cubical 10-19-2010 12:15 AM

I fixed the problem, I had done something similar to what you were posting but there was a typo in one of the variable names. Thanks for suggesting that and making me double check.
edit: i decided to go with what you posted because it will save me the hassle of having an abundance of useless lines.

scriptless 10-22-2010 12:50 PM

Nice work dusty. I was going to post something very similar to this but just mentioning I was using onwall2 got me yelled at.. lol

everyone was just saying omg onwall2 uses to many checks and that a loop and onwall would be better.. I almost want to say they claimed that onwall2 uses pixel checks not just 16x16 pixel tile checks.


is this just pure bullcrap or is there any truth to what I was told? I figure a great scripter like you might be able to clear that up? =p



EDIT:
Personally I would like to see it possible to not only detect onwall2(), but output the nearest wall cordinates.. so rounding would not be nessisary.. =/

Crow 10-22-2010 04:38 PM

Quote:

Originally Posted by scriptless (Post 1608053)
Nice work dusty. I was going to post something very similar to this but just mentioning I was using onwall2 got me yelled at.. lol

everyone was just saying omg onwall2 uses to many checks and that a loop and onwall would be better.. I almost want to say they claimed that onwall2 uses pixel checks not just 16x16 pixel tile checks.


is this just pure bullcrap or is there any truth to what I was told? I figure a great scripter like you might be able to clear that up? =p



EDIT:
Personally I would like to see it possible to not only detect onwall2(), but output the nearest wall cordinates.. so rounding would not be nessisary.. =/

onwall2 rocks, I use it. There's nothing wrong with it. In theory, it's just like tons of onwall calls in a loop, but everything is done internally.

DustyPorViva 10-22-2010 05:47 PM

Quote:

Originally Posted by scriptless (Post 1608053)
Nice work dusty. I was going to post something very similar to this but just mentioning I was using onwall2 got me yelled at.. lol

everyone was just saying omg onwall2 uses to many checks and that a loop and onwall would be better.. I almost want to say they claimed that onwall2 uses pixel checks not just 16x16 pixel tile checks.


is this just pure bullcrap or is there any truth to what I was told? I figure a great scripter like you might be able to clear that up? =p



EDIT:
Personally I would like to see it possible to not only detect onwall2(), but output the nearest wall cordinates.. so rounding would not be nessisary.. =/

The only bad thing about onwall2 is that other functions have not adapted the same functionality, like tiletype() and tiles[]. So if you start working with tiles, then it becomes a pain in the ass.

scriptless 10-23-2010 12:29 PM

Quote:

Originally Posted by DustyPorViva (Post 1608075)
The only bad thing about onwall2 is that other functions have not adapted the same functionality, like tiletype() and tiles[]. So if you start working with tiles, then it becomes a pain in the ass.

I'm confused what you mean by functionality? If you used tiletype for example, do you mean check if a tiletype exists in a given area of tiles? I actually think that feature would be VERY usefull, altho can be done with a workaround, it still would be nice.

Quote:

Originally Posted by Crow (Post 1608071)
onwall2 rocks, I use it. There's nothing wrong with it. In theory, it's just like tons of onwall calls in a loop, but everything is done internally.

Thats what I was told.. But everyone made it seem like that internal loop caused alot of lag.. tho I never tested how much or never was offered any proof to back up there claims that it would create enough lag to halt the world.

Crow 10-23-2010 12:48 PM

Quote:

Originally Posted by scriptless (Post 1608153)
Thats what I was told.. But everyone made it seem like that internal loop caused alot of lag.. tho I never tested how much or never was offered any proof to back up there claims that it would create enough lag to halt the world.

My tests have shown that onwall2 is more efficient than onwall.

DustyPorViva 10-23-2010 06:39 PM

Quote:

Originally Posted by scriptless (Post 1608153)
I'm confused what you mean by functionality? If you used tiletype for example, do you mean check if a tiletype exists in a given area of tiles? I actually think that feature would be VERY usefull, altho can be done with a workaround, it still would be nice.

Exactly. Say you build a movement system off of onwall2 like this(which I usually do). Then suddenly you need to code in some custom tile detection, say making chairs blocking(for horses). Now you're screwed because coding a wall check for onwall2(which detects areas) and tiles(which detects only a single pixel) is very different. I mean, it's not impossible but it always seems like a waste of time and effort.


I don't see any reason why someone would think onwall2 was less efficient than onwall. If you use onwall you end up having to do the extra checks that onwall2 does anyways, except you have to do them in GS2 which is much less efficient than it being internally handled. It doesn't make any sense to assume otherwise.

xXziroXx 05-06-2013 02:29 PM

Hey Dusty. I think I remember you saying in some thread a while back that you had scripted a cliff jumping function, but was unwilling to share it at the time? I could be mistaken, but in case you did make one, is it anything you'd be willing to share now or even implement into this? :)

DustyPorViva 05-06-2013 04:51 PM

Quote:

Originally Posted by xXziroXx (Post 1717584)
Hey Dusty. I think I remember you saying in some thread a while back that you had scripted a cliff jumping function, but was unwilling to share it at the time? I could be mistaken, but in case you did make one, is it anything you'd be willing to share now or even implement into this? :)

Well it was released actually, in the movement script of the server dump I posted here: http://forums.graalonline.com/forums...hlight=excited

PHP Code:

function CheckJump(d,except) {
  
hideimg(1);
  
temp.clifftiles = {
     
0xD2,0x1140xD30xD4,0x268,0x269,0x3CE,0x3CF,
     
0xE2,0x1240xE30xE4,0x267,0x26A,0x232,0x233,
    
0x111,0x112,0x1AA,0x113,0x277,0x27A,0x242,0x243,
    
0x121,0x122,0x1BA,0x123,0x287,0x28A,0x1CF,0x107,
     
0xB90xBA0xAE0xAF,0x297,0x29A,0x1DF,0x117,
     
0xC90xCA0x980x99,0x359,0x35C,0x22E,0x22F,
     
0xD90xDA,0x12E,0x12F,0x3CE,0x3CF,0x1600xCF,
     
0xE90xEA0xBE0xBF,0x1AC,0x1AC,0x1700xDF,
     
0xF90xFA,0x7CA,0x7CB,0x1BC,0x1BC,0x39F,0x39E,
    
0x7ED,0x7EE,0x7DA,0x7DB,0x153,0x154,0x3AF,0x3AE,
    
0x7FD,0x7FE,0x7FF,0x7FF,0x7FF,0x7FF,0x7FF,0x7FF
  
};

  if (
vecx(d) != 0) {
    
temp.jx int(player.x)+.5;
    
temp.jy int(player.y) + 1;
  } else {
    
temp.jx player.x;
    
temp.jy int(player.1);
  }

  
temp.nx player.x;
  
temp.ny player.y;
  
temp.sx temp.sy 0;
  
temp.1;
  
temp.jumpcliff tiles[player.x+1.5+vecx(d)*2,player.y+2+vecy(d)*2in clifftiles || tiles[player.x+1.5+vecx(d)*2,player.y+2+vecy(d)*2in except;
  while (
onwall2(jx+vecx(d)*((i-1>0?i-1:1)*2),
                 
jy+((i-1>0?i-1:1)*(== 0?-1:1)),
                 
2,2)
         || 
CheckSqrTiles(jx+vecx(d)*((i-1>0?i-1:1)*2),
                          
jy+((i-1>0?i-1:1)*(== 0?-1:1)),
                          
except)) {
    
temp.sx jx vecx(d)*(i*2);
    
temp.sy jy i*(== 0?-1:1);
    
i++;
    for (
temp.j=0;j<4;j++) {
      if ((
jumpcliff == true && CheckSqrTiles(sx,sy,clifftiles) == false && onwall2(sx,sy,1,1))
          || (
player.horseimg != null && onwater(sx+1,sy+1))) {
        
freezeplayer(0);
        if (
player.horseimg == nullplayer.act PUSH;
        return;
      }
    }
    for (
temp.npcs) {
      if (
j.gap != null) {
        if (
sx+1.5 in |j.x,j.x+j.gap[0]| && sy+2 in |j.y,j.y+j.gap[1]|) {
          
freezeplayer(0);
          if (
player.horseimg == nullplayer.act PUSH;;
          return;  
        }
      }
    }
    if (
25) {
      
freezeplayer(0);
      if (
player.horseimg == nullplayer.act PUSH;;
      return;
    }
  }
  
i++;
  if (
<= || 25) {
    
freezeplayer(0);
    if (
player.horseimg == nullplayer.act PUSH;
    return;
  }
  
player.lastpush timevar2;
  
freezeplayer(.1);
  
player.act JUMP;
  
nx sx;
  
ny sy-1;

  if (
player.carry != nullsetani("ce_carryjump",null);
  else if (
player.horseimg != null) {
    
player.attr[4] = "ce_horsejumpscript.gani";
    
setani("ce_ridejump",null);
  } else 
setani("ce_jump",null);

  
temp.jp == .2 .4;
  if (
player.dir == 0temp.jp = -.4;
  for (
temp.j=0;j<((i-2)*2)+1;j++) {
    
freezeplayer(0.25);
    
player.jx vecx(d)*j;
    
player.= (jy-1) - (jp*j)*(== 0?-1:1);

    if (
== 0showimg(0,"sprites.png",nx 1,(player..5) + 2.5 j/20);
    else if (
== 2showimg(0,"sprites.png",nx 1,(ny-1) + 3);
    else 
showimg(0,"sprites.png",jx vecx(player.dir)*j,(jy-1) + 2.5 + (j*.5));
    
changeimgpart(0,24,0,16,8);
    
changeimgvis(0,0);

    if (
player.=> ny && 0) {
      
player.ny;
      break;
    } else if (
player.<= ny && == 0) {
      
player.ny;
      break;
    }
    
jp -= (d in {0,2}) ? .1 : (0.75/(i+((i-5)*.65)));
    
sleep(0.05);
  }
  
player.nx;
  
player.ny;
  
freezeplayer(0);
  
ReturnIdle();
  
hideimg(0);
}

function 
CheckSqrTiles(cx,cy,tls) {
  
temp.istiles false;
  for (
temp.tl=0;tl<4;tl++) {
    if (
tiles[cx+tl%2,cy+int(tl/2)] in tls) {
      
istiles true;
      break;
    }
  }
  return 
istiles;



xXziroXx 05-06-2013 05:29 PM

Quote:

Originally Posted by DustyPorViva (Post 1717592)
Well it was released actually, in the movement script of the server dump I posted here: http://forums.graalonline.com/forums...hlight=excited

Thank you! Deciphering time... :D


All times are GMT +2. The time now is 07:48 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.