Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   Code Gallery (https://forums.graalonline.com/forums/forumdisplay.php?f=179)
-   -   GBaddy v.2.0 (https://forums.graalonline.com/forums/showthread.php?t=85341)

Gambet 04-27-2009 06:56 AM

GBaddy v.2.0
 
You can find version one here.


Updates

. Code optimization: restyled the entire script to make it more legible (also added new comments and changed around some old), changed some this. vars to temp. vars where they better fit, and I added two new functions:

- healBaddy(amount) - heals the baddy for specified amount
- baddyReset() - resets baddy back to its starting position (automatically done when the baddy kills a player to prevent the player from getting constantly harassed by the baddy)

. Variable-value changes: changed some values such as the baddy's speed, amount of damage taken, and also played with the chance-probability of the baddy either attacking with its sword, causing an explosion, or healing itself

. Smarter AI: when a baddy is low in health, it will cycle through the other NPC's in the level to see if any of them are joined to the "public_gambet_gbaddy" class (which means you must either add this script to a class titled the same, or tweak this portion of the script), and if they are, they will then check to see if the baddies found are currently attacking the same player, if they aren't, then they will call those baddies to help fight the player.


Important: You will need to replace 'PERCENTSIGNHERE' with the actual percent symbol in lines 58 and 69 when uploading because the forums does not allow the posting of percent signs. Also, the function onWas.Hit() will need the period removed.


PHP Code:

/*
 *GBaddy - v.2.0
 *@author Gambet
*/

enum 
{
 
WALK,
 
ATTACK,
 
DEAD
}

function 
onCreated()
{
  
showcharacter();
  
this.bodyimg "body2.png";
  
this.shieldimg "no-shield.png";
  
this.nick "GBaddy";
  
this.ap 0;
  
this.health = {1010}; //{Current Health, Maximum Health}
  
this.mov_speed 0.45;
  
this.count int(random(1040));
  
this.start_coordinates = {this.xthis.y};
  
this.mode WALK;
  
  for (
a=0a<5a++) this.colors[a] = "black";
  if (
this.ani != "idle"setcharani("idle","");
  
  
setTimer(0.1);
}

function 
onPlayerEnters()
{
  
onTimeOut(); //Wake up the NPC (in case it was sleeping due to no players being in the level)
  
this.headimg "head" int(random(01000)) @ ".png"//NPC changes head image each time you enter the level
}

function 
onTimeOut()
{
 if (
players.size() > 0
   
setTimer(0.1);
  else
   
setTimer(0); //Sleep if no players in level
    
 
if (this.mode == WALK)
  {
   
this.to_check findnearestplayer(this.xthis.y);
   
temp.new_x this.vecx(this.dir) * this.mov_speed;
   
temp.new_y this.vecy(this.dir) * this.mov_speed;
   
this.count--;
    
   if (
this.count 0)
    {
      
temp.to_add_x new_x 1.5 vecx(this.dir);
      
temp.to_add_y new_y vecy(this.dir);
      
     if (
onwall(to_add_xto_add_y)) 
      
this.dir = (this.dir 2PERCENTSIGNHERE 4;
     else 
      {
       
setcharani("walk""");
       
this.new_x;
       
this.new_y;
      }
    } 
   else
    {
     
this.count int(random(1040));
     
this.dir = (this.dir int(random(02)) * 2PERCENTSIGNHERE 4;
    }
  }
 else if (
this.mode == ATTACK)
   {
    
this.plyr this.to_check;
    
this.dist_x this.plyr.this.x;
    
this.dist_y this.plyr.this.y;
    
this.len = (this.dist_x this.dist_x this.dist_y this.dist_y) ^ 0.5;
    
this.add_x = (this.dist_x this.len);
    
this.add_y = (this.dist_y this.len);
    
this.check_x this.1.5;
    
this.check_y this.2;    
     
    if (!
onwall(this.check_x this.add_xthis.check_y this.add_y))
     {
      
damagePlayer();
      
moveBaddy();
     } 
    else if ((!
onwall(this.check_x this.add_xthis.check_y)) || (!onwall(this.check_xthis.check_y this.add_y))) 
     {
      
damagePlayer();
     }
    if ((
this.health[1] / 3) >= this.health[0]) //If low on health and other gbaddies in level, call for help
     
{
      for (
nnpcs)
       {
        if (
n.isinclass("public_gambet_gbaddy"))
         {
          if (
n.mode != ATTACK//Check to see if gbaddy isn't already attacking player
           
{
            
this.chat "Help!";
            
n.to_check this.plyr;
            
n.mode ATTACK;
           }
         }
       }
     }
   }
 if (
this.mode != DEAD)
  {
   if (
this.to_check.x in |this.x-10this.x+10| && this.to_check.y in |this.y-10this.y+10|)
    {
     if (
this.mode != ATTACKthis.mode ATTACK;
    } 
   else
    {
     
this.mode WALK;
    }
  }
  
 
setTimer(0.1); 
}

function 
moveBaddy()
{
 
setcharani("walk""");
 
this.+= this.add_x * (this.mov_speed 0.6);
 
this.+= this.add_y * (this.mov_speed 0.6);

 if (
abs(this.dist_x) > abs(this.dist_y)) 
  {
   if (
this.dist_x 0
     
this.dir 3
    else 
     
this.dir 1;
  }
 else 
  {
   if (
this.dist_y 0
     
this.dir 2
    else 
     
this.dir 0;
  }


function 
damagePlayer()
{
 
temp.randomize int(random(0101));
 
temp.plyr findPlayer(this.plyr);

 if (
plyr.hearts 0)
  {
   if (
randomize in |092|) //Attack With Sword
     
setcharani("sword""");
   else if (
randomize in |9398|) //Cause Explosion
     
putexplosion2(33this.xthis.y);
   else if (
randomize in |99101|) //Heal
    
{
     if (
this.health[0] < this.health[1])
      {
       if ((
this.health[0] + 5) < this.health[1]) healBaddy(int(random(06)));
       else if ((
this.health[0] + 5) >= this.health[1]) healBaddy(this.health[1]);
      }
    }
  }
 else
  {
   
baddyReset();
  }


function 
healBaddy(amount)
{
 if ((
this.health[0] + amount) < this.health[1])
  {
   
this.health[0] += amount;
   
this.chat "*Healed for " amount "*";
  }
 else
  {
   
this.health[0] = this.health[1];
   
this.chat "*Fully Healed*";
  }
  
 
setcharani("lift""");
 
scheduleevent(1"HideChat""idle");
}

function 
baddyReset()
{
 
this.this.start_coordinates[0];
 
this.this.start_coordinates[1];
 
this.health[0] = this.health[1];
 
this.mode WALK;
}

function 
onWas.Hit() 
{
 if (
this.health[0] - ((player.swordpower 2) + 0.5) > 0)
  {
    if (
this.ani != "hurt")
     {
      
setcharani("hurt""");
      
scheduleevent(1"Counter""");
     }
     
    switch(
this.plyr.dir//Knockback
     
{
      case 
"2":
       if (!
onwall(this.xthis.3)) 
         
this.y+=3;
       break;
      case 
"0":
       if (!
onwall(this.xthis.3))
         
this.y-=3;
       break;
      case 
"1":
       if (!
onwall(this.3this.y))
         
this.-= 3;
       break;
      case 
"3":
       if (!
onwall(this.3this.y))        
         
this.x+=3;
       break;
     }
     
   
this.health[0] -= (player.swordpower 2) + 0.5;
   
this.chat this.health[0] @ "/" this.health[1];
   
scheduleevent(2"HideChat""");
  } 
 else
  {
   if (
this.mode != DEAD)
    {
     
this.mode DEAD;
     
this.health[0] = 0;
     
setcharani("dead""");
     
this.chat this.health[0] @ "/" this.health[1];
     
scheduleevent(8"Respawn""");
    }
  }
}

function 
onRespawn()
{
 if (
this.mode == DEAD)
  {
   
setcharani("idle","");
   
chat "";
   
this.health[0] = this.health[1];
   
this.mode WALK;
  }
}

function 
onCounter()
{
 if (
this.health[0] > 0setcharani("sword","");
}

function 
onHideChat()
{
 if (
params[0] == "idle")
  {
   
this.chat "";
   
setcharani("idle""");
  } 
 else 
  {
   
this.chat "";
  }



napo_p2p 04-27-2009 07:10 AM

Good stuff, as always :).

Also, if you want to include an actual %, you can use this "percent transform." It's a funky way of posting percent signs, but they just wont fix it...

Gambet 04-27-2009 07:17 AM

Quote:

Originally Posted by napo_p2p (Post 1487113)
Good stuff, as always :).

Also, if you want to include an actual, you can use this "percent transform." It's a funky way of posting percent signs, but they just wont fix it...


I just tried editing my original post with that and I still got that bad request error (I'm using the new Internet Explorer 8 Beta - I have Firefox as well, but I've been testing around the new I.E.), not sure if my browser has anything to do with it but I actually had to write this thread twice because of the percent problem.

The first time that I wrote this thread I had completely forgotten about the percent problem and I lost everything that I wrote, I even tried using the back button on my browser but all of the information was lost through the bad request. I made sure not to make the same mistake twice. >_<

Thanks for the link, though, it's just really annoying to have to go through all this trouble.

zephirot 04-27-2009 07:04 PM

Nice.
Is there any way to try out GS2 scripts offline? (I don't have access to any server)

napo_p2p 04-27-2009 07:19 PM

Quote:

Originally Posted by zephirot (Post 1487164)
Nice.
Is there any way to try out GS2 scripts offline? (I don't have access to any server)

No, but you could get access to the 'Testbed Server'. The Testbed Server is enabled for classic accounts and is meant for people who need a place to test out their scripts.

zephirot 04-27-2009 07:34 PM

Quote:

Originally Posted by napo_p2p (Post 1487168)
No, but you could get access to the 'Testbed Server'. The Testbed Server is enabled for classic accounts and is meant for people who need a place to test out their scripts.

Oh I see, but I'm not a scripter myself, I just like to **** around with other peoples creations.

Rufus 04-27-2009 11:51 PM

Would it be possible for you to record a video of your baddy functioning with the things that you've described? I'd be interested to see it, and don't really have a server I could just throw it on and test it.

Gambet 04-28-2009 01:00 AM

1 Attachment(s)
I added an attachment that contains an avi file straight from my videos folder of the GBaddy in action (more or less since I was lagging a bit due to my connection being split at the moment). I've never before used the video capturing feature that the new Graal version has, so my apologies if it's small or whatnot since I don't really know how to make it bigger.

Although you can't really tell from the video due to the small resolution, the baddies do walk around the level if there is no player within their attack radius.

Pelikano 04-28-2009 12:01 PM

Quote:

Originally Posted by Rufus (Post 1487220)
Would it be possible for you to record a video of your baddy functioning with the things that you've described? I'd be interested to see it, and don't really have a server I could just throw it on and test it.

Testbed o_O?

Deas_Voice 04-28-2009 06:55 PM

nice work, and if u forget where the percent transform is, i have it in my sig.

Chompy 04-28-2009 06:59 PM

Quote:

Originally Posted by Deas_Voice (Post 1487430)
nice work, and if u forget where the percent transform is, i have it in my sig.

I prefer the Greasemonkey script :)

Bell 04-28-2009 09:06 PM

Quote:

Originally Posted by Pelikano (Post 1487365)
Testbed o_O?

http://forums.graalonline.com/forums...hlight=testbed

Its up of course. Just forum pm Tigairius about it if you have any questions.

fowlplay4 04-28-2009 10:39 PM

Looks like fun!

Suggestionssss

It should victory dance when it kills! As well as taunt, and when he is aggro'd.

Could have a setup in the onCreated()

this.vocals_taunt = "y so bad";
this.vocals_victory = "come back when u r not suck";
this.vocals_aggrod = "cum get summmmm";
this.victorygani = "dance";

Also where you have the whole isinclass("public_gambet_gbaddy");
Could use a onCreated string as well.

this.classname = "public_gambet_gbaddy";

So anyone who uses it can use a different class name and figure out to change that right away.

Possibly tweak so it can use a longer timer instead of 0.1, however I don't think this is that important depending on how widespread it becomes.

The above should be worthy of a 2.1 release ;) rep++

maximus_asinus 04-28-2009 10:43 PM

My only complaint is that it basically runs into your sword a number of times before it attacks you back.

Deas_Voice 04-29-2009 04:54 PM

Quote:

Originally Posted by Chompy (Post 1487431)
I prefer the Greasemonkey script :)

>:0
tell gimmeh the script!
i nvr been good at greasemonkey..

devilsknite1 09-12-2010 08:27 PM

Not meaning to revive this thread, but out of curiosity, why does this baddy not move unless on the default pics1.png tileset? I tested this on a type 1 tileset and the baddy would not move. With the same code, I tried it on the default tileset, it worked fine. I also have a custom HP system in play. When the baddy attacks the player, it subtracts from player.hearts, not the clientr var I set it to. wutdo?

xXziroXx 09-12-2010 08:29 PM

Quote:

Originally Posted by devilsknite1 (Post 1600414)
Not meaning to revive this thread, but out of curiosity, why does this baddy not move unless on the default pics1.png tileset? I tested this on a type 1 tileset and the baddy would not move. With the same code, I tried it on the default tileset, it worked fine. I also have a custom HP system in play. When the baddy attacks the player, it subtracts from player.hearts, not the clientr var I set it to. wutdo?

The script does not recognize the levels tiletype unless you add the level to serveroptions like this:

PHP Code:

newtilesetlevels=mal_blobbowl.nw,exampleheader_ 


cbk1994 09-12-2010 09:08 PM

You can also do newtilesets=true if your entire server uses a type 1 tileset.

devilsknite1 09-15-2010 11:18 PM

Quote:

Originally Posted by cbk1994 (Post 1600421)
You can also do newtilesets=true if your entire server uses a type 1 tileset.

Quote:

Originally Posted by xXziroXx (Post 1600415)
The script does not recognize the levels tiletype unless you add the level to serveroptions like this:

PHP Code:

newtilesetlevels=mal_blobbowl.nw,exampleheader_ 


Thanks to both of you! :D
Now it still subtracts from player.hearts, when that's not defined anywhere... Any ideas?

cbk1994 09-15-2010 11:24 PM

Quote:

Originally Posted by devilsknite1 (Post 1600947)
Thanks to both of you! :D
Now it still subtracts from player.hearts, when that's not defined anywhere... Any ideas?

Classic hit detection is a bit peculiar. It loops through all GANIs in the level and looks for the "sword" gani, and if it's present and in position to hit the player, the player's hearts are subtracted.

The easiest solution is just to make a new GANI named "myserver_sword.gani" (which is a clone of sword.gani) and use this in place of "sword".

fowlplay4 09-16-2010 06:39 AM

Quote:

Originally Posted by cbk1994 (Post 1600950)
The easiest solution is just to make a new GANI named "myserver_sword.gani" (which is a clone of sword.gani) and use this in place of "sword".

I imagine replaceani("sword", "reallyobscureswordgani"); would do the trick as well. (Ez Classic Spar God Mode?)

I remember at one point doing: replaceani("sword", "idle"); caused NPCs to 'attack' you if you touched them that was a good laugh.

Gambet 09-16-2010 06:41 AM

I released version 3 of the GBaddy not that long ago (you can find it here). Just figure I'd point that out in case you didn't notice since you should be using the most recent version of the script before changing it around.

As for wanting the baddy to work with custom systems, you would have to make alterations to the damagePlayer() function (particularly the setcharani("sword", ""); line). You can place your custom health variable under that line and it should deduct straight from it but the system will still remove from player.hearts due to the baddy using sword.gani, so you'll need to address that. The onCounter() event also uses a setcharani("sword", ""); line so keep that in mind as well.

Edit: Looking back at it, the script as a whole could use a complete overhaul (especially with there being a lot of redundancy), but investing anymore time in it would be a waste; nonetheless, it's complete enough for what it's worth--a learning tool to help get you started, not something to be used on a server without major modifications.


All times are GMT +2. The time now is 04:58 AM.

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