Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   NPC Scripting (https://forums.graalonline.com/forums/forumdisplay.php?f=8)
-   -   2 questions (server warp & putnpc2) (https://forums.graalonline.com/forums/showthread.php?t=85704)

Jiroxys7 05-25-2009 07:06 AM

Quote:

Originally Posted by cbk1994 (Post 1493810)
Can you post the code that is placing the NPC?

The problems I seem to be having in general is anything that tells the script to read something from a different side. Problem is, since the editor never required such a thing for scripts to work, I never had to tell anything which side to use. The wiki tends to just complicate the hell out of things (also the place where I first saw the putnpc2(32, 32, "join(\"classname\");"); variation of putnpc2.). And I quickly gave up on testbed since nearly everything players put on there is GS1 or doesnt work or something.


My 5-6 years of scripting experience on the editor only required 2 things:
1. Some GS1 knowledge.
2. The "If it works the way you want it to one way, There's no reason to change it" mindset. Which allowed me to skip practicing with //#CLIENTSIDE completely. Also with the fact that since the editor IS clientside, i just mistook the thing as a //comment since it didn't seem to change or do anything.

Which also makes it seem very VERY hard for me to get anything off clientside. Since I have nearly zero first-hand experience with calling parts of a script serverside FROM clientside and vice-versa. Since the editor uses nothing but clientside, I'm fairly comfortable with clientside. Of course, when I have something that needs to be serverside, tons of complications tend to arise.

Also, another problem is I'd love to hire a scripter or two who knows what they're doing.. But the problem there is that there's no one I feel I could trust (Ever get those people who either randomly, out of the blue, pop up on your server asking to be Co-Manager, or Manager or some high up staff? Or those players who just want to be staff mainly for the RC and, as scripters go anyways, the manipulative scripts they can give themselves?)

So right now, I really feel I'm stuck doing this solo for now.

Anyways, If you want to take a look at the script. This is the best "working" version.


PHP Code:

//#CLIENTSIDE
function onCreated(){
  
// Initialize the attributes

  
this.startershot=1;
  
this.timeout1=random(0.05,0.25);

  
showcharacter;
  
dontblock;

  
setcharprop #3,archersummon.png;
  
setcharprop #C0,orange;
  
setcharprop #C1,green;
  
setcharprop #C2,black;
  
setcharprop #C3,green;
  
setcharprop #C4,black;
  
setcharprop #2,no-shield.gif;
  
shieldpower 1;
  
dir 1;
  
hurtdx 0;
  
hurtdy 0;

  
hearts 1+strtofloat(#s(client.summonarcherallylevel))/5;
  
move -random(15,20)-strtofloat(#s(client.summonarcherallylevel)),random(-15,15),random(1.5,2.5),8;
  
setcharani bowwalk,wbow1.png;
  
      if(
strtofloat(#s(client.summonarcherallylevel))>8){
      
this.timeout2=random(0.25,0.50);
      }
     
      else if(
strtofloat(#s(client.summonarcherallylevel))>5){
      
this.timeout2=random(0.50,0.75);
      }

      else if(
strtofloat(#s(client.summonarcherallylevel))>2){
      
this.timeout2=random(0.75,1);
      }

      else if(
strtofloat(#s(client.summonarcherallylevel))>=0){
      
this.timeout2=random(1,1.25);
      }


if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>8){
putexplosion2 3,2,x+0.5,y+0.5;destroy();
}
else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>5){
putexplosion2 3,1,x+0.5,y+0.5;destroy();
}
else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>2){
putexplosion2 3,0,x+0.5,y+0.5;destroy();
}
else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>=0){
destroy();
}

if(
this.timeout1<=0.1&& !movementfinished && this.startershot=1){
shootarrow 1;this.startershot=0;
}
if(
this.timeout2<=0.1&&!movementfinished){
shootarrow 1;this.timeout2=random(1,2);
}

if(
wa****){
hearts -= playerswordpower/2;
}

if(
hearts<=0){
move 0,0,0,0;
setcharani classic_dead,;
sleep 3;
lay darts;
destroy();
}

if(
timeout){
this.timeout1-=0.1;
this.timeout2-=0.1;
}

timeout 0.1

Reason why 'working' is in quotes is because since the whole thing is clientsided. So although it appears to work. Other players see the NPC moving in a different direction and whatnot.
Also, the player is supposed to be able to improve the "skill level" of the weapon being the client.summonarcherallylevel variable. However, again, since it's all clientsided, Lets say, if i have a high skill level with it, i fire it, it explodes at the end. my friend nearby won't see the explosion since his client.summonarcherallylevel = 0. But now this also means when he uses it, since my client.summonarcherallylevel > 2, the explosion is on his too. though he doesn't see it.

..Along with the destroy() still being clientsided.
I have 2 other attempts at this. I'm not quite sure which one (if either) is closer to what I need:

PHP Code:

doSpawnArcherAlly(){
  
// Initialize the attributes

  
this.startershot=1;
  
this.timeout1=random(0.05,0.25);

  
showcharacter;
  
dontblock;
  
setcharprop #3,archersummon.png;
  
setcharprop #C0,orange;
  
setcharprop #C1,green;
  
setcharprop #C2,black;
  
setcharprop #C3,green;
  
setcharprop #C4,black;
  
setcharprop #2,no-shield.gif;
  
shieldpower 1;
  
dir 0;
  
hurtdx 0;
  
hurtdy 0;

  
hearts 1+strtofloat(#s(client.summonarcherallylevel))/5;
  
move random(-15,15),random(-15,-20)-strtofloat(#s(client.summonarcherallylevel)),random(1.5,2.5),8;
  
setcharani bowwalk,wbow1.png;
  
     if(
strtofloat(#s(client.summonarcherallylevel))>8){
     
this.timeout2=random(0.25,0.50);
     }
     else if(
strtofloat(#s(client.summonarcherallylevel))>5){
     
this.timeout2=random(0.50,0.75);
     }
     else if(
strtofloat(#s(client.summonarcherallylevel))>2){
     
this.timeout2=random(0.75,1);
     }
     else if(
strtofloat(#s(client.summonarcherallylevel))>=0){
     
this.timeout2=random(1,1.25);
     }
}


  if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>8){
  
putexplosion2 3,2,x+0.5,y+0.5;destroy();
  }
  else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>5){
  
putexplosion2 3,1,x+0.5,y+0.5;destroy();
  }
  else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>2){
  
putexplosion2 3,0,x+0.5,y+0.5;destroy();
  }
  else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>=0){
  
destroy();
  }


  if(
this.timeout1<=0.1&& !movementfinished && this.startershot=1){
  
doArcherShot();this.startershot=0;
  }
  else if(
this.timeout2<=0.1 && !movementfinished){
  
this.timeout2=random(1,2);
  }

  if(
wa****){
  
hearts -= playerswordpower/2;
  }

  if(
hearts<=0){
  
move 0,0,0,0;
  
setcharani dead,;
  
sleep 3;
  
lay darts;
  
destroy();
  }

  function 
onTimeout(){
  
this.timeout1-=0.1;
  
this.timeout2-=0.1;
  }


  
setTimer(0.1);

//#CLIENTSIDE

  
function onCreated(){
  
doSpawnArcherAlly();
  }
  function 
doArcherShot(){
  
shoot x,y,npc.z+1.5,getangle(vecx(dir),vecy(playerdir)),0.75,1.2,arrow,barrow0;
  } 

And

PHP Code:

function moveArcher(){
move random(15,20)+strtofloat(#s(client.summonarcherallylevel)),random(-15,15),random(1.5,2.5),8;
}

function 
destroyArcher(){
   if(
strtofloat(#s(client.summonarcherallylevel))>8){
   
putexplosion2 3,2,x+0.5,y+0.5;
   
destroy();
   }
   else if(
strtofloat(#s(client.summonarcherallylevel))>5){
   
putexplosion2 3,1,x+0.5,y+0.5;
   
destroy();
   }
   else if(
strtofloat(#s(client.summonarcherallylevel))>2){
   
putexplosion2 3,0,x+0.5,y+0.5;
   
destroy();
   }
   else if(
strtofloat(#s(client.summonarcherallylevel))>=0){
   
destroy();
   }
}


//#CLIENTSIDE
if (created) {
  
// Initialize the attributes

  
this.startershot=1;
  
this.timeout1=random(0.05,0.25);

  
showcharacter;dontblock;

  
setcharprop #3,archersummon.png;
  
setcharprop #C0,orange;
  
setcharprop #C1,green;
  
setcharprop #C2,black;
  
setcharprop #C3,green;
  
setcharprop #C4,black;
  
setcharprop #2,no-shield.gif;
  
shieldpower 1;
  
dir 3;
  
hurtdx 0;
  
hurtdy 0;

  
hearts 1+strtofloat(#s(client.summonarcherallylevel))/5;
  
moveArcher();
  
setcharani bowwalk,wbow1.png;
  
   if(
strtofloat(#s(client.summonarcherallylevel))>8){
   
this.timeout2=random(0.25,0.50);
   }
   else if(
strtofloat(#s(client.summonarcherallylevel))>5){
   
this.timeout2=random(0.50,0.75);
   }
   else if(
strtofloat(#s(client.summonarcherallylevel))>2){
   
this.timeout2=random(0.75,1);
   }
   else if(
strtofloat(#s(client.summonarcherallylevel))>=0){
   
this.timeout2=random(1,1.25);
   }
}

if(
movementfinished){
destroyArcher();
}

if(
this.timeout1<=0.1&& !movementfinished && this.startershot=1){
shoot x,y,npc.z+1.5,getangle(vecx(dir),vecy(dir)),0.75,1.2,arrow,barrow0;
this.startershot=0;
}
else if(
this.timeout2<=0.1&&!movementfinished){
shoot x,y,npc.z+1.5,getangle(vecx(dir),vecy(dir)),0.75,1.2,arrow,barrow0;
this.timeout2=random(1,2);
}

if(
wa****){
hearts -= playerswordpower/2;
}
if(
hearts<=0){
move 0,0,0,0;
setcharani dead,;
sleep 3;
lay darts;
destroyArcher();
}

function 
onTimeout(){
this.timeout1-=0.1;this.timeout2-=0.1;
}

timeout(0.1); 

Somewhere in the last few hours, I tried the thing with the triggerserver command on the second one. But when it didn't work, I tried changing it to define a function on one side, then excecute it on the other side. (For some reason, that tends to work sometimes, but not at most other times. And by the way, would it be triggerserver("npc", name, "dropSpawnArcherAlly"); that I would use? instead of "gui" I mean.)

And one more problem is that I don't quite know how to do is turn something like
PHP Code:

  if(this.timeout1<=0.1&& !movementfinished && this.startershot=1){
  
doArcherShot();this.startershot=0;
  } 

into its own function. (If thats what you do anyway)

Sorry for the HUGE post.

Stryke 05-25-2009 09:54 PM

Quote:

Originally Posted by Jiroxys7 (Post 1493907)
And one more problem is that I don't quite know how to do is turn something like
PHP Code:

  if(this.timeout1<=0.1&& !movementfinished && this.startershot=1){
  
doArcherShot();this.startershot=0;
  } 

into its own function. (If thats what you do anyway)

Sorry for the HUGE post.

You can put it in your timeout event.

PHP Code:

if(timeout){ 
this.timeout1-=0.1
this.timeout2-=0.1;
if (
this.timeout1 <= 0.1) {
  
doStuff();
}
}

function 
doStuff() {
  if (!
movementfinished && this.startershot==1) {
    
doArcherShot();
    
this.startershot=0;
  }


Btw, does 'this.startershot=1' even work?
I've always thought you had to use two equal signs when comparing two things but I guess it might've worked in GS1.

You can't define a function on the serverside and expect to call it from the clientside. You have to use triggeraction, so try adding this to the serverside part of your code.

PHP Code:

function onCreated() {
  
setshape(13232);
}

function 
onActionMoveArcher() {
  
//put your code here
}

function 
onActionDestroyArcher() {
  
//put your code here


Now change all instances of moveArcher() to triggeraction(this.x + .5, this.y + .5, "MoveArcher"); on the clientside and do the same for destroyArcher() except change the last parameter to "DestroyArcher".

cbk1994 05-25-2009 11:14 PM

Quote:

Originally Posted by Jiroxys7 (Post 1493907)
And I quickly gave up on testbed since nearly everything players put on there is GS1 or doesnt work or something.

Most good scripters are working on projects, and don't hang around testbed. However, I'm happy to get on some time and help you out. Just let me know when.
Quote:

PHP Code:

//#CLIENTSIDE
function onCreated(){
  
// Initialize the attributes

  
this.startershot=1;
  
this.timeout1=random(0.05,0.25);

  
showcharacter;
  
dontblock;

  
setcharprop #3,archersummon.png;
  
setcharprop #C0,orange;
  
setcharprop #C1,green;
  
setcharprop #C2,black;
  
setcharprop #C3,green;
  
setcharprop #C4,black;
  
setcharprop #2,no-shield.gif;
  
shieldpower 1;
  
dir 1;
  
hurtdx 0;
  
hurtdy 0;

  
hearts 1+strtofloat(#s(client.summonarcherallylevel))/5;
  
move -random(15,20)-strtofloat(#s(client.summonarcherallylevel)),random(-15,15),random(1.5,2.5),8;
  
setcharani bowwalk,wbow1.png;
  
      if(
strtofloat(#s(client.summonarcherallylevel))>8){
      
this.timeout2=random(0.25,0.50);
      }
     
      else if(
strtofloat(#s(client.summonarcherallylevel))>5){
      
this.timeout2=random(0.50,0.75);
      }

      else if(
strtofloat(#s(client.summonarcherallylevel))>2){
      
this.timeout2=random(0.75,1);
      }

      else if(
strtofloat(#s(client.summonarcherallylevel))>=0){
      
this.timeout2=random(1,1.25);
      }


if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>8){
putexplosion2 3,2,x+0.5,y+0.5;destroy();
}
else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>5){
putexplosion2 3,1,x+0.5,y+0.5;destroy();
}
else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>2){
putexplosion2 3,0,x+0.5,y+0.5;destroy();
}
else if(
movementfinished && strtofloat(#s(client.summonarcherallylevel))>=0){
destroy();
}

if(
this.timeout1<=0.1&& !movementfinished && this.startershot=1){
shootarrow 1;this.startershot=0;
}
if(
this.timeout2<=0.1&&!movementfinished){
shootarrow 1;this.timeout2=random(1,2);
}

if(
wa****){
hearts -= playerswordpower/2;
}

if(
hearts<=0){
move 0,0,0,0;
setcharani classic_dead,;
sleep 3;
lay darts;
destroy();
}

if(
timeout){
this.timeout1-=0.1;
this.timeout2-=0.1;
}

timeout 0.1


I'll rescript this, and leave comments for you.

PHP Code:

// we're doing this on serverside, because there's no reason
// to show the character clientside
//
// in the future, for showing characters, try using this
// script to generate them:
// http://forums.graalonline.com/forums/showthread.php?t=82880
function onCreated() {
  
// Initialize the attributes
  
  
this.starterShot 1;
  
this.timeout1 random(0.10.25); // serverside does not support timeouts faster than .1 seconds
  
  
showcharacter();
  
dontblock();
  
  
this.head "archersummon.png";
  
this.colors[0] = "orange";
  
this.colors[1] = "green";
  
this.colors[2] = "black";
  
this.colors[3] = "green";
  
this.colors[4] = "black";
  
  
this.shield "no-shield.png"// png > gif
  
  // shieldpower = 1; does nothing as far as I know, and
  // was only added by Stefan's thing in the level editor
  // because of the scripted baddies he made
  // hurtdx and hurtdy also do nothing as far as I know
  
  
this.dir 1;
  
  
// here's where you're going to hit problems, and you will
  // have to find a way to get around it.
  // 
  // the problem is that, because serverside affects all
  // players, which "player" is being loaded?
  // 
  // however, I'll let you figure out the best way to deal
  // with this
  
  
this.hearts + (client.summonarcherallylevel 5); // no reason to use strtofloat, ever, in GS2
  
  
setCharAni("bowwalk""wbow1.png");
  
  
move((- random(1520) - client.summonarcherallylevel), random((- 15), 15), random(1.52.5), 8);
  
  
// this simplifies your if-else tree a bit
  
  
temp.levels = { // {level, min timeout2, max timeout2}
                  
{8.25.5},
                  {
5.5.75},
                  {
2.751},
                  {(- 
1), 11.25}
                };
  
  for (
temp.lvl levels) { // using 'lvl' instead of 'level' because 'level' refers to 'this.level', which is the level object
    
if (client.summonarcherallylevel lvl[0]) {
      
this.timeout2 random(lvl[1], lvl[2]);
      break; 
// leave the for loop; equivalent to the 'if-else', it ends the tree
    
}
  }
  
  
setTimer(0.1); // this can't be outside of a function block; this replications 'timeout = 0.1'
}
// all things must happen when an event is called;
// before, the script was being scanned to see if
// conditions were met.
//
// now, it looks for an event to call, which is much more
// efficient, and makes more sense
function onMovementFinished() {
  
// not sure why you are destroying the NPC when it finishes
  // moving, anyway... i'll let you fix that if it needs
  // fixing
  
  // simplifying your if-else tree
  
  
temp.levels = {
                  {
82},
                  {
51},
                  {
20},
                  {(- 
1)} // will add a check to make it place no explosions
                
};
  
  for (
temp.lvl levels) {
    if (
client.summonarcherallylevel lvl[0]) {
      if (
lvl[0] > (- 1)) {
        
putexplosion2(3lvl[1], this.0.5this.0.5);
      }
      
      
destroy();
      
// no need to 'break' because destroy is stopping everything
      // and removing the NPC
    
}
  }
}
// keep in mind you need to remove the **** and replace it with
// WasHi.t, removing the period
function onWa****() {
  
this.hearts -= (player.swordpower 2);
}
function 
onTimeOut() {
  if (
this.hearts <= 0) { // this has to be inside a function block
    
move(0000);
    
setCharAni("classic_dead"null);
    
scheduleevent(3"Die"); // using this instead of sleep
    
    
return;
  }
  
  
this.timeout1 -= 0.1;
  
this.timeout2 -= 0.1;
  
  
// there is no reason to use "&& ! movementfinished" because
  // the NPC is destroying when the movement finishes, apparently
  
  
if (this.timeout1 <= 0.1 && this.startershot == 1) {
    
// you MUST use var == val because otherwise you are
    // assigning var to val
    
    
shootarrow(1);
    
this.startershot 0;
  }
  if (
this.timeout2 <= 0.1) {
    
shootarrow(1);
    
this.timeout2 random(12);
  }
  
  
setTimer(0.1); // I think you meant to put this in here
}
function 
onDie() {
  
// using this instead of sleep
  
  
lay("darts");
  
destroy();




All times are GMT +2. The time now is 06:55 PM.

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