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 = {10, 10}; //{Current Health, Maximum Health}
this.mov_speed = 0.45;
this.count = int(random(10, 40));
this.start_coordinates = {this.x, this.y};
this.mode = WALK;
for (a=0; a<5; 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(0, 1000)) @ ".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.x, this.y);
temp.new_x = this.x + vecx(this.dir) * this.mov_speed;
temp.new_y = this.y + 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 + 2 + vecy(this.dir);
if (onwall(to_add_x, to_add_y))
this.dir = (this.dir + 2) PERCENTSIGNHERE 4;
else
{
setcharani("walk", "");
this.x = new_x;
this.y = new_y;
}
}
else
{
this.count = int(random(10, 40));
this.dir = (this.dir + 1 + int(random(0, 2)) * 2) PERCENTSIGNHERE 4;
}
}
else if (this.mode == ATTACK)
{
this.plyr = this.to_check;
this.dist_x = this.plyr.x - this.x;
this.dist_y = this.plyr.y - 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.x + 1.5;
this.check_y = this.y + 2;
if (!onwall(this.check_x + this.add_x, this.check_y + this.add_y))
{
damagePlayer();
moveBaddy();
}
else if ((!onwall(this.check_x + this.add_x, this.check_y)) || (!onwall(this.check_x, this.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 (n: npcs)
{
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-10, this.x+10| && this.to_check.y in |this.y-10, this.y+10|)
{
if (this.mode != ATTACK) this.mode = ATTACK;
}
else
{
this.mode = WALK;
}
}
setTimer(0.1);
}
function moveBaddy()
{
setcharani("walk", "");
this.x += this.add_x * (this.mov_speed + 0.6);
this.y += 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(0, 101));
temp.plyr = findPlayer(this.plyr);
if (plyr.hearts > 0)
{
if (randomize in |0, 92|) //Attack With Sword
setcharani("sword", "");
else if (randomize in |93, 98|) //Cause Explosion
putexplosion2(3, 3, this.x, this.y);
else if (randomize in |99, 101|) //Heal
{
if (this.health[0] < this.health[1])
{
if ((this.health[0] + 5) < this.health[1]) healBaddy(int(random(0, 6)));
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.x = this.start_coordinates[0];
this.y = 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.x, this.y + 3))
this.y+=3;
break;
case "0":
if (!onwall(this.x, this.y - 3))
this.y-=3;
break;
case "1":
if (!onwall(this.x - 3, this.y))
this.x -= 3;
break;
case "3":
if (!onwall(this.x + 3, this.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] > 0) setcharani("sword","");
}
function onHideChat()
{
if (params[0] == "idle")
{
this.chat = "";
setcharani("idle", "");
}
else
{
this.chat = "";
}
}