Graal Forums

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

Gambet 03-18-2010 10:55 PM

GBaddy v.3.0.
 
Read about version one.
Read about version two.

Updates

. Code optimization: Restyled the script to make it more legible, added some new comments, and I added checks for onwater() via the new function:

- checkBlockedTile(xValue, yValue) - boolean - checks if the denoted tile is not walkable

I also added the following function:

- resetIfBaddyGetsStuck() - Automatically called to reset the baddy if it gets stuck on a wall, gets stuck in water, or gets glitched due to things like players pausing in the middle of battle and such.

. Smarter AI: The baddy has a greater chance of healing itself once it's in a weak state (1/3 of its total hp or less). Also, although there are instances where you can put the baddies in a glitched state, they will no longer remain glitched thanks to the newly added resetIfBaddyGetsStuck() function.

Important: As suggested by Jerret (fowlplay4), I added a string in the onCreated() function (this.className) that you can change to whatever name you plan on calling the class so that the script will function properly without needing to change anything else (I didn't bother to add any of the chat stuff that he suggested since it seems like it would be a silly thing to include). Also, you need to remove the period in the middle of: function onWas.Hit().

I don't remember if I changed or added anything else, but this version is much better than the previous ones. It isn't anywhere near perfect, but this is something where I generally just change things around or add things to it, I don't really have much drive to rescript it so look at it as a learning source.

PHP Code:

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

enum {
  
WALK,
  
ATTACK,
  
DEAD
}

function 
onCreated() {
  
this.className "public_gambet_gbaddy"//Change this string to match the name of the class this script is in
  
  
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//The larger the number, the faster the baddy moves
  
this.count int(random(1040));
  
this.start_coordinates = {this.xthis.y};
  
this.mode WALK;
 
  for (
temp.0temp.5temp.a++) 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) { //Baddy walks around the level when no player is within its attack radius
    
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 (
checkBlockedTile(to_add_xto_add_y)) 
        
this.dir = (this.dir 2) % 4;
      else {
        
setcharani("walk""");
        
this.new_x;
        
this.new_y;
      }
    } else {
      
this.count int(random(1040));
      
this.dir = (this.dir int(random(02)) * 2) % 4;
    }
    
    
resetIfBaddyGetsStuck();
  } else if (
this.mode == ATTACK) { //Attack targeted player
    
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 (!
checkBlockedTile(this.check_x+this.add_xthis.check_y+this.add_y)) {
      
damagePlayer();
      
moveBaddy();
    } else if ((!
checkBlockedTile(this.check_x+this.add_xthis.check_y)) || (!checkBlockedTile(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(this.className)) {
          if (
n.mode != ATTACK) { //Check to see if gbaddy being called for help isn't already attacking a player
            
n.mode ATTACK;
            
this.chat "Help!";
            
n.to_check this.plyr;
          }
        }
      }
    }
    
    
resetIfBaddyGetsStuck();
  }
  
  if (
this.mode != DEAD && this.mode != ATTACK) {
    if (
this.to_check.x in |this.x-10this.x+10| && this.to_check.y in |this.y-10this.y+10|) { //Aggro radius - gbaddy will attack a player within this range
      
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;
  }
  
  if (
this.resetTimer != ""this.resetTimer "";


function 
damagePlayer() { //Controls how the gbaddy reacts to the player (the gbaddy either damages the player or heals itself)
  
temp.randomize = (this.health[0] <= (this.health[1] / 3)) ? int(random(80101)) : int(random(0101)); //Greater chance of gbaddy healing itself when weak
  
temp.plyr findPlayer(this.plyr);

  if (
plyr.hearts 0) {
    if (
randomize in |094|) //Attack player with sword
      
setcharani("sword""");
    else if (
randomize in |9498|) //Cause explosion 
      
putexplosion2(33this.xthis.y);
    else if (
randomize in |98101|) { //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) { //The gbaddy can heal itself as one of its possible actions
  
if ((this.health[0] + amount) < this.health[1]) {
    
this.health[0] += amount;
    
this.chat "*Healed for " amount "*";
  } else {
    
this.health[0] = amount;
    
this.chat "*Fully Healed*";
  }
  
  
setcharani("lift""");
  
scheduleevent(1"HideChat""idle");
}

function 
resetIfBaddyGetsStuck() {
  if (
this.checkCoords[0] != this.&& this.checkCoords[1] != this.y) {
    
this.checkCoords = {this.xthis.y};
    
this.resetTimer "";
  } else {
    
this.resetTimer += 1/100;
    if (
this.resetTimer >= 0.4baddyReset();
  }
}

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

function 
onWas.Hit() { //gBaddy is attacked by a player's sword
  
if (this.health[0] - ((player.swordpower 2) + 0.5) > 0) {
    if (
this.ani != "hurt") {
      
setcharani("hurt""");
      
temp.knockbackAmount 3;
      switch(
this.plyr.dir) { //Knockback
        
case "2":
          if (!
checkBlockedTile(this.xthis.y+knockbackAmount)) 
            
this.+= knockbackAmount;
        break;
        case 
"0":
          if (!
checkBlockedTile(this.xthis.y-knockbackAmount))
            
this.-= knockbackAmount;
        break;
        case 
"1":
          if (!
checkBlockedTile(this.x-knockbackAmountthis.y))
            
this.-= knockbackAmount;
        break;
        case 
"3":
          if (!
checkBlockedTile(this.x+knockbackAmountthis.y))        
            
this.+= knockbackAmount;
        break;
      }
      
scheduleevent(1"Counter""");
    }
          
    
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 
checkBlockedTile(xValueyValue) { //Check if tile is not walkable 
  
if (onwall(xValueyValue) || onwater(xValueyValue)) 
    return 
true;
  else 
    return 
false;
}

function 
onRespawn() {
  if (
this.mode == DEAD) {
    
setcharani("idle","");
    
this.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 "";
  }



Enjoy.

jkldogg 03-19-2010 01:33 AM

anyway to make guns hurt the baddy instead of swords?

fowlplay4 03-19-2010 01:40 AM

Quote:

Originally Posted by jkldogg (Post 1563461)
anyway to make guns hurt the baddy instead of swords?

Projectiles that hit it will trigger onActionProjectile(), and depending on the parameters of the projectiles you can have it react accordingly.

Also if the projectile is shot on the server-side it will also trigger onActionSProjectile().

PHP Code:

// NPC was hit by a shoot projectile that originated on the client-side.
function onActionProjectile() {
  
// Handle accordingly
}

// NPC was hit by a shoot projectile that originated on the server-side.
function onActionSProjectile() {
  
// Handle accordingly



DrakilorP2P 03-19-2010 05:45 PM

Quote:

Originally Posted by fowlplay4 (Post 1563463)
Projectiles that hit it will trigger onActionProjectile(), and depending on the parameters of the projectiles you can have it react accordingly.

Also if the projectile is shot on the server-side it will also trigger onActionSProjectile().

PHP Code:

// NPC was hit by a shoot projectile that originated on the client-side.
function onActionProjectile() {
  
// Handle accordingly
}

// NPC was hit by a shoot projectile that originated on the server-side.
function onActionSProjectile() {
  
// Handle accordingly



I think this should be built into the next version.

r3ckless 04-22-2012 04:47 AM

Sorry to revive this, but for some reason the baddy doesn't hurt the player when it uses it's sword? Any idea's on a fix to this?

Again, sorry to reply to such an old thread.

fowlplay4 04-22-2012 04:58 AM

If you use replaceani("sword", "somethingelse"); then "sword" doesn't hurt as an ani anymore.

The script doesn't actually use hitobjects() or anything like that to actually hit the player. You can modify that behavior where it changes it's ani to sword.

r3ckless 04-22-2012 05:11 AM

I figured it out, you need to add "this.swordpower" or the sword won't work properly. Thank you, though. :)


All times are GMT +2. The time now is 02:41 PM.

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