#include "std.zh" /////////////////////// /// GUARDIANS /// /// NPC Script /// /// For ZC 2.55 /// /// v1.0 /// /// 13th Aug., 2019 /// /////////////////////// npc script Guardian { const int LASER_LAYER = 3; const int LASER_COLOUR = 0x04; const int LASER_OPACITY = 128; const int ANGLE_VISION = 60; const int SHOT_STEP = 120; const int COODOWN = 150; const int WTYPE = EW_SCRIPT1; const int SHOT_SFX = 70; void run (int angleOfVision, int shotStep, int shotCooldownTime, int weaponType, int shotSFX, int laserColour) { //Get attributes angleOfVision = (this->InitD[0] > 0 ) ? this->InitD[0] : ANGLE_VISION; shotStep = (this->InitD[1] > 0 ) ? this->InitD[1] : SHOT_STEP; shotCooldownTime = ((this->InitD[2] > 0) ? (this->InitD[2]) : COODOWN); weaponType = (this->InitD[3] > 0 ) ? this->InitD[3] : WTYPE; shotSFX = (this->InitD[4] > 0 ) ? this->InitD[4]: SHOT_SFX; laserColour = (this->InitD[5] > 0 ) ? this->InitD[5]: LASER_COLOUR; int laserStartX; int laserStartY; eweapon beam; while(this->isValid()) { laserStartX = this->X + 8; laserStartY = this->Y + 8; //Shooting if ( shotCooldownTime > 0 ) --shotCooldownTime; //Only one beam at a time else if ( !beam->isValid() ) { //Check angle to Link against angle of vision //If Link is within this angle if ( (Abs((Angle(CenterX(this), CenterY(this), CenterLinkX(), CenterLinkY())) - (Dir4Angle(this->Dir)))) <= angleOfVision/2 ) { shotCooldownTime = (this->InitD[2] > 0 ) ? this->InitD[2] : COODOWN; //can reduce down by reading InitD again -Z laserStartX = CenterX(this); laserStartY = CenterY(this); /*beam = Screen->CreateEWeapon(weaponType); beam->X = laserStartX; beam->Y = laserStartY; beam->Angular = true; beam->Angle = ArcTan(Link->X-beam->X, Link->Y-beam->X); beam->Step = shotStep;*/ beam = FireLaser(weaponType, laserStartX, laserStartY, 0, shotStep, this->WeaponDamage); beam->DrawXOffset = 999; //Draw off-screen Audio->PlaySound(shotSFX); //beam->DrawXOffset = 999; //Draw off-screen } } //Draw laser beam if ( beam->isValid() ) { Screen->Line(LASER_LAYER, laserStartX, laserStartY, CenterX(beam), CenterY(beam), laserColour, 1, 0, 0, 0, LASER_OPACITY); } Waitframe(); } } // Set the weapon's direction based on its angle; // Can also makes weapons unblockable void LaserDir(eweapon wpn) { float angle=wpn->Angle%6.2832; int dir; if(angle<0) angle+=6.2832; if(angle<0.3927 || angle>5.8905) dir=DIR_RIGHT; else if(angle<1.1781) dir=DIR_RIGHTDOWN; else if(angle<1.9635) dir=DIR_DOWN; else if(angle<2.7489) dir=DIR_LEFTDOWN; else if(angle<3.5343) dir=DIR_LEFT; else if(angle<4.3197) dir=DIR_LEFTUP; else if(angle<5.1051) dir=DIR_UP; else dir=DIR_RIGHTUP; wpn->Dir=dir; } eweapon FireLaser(int weaponID, int x, int y, float angle, int step, int damage) { eweapon wpn=Screen->CreateEWeapon(weaponID); wpn->X=x; wpn->Y=y; wpn->Step=step; wpn->Damage=damage; wpn->Angular=true; wpn->Angle=ArcTan(Link->X-x, Link->Y-y)+angle; LaserDir(wpn); return wpn; } }