Copy to Clipboard Test

Breath of the Wild Guardian Code

#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;
	}

}