/////////////////////////////////////////////////////
/// Daira NPC Script for 2.55 ///
/// v0.2 ///
/// 7th March, 2019 ///
/// ///
/// Original Daira by: Tamamo, and NightmareJames ///
/// This version, by: ZoriaRPG ///
/////////////////////////////////////////////////////
npc script DairaNPC
{
void run()
{
//Original Tile
int OTile = this->OriginalTile;
//Movement Variables
float counter = -1;
int step = this->Step;
int rate = this->Rate;
int homing = this->Homing;
int hunger = this->Hunger;
//Weapon Variables
eweapon wpn;
int damage = this->WeaponDamage;
int attackTimer;
int attackWait; //Time between swings.
bool throw = (this->BFlags[4]); //Behavioural FLag 4
//bool shielded = this->Attributes[0]&4;
int wSprite = this->WeaponSprite; //Ghost_GetAttribute(ghost,1,-1);
//Behavior
while(this->isValid())
{
//Attacking
if(!attackTimer) //Attacks when Link is in Range, and within Line of Sight
{
if ( this->LinkInRange(80) )
{
bool LoS = false;
switch(this->Dir)
{
case DIR_UP:
{
if ( Link->Y > this->Y ) break; //Facing Link
if ( Abs(Link->X - this->X) <= 16 ) LoS = true; break;
}
case DIR_DOWN:
{
if ( Link->Y < this->Y ) break;
if ( Abs(Link->X - this->X) <= 16 ) LoS = true; break;
}
case DIR_LEFT:
{
if ( Link->X > this->X ) break;
if ( Abs(Link->Y - this->Y) <= 16 ) LoS = true; break;
}
case DIR_RIGHT:
{
if ( Link->X < this->X ) break;
if ( Abs(Link->Y - this->Y) <= 16 ) LoS = true; break;
}
default: break;
}
if ( LoS )
{
attackWait--;
if(attackWait<=0)
{
attackTimer = 21;
attackWait = 60;
}
}
}
}
if(attackTimer>0) //Attacking?
{
if(this->OriginalTile == OTile)
{
wpn=Screen->CreateEWeapon(EW_BEAM);
wpn->Dir = Ghost_Dir;
wpn->Step= 200;
wpn->UseSprite(wSprite);
wpn->Damage=damage;
wpn->Angular=false;
wpn->Script = 1; //daira axe
wpn->CSet = this->CSet;
}
else if(!wpn->isValid())
{
this->OriginalTile = OTile;
Waitframe();
attackTimer = 0;
continue;
}
this->OriginalTile = OTile + 20*Div(28-attackTimer, 7);
wpn->Tile = this->OriginalTile+this->Dir+16;
wpn->X = this->X;
wpn->Y = this->Y;
wpn->DeadState = WDS_ALIVE;
if(attackTimer>14)
{
if((this->Dir == DIR_UP || this->Dir == DIR_DOWN))
wpn->Y -= 16;
else wpn->X -= InFrontX(this->Dir, 0);
}
else if(attackTimer>7)
{
if(this->Dir == DIR_UP || this->Dir == DIR_DOWN)
{
if(this->Dir == DIR_UP )
wpn->Y -= 16;
}
else
{
wpn->X += InFrontX(this->Dir, 0);
}
}
else
{
wpn->X += InFrontX(this->Dir,0);
wpn->Y += InFrontY(this->Dir,0);
}
//the weapon hit boxes are small.
SetWpnHitOffsets(wpn, Div(28-attackTimer, 7), this->Dir);
attackTimer--;
}
else if(wpn->isValid())
{
this->OriginalTile = OTile;
if(throw)
{
wpn=Screen->CreateEWeapon(EW_BEAM);
wpn->Dir = Ghost_Dir;
wpn->Step= 200;
wpn->UseSprite(wSprite);
wpn->Damage=damage;
wpn->Angular=false;
wpn->Script = 1; //daira axe
this->OriginalTile = this->OriginalTile + 80 + (this->Dir*4);
}
}
if(this->HP <= 0)
{
wpn->DeadState = WDS_DEAD;
Quit();
}
Waitframe();
}
}
void SetWpnHitOffsets(eweapon wpn, int frame, int dir)
{
//Set Default Collision Properties
wpn->CollDetection = true;
wpn->HitXOffset = 0;
wpn->HitYOffset = 0;
wpn->HitWidth = 16;
wpn->HitHeight = 16;
//Modify it based off attack frame.
switch(frame)
{
case 1:
{
if(dir == DIR_UP || dir == DIR_DOWN)
{
wpn->CollDetection = false;
return;
}
else
wpn->HitWidth = 8;
if(dir == DIR_RIGHT)
wpn->HitXOffset = 8;
break;
}
case 2:
{
if(dir == DIR_UP || dir==DIR_DOWN)
{
wpn->HitHeight = 8;
return;
}
else
wpn->HitWidth = 8;
if(dir == DIR_LEFT)
wpn->HitXOffset = 8;
break;
}
case 3:
{
wpn->HitXOffset = Cond(dir==DIR_LEFT, 8, 0);
wpn->HitYOffset = Cond(dir==DIR_UP, 8, 0);
wpn->HitWidth = Cond(dir==DIR_LEFT||dir==DIR_RIGHT, 8, 16);
wpn->HitHeight = Cond(dir==DIR_UP||dir==DIR_DOWN, 8, 16);
break;
}
default: //Out of range.
{
wpn->DeadState = WDS_DEAD;
return;
}
}
}
}
////////////////////////////////////
/// Axe Weapon Handler For Daira ///
////////////////////////////////////
eweapon script dairaaxe
{
void run()
{
this->X = Clamp(this->X, 1, 255);
this->Y = Clamp(this->Y, 1, 175);
int timer = 22;
while(this->isValid())
{
this->X = Clamp(this->X, 1, 255);
this->Y = Clamp(this->Y, 1, 175);
--timer;
if ( timer < 1 ) { Remove(this); Quit(); }
Waitframe();
}
}
}
Comments