1330 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			1330 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
/*
 | 
						|
**
 | 
						|
*/
 | 
						|
#if defined _FLY_MM_included
 | 
						|
 #endinput
 | 
						|
#endif
 | 
						|
#define _FLY_MM_included
 | 
						|
#include <basic>
 | 
						|
#include <vscripts>
 | 
						|
#include <adt_array>
 | 
						|
#include <float>
 | 
						|
 | 
						|
enum Fly_Type
 | 
						|
{
 | 
						|
	eFlyBase = 0,
 | 
						|
	eFlySmall = 1,
 | 
						|
	eFly = 2,
 | 
						|
	eFlyEnd = 3,
 | 
						|
	eFlyEndHovno = 4
 | 
						|
};
 | 
						|
 | 
						|
float TOASTER_POSITION[] =  { 7063.0, 2329.0, -360.0 };
 | 
						|
 | 
						|
const int t_len = 6;
 | 
						|
float TARGET_NODES[][] = {	
 | 
						|
							{-2400.0, 5136.0, -611.0},
 | 
						|
							{5824.0, 2337.0, -64.0},
 | 
						|
							{3600.0, 4496.0, -256.0},
 | 
						|
							{3456.0, 7680.0, -375.98},
 | 
						|
							{2080.0, 9790.1, -2696.0},
 | 
						|
							{1100.99, 10777.0, -2680.0}
 | 
						|
						};
 | 
						|
 | 
						|
//const int t_len_0 = 6, t_len_1 = 1;
 | 
						|
//float TARGET_NODES2[][][] = {
 | 
						|
					//{	
 | 
						|
						//{5756.0, 4749.0, -390.0},
 | 
						|
						//{6000.0, 2336.0, -288.0},
 | 
						|
						//{3608.0, 4496.0, -472.0},
 | 
						|
						//{3456.0, 7680.0, -375.98},
 | 
						|
						//{2080.0, 9790.1, -2696.0},
 | 
						|
						//{1100.99, 10777.0, -2680.0}
 | 
						|
					//},
 | 
						|
					//{
 | 
						|
						//{895.99, 11192.0, -2216.0},
 | 
						|
						//{0.0, 0.0, 0.0},
 | 
						|
						//{0.0, 0.0, 0.0},
 | 
						|
						//{0.0, 0.0, 0.0},
 | 
						|
						//{0.0, 0.0, 0.0},
 | 
						|
						//{0.0, 0.0, 0.0}
 | 
						|
					//}
 | 
						|
				//};
 | 
						|
 | 
						|
public bool IsValidPlayer(int player)
 | 
						|
{
 | 
						|
	return player >= 1 && player <= 64 && IsValidEntity(player) && IsPlayerAlive(player);
 | 
						|
}
 | 
						|
 | 
						|
methodmap Fly_base < Basic
 | 
						|
{
 | 
						|
	public Fly_base(int entity)
 | 
						|
	{
 | 
						|
		Basic myclass = new Basic();
 | 
						|
		myclass.SetInt("iEntity", entity);
 | 
						|
		myclass.SetFloat("fSpeed", 25.0);
 | 
						|
		myclass.SetFloat("fRotation_speed", 0.05);
 | 
						|
		myclass.SetFloat("fPrevious_distance_to_target", -1.0);
 | 
						|
		myclass.SetFloat("fCurrent_distance_to_target", -1.0);
 | 
						|
		myclass.SetFloat("fBlocker1", 0.0);
 | 
						|
		myclass.SetFloat("fBlocker2", 100.0);
 | 
						|
		myclass.SetFloat("fRot_speed_min", 0.05);
 | 
						|
		myclass.SetFloat("fRot_speed_max", 0.2);
 | 
						|
		myclass.SetFloat("fRot_speed_acceleration", 0.0005);
 | 
						|
		myclass.SetFloat("fRot_err", 0.15);
 | 
						|
		myclass.SetFloat("fSpeed_acceleration", 0.3);
 | 
						|
		myclass.SetFloat("fMax_speed", 50.0);
 | 
						|
		myclass.SetInt("iType", view_as<int>(eFlyBase));
 | 
						|
		myclass.SetBool("bDoNextTick", true);
 | 
						|
		return view_as<Fly_base>(myclass);
 | 
						|
	}
 | 
						|
	
 | 
						|
	property bool doNextTick
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bDoNextTick");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bDoNextTick", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property Fly_Type type
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return view_as<Fly_Type>(this.GetInt("iType"));
 | 
						|
		}
 | 
						|
		public set(Fly_Type val)
 | 
						|
		{
 | 
						|
			this.SetInt("iType", view_as<int>(val));
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float max_speed
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fMax_speed");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fMax_speed", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float speed_acceleration
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fSpeed_acceleration");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fSpeed_acceleration", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float rot_err
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fRot_err");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fRot_err", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float rot_speed_acceleration
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fRot_speed_acceleration");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fRot_speed_acceleration", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float rot_speed_min
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fRot_speed_min");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fRot_speed_min", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float rot_speed_max
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fRot_speed_max");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fRot_speed_max", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float blocker1
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fBlocker1");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fBlocker1", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float blocker2
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fBlocker2");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fBlocker2", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property int entity 
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iEntity");
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float speed 
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fSpeed");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fSpeed", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float rotation_speed 
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fRotation_speed");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fRotation_speed", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float previous_distance_to_target 
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fPrevious_distance_to_target");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fPrevious_distance_to_target", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property float current_distance_to_target
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetFloat("fCurrent_distance_to_target");
 | 
						|
		}
 | 
						|
		public set(float val)
 | 
						|
		{
 | 
						|
			this.SetFloat("fCurrent_distance_to_target", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	public void MoveTowardsTarget(const float[3] fly, const float[3] target)
 | 
						|
	{
 | 
						|
		float targetDir[3];
 | 
						|
		SubtractVectors(target, fly, targetDir);
 | 
						|
		NormalizeVector(targetDir, targetDir);
 | 
						|
		float currentDir[3];
 | 
						|
		GetForwardVector(this.entity, currentDir);
 | 
						|
		float dir[3];
 | 
						|
		GetNewDir(this, targetDir, currentDir, dir);
 | 
						|
		dir[2] = targetDir[2];
 | 
						|
		SetForwardVector(this.entity, dir);
 | 
						|
		MoveForward(this, this.blocker1, this.blocker2);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
methodmap Fly_Small < Fly_base
 | 
						|
{
 | 
						|
	public Fly_Small(int entity)
 | 
						|
	{
 | 
						|
		Fly_base myclass = new Fly_base(entity);
 | 
						|
		myclass.SetBool("bDead", false);
 | 
						|
		myclass.SetInt("iRetarget", 10);
 | 
						|
		myclass.SetInt("iTarget", -1);
 | 
						|
		myclass.type = eFlySmall;
 | 
						|
		return view_as<Fly_Small>(myclass);
 | 
						|
	}
 | 
						|
	
 | 
						|
	property bool dead
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bDead");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bDead", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property int retarget
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iRetarget");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iRetarget", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property int target
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iTarget");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iTarget", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void Start()
 | 
						|
	{
 | 
						|
		
 | 
						|
		float currentAngle[3];
 | 
						|
		GetForwardVector(this.entity, currentAngle);
 | 
						|
		currentAngle[2] = 0.0;
 | 
						|
		SetForwardVector(this.entity, currentAngle);
 | 
						|
		float orig[3];
 | 
						|
		GetOrigin(this.entity, orig);
 | 
						|
		orig[2] += 40.0;
 | 
						|
		SetOrigin(this.entity, orig);
 | 
						|
		
 | 
						|
		CreateTimer(0.0, Tick_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void Tick()
 | 
						|
	{
 | 
						|
		
 | 
						|
		float flyPos[3], flyPos_copy[3];
 | 
						|
		GetOrigin(this.entity, flyPos);
 | 
						|
		GetOrigin(this.entity, flyPos_copy);
 | 
						|
		flyPos_copy[2] -= 300.0;
 | 
						|
		if (this.dead)
 | 
						|
		{
 | 
						|
			float distToFloor = TraceLine(flyPos, flyPos_copy, this.entity);
 | 
						|
			if (distToFloor < 0.03)
 | 
						|
			{
 | 
						|
				
 | 
						|
				EntFireByIndex(this.entity, "SetAnimation", "dead", "0.0", -1);
 | 
						|
				EntFireByIndex(this.entity, "SetAnimation", "dead_loop", "2.0", -1);
 | 
						|
				EntFireByIndex(this.entity, "kill", "", "20.0", -1);
 | 
						|
				delete this;
 | 
						|
				return;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				
 | 
						|
				MoveDir(this, {0.0, 0.0, -1.0});
 | 
						|
			}
 | 
						|
		}
 | 
						|
	
 | 
						|
		/*** Move towards a targetted player ***/
 | 
						|
		else if(IsValidPlayer(this.target))
 | 
						|
		{
 | 
						|
			
 | 
						|
			ChasePlayer(this, flyPos);
 | 
						|
		}
 | 
						|
	
 | 
						|
		/*** Search for a target player ***/
 | 
						|
		else
 | 
						|
		{
 | 
						|
			
 | 
						|
			this.target = GetNewTarget(this);
 | 
						|
			flyPos_copy[2] += 400.0;
 | 
						|
			if (this.target == -1 && TraceLine(flyPos, flyPos_copy, this.entity) >= 1.0)
 | 
						|
			{
 | 
						|
				MoveDir(this, {0.0, 0.0, 1.0});
 | 
						|
			}
 | 
						|
		}
 | 
						|
		CreateTimer(0.0, Tick_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
	}
 | 
						|
	public void Die()
 | 
						|
	{
 | 
						|
		
 | 
						|
		this.dead = true;
 | 
						|
		this.speed = 0.0;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
methodmap Fly < Fly_Small
 | 
						|
{
 | 
						|
	public Fly(int entity)
 | 
						|
	{
 | 
						|
		Fly_Small myclass = new Fly_Small(entity);
 | 
						|
		myclass.type = eFly;
 | 
						|
		myclass.speed = 35.0;
 | 
						|
		myclass.retarget = 8;
 | 
						|
		myclass.blocker1 = 50.0;
 | 
						|
		myclass.blocker2 = 160.0;
 | 
						|
		myclass.rot_speed_min = 0.025;
 | 
						|
		myclass.rot_speed_max = 0.1;
 | 
						|
		myclass.speed_acceleration = 0.25;
 | 
						|
		myclass.max_speed = 85.0;
 | 
						|
		myclass.SetBool("bStarted", false);
 | 
						|
		myclass.SetBool("bGrabbed_player", false);
 | 
						|
		myclass.SetBool("bReturn_to_toaster", false);
 | 
						|
		myclass.SetBool("bSpawn_eggs", false);
 | 
						|
		myclass.SetInt("iHealth", 1000);
 | 
						|
		myclass.SetInt("iPlayers_in_arena", 0);
 | 
						|
		myclass.SetInt("iEggs_currently_spawned", 0);
 | 
						|
		myclass.SetInt("iMax_spawned_eggs", 0);
 | 
						|
		myclass.SetHandle("lGrabbed_players", new ArrayList());
 | 
						|
		myclass.SetHandle("lGrabbed_players_dead", new ArrayList());
 | 
						|
		return view_as<Fly>(myclass);
 | 
						|
	}
 | 
						|
	
 | 
						|
	property bool started
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bStarted");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bStarted", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property bool grabbed_player
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bGrabbed_player");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bGrabbed_player", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property bool return_to_toaster
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bReturn_to_toaster");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bReturn_to_toaster", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property bool spawn_eggs
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bSpawn_eggs");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bSpawn_eggs", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property int health
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iHealth");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iHealth", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property int players_in_arena
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iPlayers_in_arena");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iPlayers_in_arena", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property int eggs_currently_spawned
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iEggs_currently_spawned");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iEggs_currently_spawned", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property int max_spawned_eggs
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iMax_spawned_eggs");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iMax_spawned_eggs", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property ArrayList grabbed_players
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return view_as<ArrayList>(this.GetHandle("lGrabbed_players"));
 | 
						|
		}
 | 
						|
		public set(ArrayList list)
 | 
						|
		{
 | 
						|
			this.SetHandle("lGrabbed_players", list);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property ArrayList grabbed_players_dead
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return view_as<ArrayList>(this.GetHandle("lGrabbed_players_dead"));
 | 
						|
		}
 | 
						|
		public set(ArrayList list)
 | 
						|
		{
 | 
						|
			this.SetHandle("lGrabbed_players_dead", list);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void TeleportGrabbedPlayers(const float[3] position)
 | 
						|
	{
 | 
						|
		for (int i = 0; i < this.grabbed_players.Length; i++)
 | 
						|
		{
 | 
						|
			if (IsValidPlayer(this.grabbed_players.Get(i)))
 | 
						|
			{
 | 
						|
				if(GetClientTeam(this.grabbed_players.Get(i)) == 3)
 | 
						|
					SetOrigin(this.grabbed_players.Get(i), position);
 | 
						|
			}
 | 
						|
		}	
 | 
						|
	}
 | 
						|
	
 | 
						|
	public bool IsValidTarget()
 | 
						|
	{
 | 
						|
		return IsValidPlayer(this.target) && !IsElementInArray(this.target, this.grabbed_players) && !IsElementInArray(this.target, this.grabbed_players_dead);
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void Start()
 | 
						|
	{
 | 
						|
		this.max_spawned_eggs = this.players_in_arena / 6;
 | 
						|
		this.started = true;
 | 
						|
		EntFireByIndex(this.entity, "SetAnimation", "fly", "0.00", -1);
 | 
						|
		CreateTimer(0.0, Tick_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void KillFly()
 | 
						|
	{
 | 
						|
		delete this.grabbed_players_dead;
 | 
						|
		delete this.grabbed_players;
 | 
						|
		delete this;
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void Tick()
 | 
						|
	{
 | 
						|
		float flyPos[3], flyPos_copy[3];
 | 
						|
		GetOrigin(this.entity, flyPos);
 | 
						|
		GetOrigin(this.entity, flyPos_copy);
 | 
						|
		flyPos_copy[2] -= 300.0;
 | 
						|
		float distToFloor = TraceLine(flyPos, flyPos_copy, this.entity);
 | 
						|
		
 | 
						|
		/*****************************/
 | 
						|
		/*** Stuff done every tick ***/
 | 
						|
		/*****************************/
 | 
						|
		
 | 
						|
		/*** Grab a near player ***/
 | 
						|
		int playerNear;
 | 
						|
		float point[3], fwd[3];
 | 
						|
		GetForwardVector(this.entity, fwd);
 | 
						|
		ScaleVector(fwd, 80.0);
 | 
						|
		AddVectors(flyPos, fwd, point);
 | 
						|
		
 | 
						|
		if(!this.dead && (playerNear = FindEntityByClassnameWithin(playerNear, "player", point, 64.0)) != -1)
 | 
						|
		{
 | 
						|
			if(GetClientTeam(playerNear) == 3)
 | 
						|
			{
 | 
						|
				if(!IsElementInArray(playerNear, this.grabbed_players) && !IsElementInArray(playerNear, this.grabbed_players_dead))
 | 
						|
				{
 | 
						|
					this.grabbed_players.Push(playerNear);
 | 
						|
					this.grabbed_players_dead.Push(playerNear);
 | 
						|
		
 | 
						|
					if ((this.target = GetNewTarget(this)) == -1 || !this.IsValidTarget())
 | 
						|
						this.return_to_toaster = true;
 | 
						|
					else if (!this.grabbed_player)
 | 
						|
						CreateTimer(15.0, SetReturn_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
					if (playerNear == this.target)
 | 
						|
						this.target = -1;
 | 
						|
		
 | 
						|
					this.grabbed_player = true;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		/*** Teleport grabbed players ***/
 | 
						|
		if (!this.dead)
 | 
						|
		{
 | 
						|
			flyPos_copy[2] += 260;
 | 
						|
			this.TeleportGrabbedPlayers(flyPos_copy);
 | 
						|
		}
 | 
						|
		
 | 
						|
		/*** Random chance to spawn an egg ***/
 | 
						|
		if (!this.grabbed_player && this.eggs_currently_spawned != this.max_spawned_eggs && GetRandomInt(0, 500) == 0 && distToFloor > 0.1)
 | 
						|
		{
 | 
						|
			this.spawn_eggs = true;
 | 
						|
		}
 | 
						|
	
 | 
						|
		/*************************/
 | 
						|
		/*** Decide what to do ***/
 | 
						|
		/*************************/
 | 
						|
		
 | 
						|
		/*** Fly died - fall to the ground ***/
 | 
						|
		if (this.dead)
 | 
						|
		{
 | 
						|
			
 | 
						|
			if (distToFloor < 0.05)
 | 
						|
			{
 | 
						|
				EntFire("fly_dead", "FireUser1", "", "0.00", -1);
 | 
						|
				EntFire("fly", "Kill", "", "0.02", -1);
 | 
						|
				return;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				MoveDir(this, {0.0, 0.0, -1.0});
 | 
						|
			}
 | 
						|
		}
 | 
						|
		
 | 
						|
		/*** Move to the floor to spawn eggs ***/
 | 
						|
		else if (!this.grabbed_player && this.spawn_eggs && this.eggs_currently_spawned < this.max_spawned_eggs && distToFloor < 1.0 && this.speed < this.max_speed / 2.0)
 | 
						|
		{
 | 
						|
			this.spawn_eggs = false;
 | 
						|
			this.eggs_currently_spawned++;
 | 
						|
			int eggSpawner = GetEntityIndexByHammerID(1248969, "env_entity_maker");
 | 
						|
			TeleportEntity(eggSpawner, flyPos, { 0.0, 0.0, 0.0 }, NULL_VECTOR);
 | 
						|
			AcceptEntityInput(eggSpawner, "ForceSpawn");
 | 
						|
		}
 | 
						|
		
 | 
						|
		/*** Move towards a targetted player ***/
 | 
						|
		else if(!this.return_to_toaster && IsValidPlayer(this.target))
 | 
						|
		{
 | 
						|
			ChasePlayer(this, flyPos);
 | 
						|
		}
 | 
						|
		
 | 
						|
		/*** Take the grabbed player(s) above the toaster ***/
 | 
						|
		else if(this.return_to_toaster)
 | 
						|
		{
 | 
						|
			// Fast approx of distance without needing sqrt
 | 
						|
			this.current_distance_to_target = FloatAbs(TOASTER_POSITION[0] - flyPos[0]) + FloatAbs(TOASTER_POSITION[1] - flyPos[1]);
 | 
						|
			
 | 
						|
			float distToToaster[3]; 
 | 
						|
			SubtractVectors(flyPos, TOASTER_POSITION, distToToaster);
 | 
						|
			if (FloatAbs(distToToaster[0]) < 80.0 && FloatAbs(distToToaster[1]) < 80.0 && FloatAbs(distToToaster[2]) < 80.0)
 | 
						|
			{
 | 
						|
				this.grabbed_player = false;
 | 
						|
				this.return_to_toaster = false;
 | 
						|
				this.grabbed_players.Clear();
 | 
						|
				this.previous_distance_to_target = -1.0;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				this.MoveTowardsTarget(flyPos, TOASTER_POSITION);
 | 
						|
				this.previous_distance_to_target = this.current_distance_to_target;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	
 | 
						|
		/*** Search for a target player ***/
 | 
						|
		else
 | 
						|
		{
 | 
						|
			this.target = GetNewTarget(this);
 | 
						|
			if (!this.IsValidTarget())
 | 
						|
				this.target = -1;
 | 
						|
			flyPos_copy[2] += 140;
 | 
						|
			if (this.target == -1 && TraceLine(flyPos, flyPos_copy, this.entity) >= 1.0)
 | 
						|
				MoveDir(this, { 0.0, 0.0, 1.0 } );
 | 
						|
		}
 | 
						|
		CreateTimer(0.0, Tick_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void SetReturn(bool state)
 | 
						|
	{
 | 
						|
		this.return_to_toaster = state;
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void AddHealth(int hp)
 | 
						|
	{
 | 
						|
		this.health += hp;
 | 
						|
		this.players_in_arena++;
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void Hit()
 | 
						|
	{
 | 
						|
		if (this.started && !this.dead)
 | 
						|
		{
 | 
						|
			this.health--;
 | 
						|
			char param[256];
 | 
						|
			Format(param, sizeof(param), "message Fly %i HP", this.health);
 | 
						|
			EntFire("fly_text", "AddOutput", param, "0.0", -1);
 | 
						|
			EntFire("fly_text", "Display", "", "0.01", -1);
 | 
						|
		}
 | 
						|
		
 | 
						|
		if (this.health == 0 && !this.dead)
 | 
						|
		{
 | 
						|
			EntFire("fly_dead_relay", "Trigger", "", "0.0", -1);
 | 
						|
			this.dead = true;
 | 
						|
			float flyPos[3];
 | 
						|
			GetOrigin(this.entity, flyPos);
 | 
						|
			flyPos[2] += 160.0;
 | 
						|
			this.TeleportGrabbedPlayers(flyPos);	
 | 
						|
			this.grabbed_player = false;
 | 
						|
			this.grabbed_players.Clear();
 | 
						|
			this.speed = 0.0;	
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void IncrementEggCount(int count)
 | 
						|
	{
 | 
						|
		this.eggs_currently_spawned += count;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
public Action SetReturn_Cb(Handle timer, Fly fly)
 | 
						|
{
 | 
						|
	KillTimer(timer);
 | 
						|
	fly.SetReturn(true);
 | 
						|
	return Plugin_Stop;
 | 
						|
}
 | 
						|
 | 
						|
methodmap Fly_End < Fly_base 
 | 
						|
{
 | 
						|
	public Fly_End(int entity)
 | 
						|
	{
 | 
						|
		Fly_base myclass = new Fly_base(entity);
 | 
						|
		myclass.type = eFlyEnd;
 | 
						|
		myclass.blocker1 = 60.0;
 | 
						|
		myclass.blocker2 = 60.0;
 | 
						|
		myclass.rot_speed_max = 0.4;
 | 
						|
		myclass.rot_speed_min = 0.1;
 | 
						|
		myclass.speed_acceleration = 0.25;
 | 
						|
		myclass.max_speed = 85.0;
 | 
						|
		myclass.SetBool("bEnd", false);
 | 
						|
		myclass.SetInt("iCurrent_node", 0);
 | 
						|
		myclass.SetHandle("lGrabbed_players", new ArrayList());
 | 
						|
		myclass.speed = 35.0;
 | 
						|
		return view_as<Fly_End>(myclass);
 | 
						|
	}
 | 
						|
	property bool end 
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bEnd");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bEnd", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property int current_node
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iCurrent_node");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iCurrent_node", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	property ArrayList grabbed_players
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return view_as<ArrayList>(this.GetHandle("lGrabbed_players"));
 | 
						|
		}
 | 
						|
		public set(ArrayList list)
 | 
						|
		{
 | 
						|
			this.SetHandle("lGrabbed_players", list);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	public void TeleportGrabbedPlayers(const float[3] position)
 | 
						|
	{
 | 
						|
		for (int i = 0; i < this.grabbed_players.Length; i++)
 | 
						|
		{
 | 
						|
			if (IsValidPlayer(this.grabbed_players.Get(i)))
 | 
						|
			{
 | 
						|
				if(GetClientTeam(this.grabbed_players.Get(i)) == 3)
 | 
						|
					SetOrigin(this.grabbed_players.Get(i), position);
 | 
						|
			}
 | 
						|
		}	
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void KillFly()
 | 
						|
	{
 | 
						|
		delete this.grabbed_players;
 | 
						|
		delete this;
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void Start()
 | 
						|
	{
 | 
						|
		EntFireByIndex(this.entity, "SetAnimation", "fly", "0.00", -1);
 | 
						|
		CreateTimer(0.0, Tick_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
	}
 | 
						|
	public void Tick()
 | 
						|
	{
 | 
						|
		float flyPos[3], flyPos_copy[3];
 | 
						|
		GetOrigin(this.entity, flyPos);
 | 
						|
		GetOrigin(this.entity, flyPos_copy);
 | 
						|
		float targetNode[3];
 | 
						|
		MakeVectorFromPoints( { 0.0, 0.0, 0.0 }, TARGET_NODES[this.current_node], targetNode);
 | 
						|
		int playerNear;
 | 
						|
		float point[3], fwd[3];
 | 
						|
		GetForwardVector(this.entity, fwd);
 | 
						|
		ScaleVector(fwd, 80.0);
 | 
						|
		AddVectors(flyPos, fwd, point);
 | 
						|
	
 | 
						|
		/*** Kill nearby physboxes ***/
 | 
						|
		int physbox;
 | 
						|
		if ((physbox = FindEntityByClassnameWithin(physbox, "func_physbox", flyPos, 350.0)) != -1)
 | 
						|
		{
 | 
						|
			EntFireByIndex(physbox, "FireUser2", "", "0.00", -1);
 | 
						|
		}
 | 
						|
	
 | 
						|
		/*** Grab a near player ***/
 | 
						|
		if((playerNear = FindEntityByClassnameWithin(playerNear, "player", point, 100.0)) != -1)
 | 
						|
		{	
 | 
						|
			if(GetClientTeam(playerNear) == 3)
 | 
						|
			{
 | 
						|
				if(!IsElementInArray(playerNear, this.grabbed_players))
 | 
						|
				{
 | 
						|
					this.grabbed_players.Push(playerNear);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	
 | 
						|
		if((playerNear = FindEntityByClassnameWithin(playerNear, "player", point, 100.0)) != -1)
 | 
						|
		{	
 | 
						|
			if(GetClientTeam(playerNear) == 3)
 | 
						|
			{
 | 
						|
				if(!IsElementInArray(playerNear, this.grabbed_players))
 | 
						|
				{
 | 
						|
					this.grabbed_players.Push(playerNear);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	
 | 
						|
		/*** Teleport grabbed players ***/
 | 
						|
		flyPos_copy[2] -= 40.0;
 | 
						|
		this.TeleportGrabbedPlayers(flyPos_copy);
 | 
						|
 | 
						|
		/*** Move towards the next node ***/
 | 
						|
		// Fast approx of distance without needing sqrt
 | 
						|
		this.current_distance_to_target = FloatAbs(targetNode[0] - flyPos[0]) + FloatAbs(targetNode[1] - flyPos[1]);
 | 
						|
	
 | 
						|
		float distToTarget[3];
 | 
						|
		SubtractVectors(flyPos, targetNode, distToTarget);
 | 
						|
	
 | 
						|
		if (FloatAbs(distToTarget[0]) < 80.0 && FloatAbs(distToTarget[1]) < 80.0 && FloatAbs(distToTarget[2]) < 80.0)
 | 
						|
		{
 | 
						|
			if (this.current_node < t_len - 1)
 | 
						|
			{
 | 
						|
					this.current_node++;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				EntFireByIndex(this.entity, "SetAnimation", "idle", "0.00", -1);
 | 
						|
				EntFireByIndex(this.entity, "SetAnimation", "attack", "2.00", -1);
 | 
						|
				EntFire("boss_fly_sound_end", "StopSound", "", "0.00", -1);
 | 
						|
				//EntFire("4_fly_hovno", "FireUser1", "", "0.50", -1);
 | 
						|
				//EntFire("5_fly_hovno", "FireUser1", "", "0.50", -1);
 | 
						|
				//EntFire("fly_hovno_sound4", "PlaySound", "", "0.50", -1);
 | 
						|
				//EntFire("fly_hovno_sound5", "PlaySound", "", "0.50", -1);
 | 
						|
				flyPos_copy[2] += 200;
 | 
						|
				this.TeleportGrabbedPlayers(flyPos_copy);
 | 
						|
				this.grabbed_players.Clear();
 | 
						|
				float angles[3];
 | 
						|
				GetForwardVector(this.entity, angles);
 | 
						|
				angles[2] = 0.0;
 | 
						|
				SetForwardVector(this.entity, angles);
 | 
						|
				this.end = true;
 | 
						|
				return;
 | 
						|
			}
 | 
						|
			
 | 
						|
			this.previous_distance_to_target = -1.0;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			this.MoveTowardsTarget(flyPos, targetNode);
 | 
						|
			this.previous_distance_to_target = this.current_distance_to_target;
 | 
						|
		}
 | 
						|
		
 | 
						|
		if (!this.end)
 | 
						|
			CreateTimer(0.0, Tick_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
	}
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
//methodmap Fly_End_Hovno < Fly_End
 | 
						|
//{
 | 
						|
	//public Fly_End_Hovno(int entity)
 | 
						|
	//{
 | 
						|
		//Fly_End myclass = new Fly_End(entity);
 | 
						|
		//myclass.type = eFlyEndHovno;
 | 
						|
		//myclass.rot_speed_acceleration = 0.16;
 | 
						|
		//myclass.rot_speed_max = 0.24;
 | 
						|
		//myclass.rot_speed_min = 0.16;
 | 
						|
		//myclass.max_speed = 120.0;
 | 
						|
		//myclass.speed_acceleration = 0.4;
 | 
						|
		//myclass.SetBool("bStop_on_last_node", true);
 | 
						|
		//myclass.SetInt("iPath", 0);
 | 
						|
		//return view_as<Fly_End_Hovno>(myclass);
 | 
						|
	//}
 | 
						|
	//property bool stop_on_last_node
 | 
						|
	//{
 | 
						|
		//public get()
 | 
						|
		//{
 | 
						|
			//return this.GetBool("bStop_on_last_node");
 | 
						|
		//}
 | 
						|
		//public set(bool val)
 | 
						|
		//{
 | 
						|
			//this.SetBool("bStop_on_last_node", val);
 | 
						|
		//}
 | 
						|
	//}
 | 
						|
	//property int path 
 | 
						|
	//{
 | 
						|
		//public get()
 | 
						|
		//{
 | 
						|
			//return this.GetInt("iPath");
 | 
						|
		//}
 | 
						|
		//public set(int val)
 | 
						|
		//{
 | 
						|
			//this.SetInt("iPath", val);
 | 
						|
		//}
 | 
						|
	//}
 | 
						|
	//public void Start(int p, bool stop)
 | 
						|
	//{
 | 
						|
		//this.path = p;
 | 
						|
		//this.stop_on_last_node = stop;
 | 
						|
		//EntFireByIndex(this.entity, "SetAnimation", "fly", "0.00", -1);
 | 
						|
		//CreateTimer(0.0, Tick_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
	//}
 | 
						|
	//
 | 
						|
	//public void Tick()
 | 
						|
	//{
 | 
						|
		//float flyPos[3], flyPos_copy[3];
 | 
						|
		//GetOrigin(this.entity, flyPos);
 | 
						|
		//GetOrigin(this.entity, flyPos_copy);
 | 
						|
		//float targetNode[3];
 | 
						|
		//MakeVectorFromPoints( { 0.0, 0.0, 0.0 }, TARGET_NODES2[this.path][this.current_node], targetNode);
 | 
						|
		//flyPos_copy[2] -= 40;
 | 
						|
		
 | 
						|
		
 | 
						|
		/*** Teleport grabbed players ***/
 | 
						|
		//this.TeleportGrabbedPlayers(flyPos_copy);
 | 
						|
	
 | 
						|
		/*** Move towards the next node ***/
 | 
						|
		// Fast approx of distance without needing sqrt
 | 
						|
		//this.current_distance_to_target = FloatAbs(targetNode[0] - flyPos[0]) + FloatAbs(targetNode[1] - flyPos[1]);
 | 
						|
		
 | 
						|
		//float distToTarget[3]; 
 | 
						|
		//SubtractVectors(flyPos, targetNode, distToTarget);
 | 
						|
		
 | 
						|
		//if (FloatAbs(distToTarget[0]) < 80.0 && FloatAbs(distToTarget[1]) < 80.0 && FloatAbs(distToTarget[2]) < 80.0)
 | 
						|
		//{
 | 
						|
				//this.previous_distance_to_target = -1.0;
 | 
						|
				//int len = (this.path == 0) ? t_len_0:t_len_1;
 | 
						|
				//if (this.current_node < len - 1)
 | 
						|
				//{
 | 
						|
					//this.current_node++;
 | 
						|
				//}
 | 
						|
				//else if (this.stop_on_last_node)
 | 
						|
				//{
 | 
						|
					//EntFireByIndex(this.entity, "SetAnimation", "idle", "0.00", -1);
 | 
						|
					//flyPos_copy[2] += 200.0;
 | 
						|
					//this.TeleportGrabbedPlayers(flyPos_copy);
 | 
						|
					//float angles[3]; 
 | 
						|
					//GetForwardVector(this.entity, angles);
 | 
						|
					//angles[2] = 0.0;
 | 
						|
					//SetForwardVector(this.entity, angles);
 | 
						|
					//this.end = true;
 | 
						|
					//return;
 | 
						|
				//}
 | 
						|
		//}
 | 
						|
		//if (!this.end)
 | 
						|
		//{
 | 
						|
			//this.MoveTowardsTarget(flyPos, targetNode);
 | 
						|
			//this.previous_distance_to_target = this.current_distance_to_target;	
 | 
						|
			//CreateTimer(0.0, Tick_Cb, this, TIMER_FLAG_NO_MAPCHANGE);
 | 
						|
		//}
 | 
						|
	//}
 | 
						|
//}
 | 
						|
 | 
						|
 | 
						|
public void ChasePlayer(Fly_Small fly, const float[3] flyPos)
 | 
						|
{
 | 
						|
	
 | 
						|
	fly.retarget -= 0.01;
 | 
						|
	float targetPos[3];
 | 
						|
	GetOrigin(fly.target, targetPos);
 | 
						|
	targetPos[2] += 48;
 | 
						|
 | 
						|
	// Fast approx of distance without needing sqrt
 | 
						|
	fly.current_distance_to_target = FloatAbs(targetPos[0] - flyPos[0]) + FloatAbs(targetPos[1] - flyPos[1]);
 | 
						|
	if(fly.retarget <= 0.0 || !IsTargetInSight(fly.entity, flyPos, targetPos))
 | 
						|
	{
 | 
						|
		fly.target = -1;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		fly.MoveTowardsTarget(flyPos, targetPos);
 | 
						|
		fly.previous_distance_to_target = fly.current_distance_to_target;
 | 
						|
	}
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
public bool IsTargetInSight(int entity, const float[3] flyPos, const float[3] targetPos)
 | 
						|
{
 | 
						|
	return TraceLine(flyPos, targetPos, entity) >= 1.0;    
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
public int GetNewTarget(Fly_Small fly)
 | 
						|
{
 | 
						|
	
 | 
						|
	if(!IsValidPlayer(fly.target))
 | 
						|
	{
 | 
						|
		fly.target = -1;
 | 
						|
	}
 | 
						|
	
 | 
						|
	int player = -1;
 | 
						|
	ArrayList playerArr = new ArrayList();
 | 
						|
	
 | 
						|
	while(-1 != (player = FindEntityByClassname(player, "player")))
 | 
						|
	{
 | 
						|
		if(GetClientTeam(player) == 3)
 | 
						|
		{
 | 
						|
			float playerPos[3], selfPos[3];
 | 
						|
			GetOrigin(fly.entity, selfPos);
 | 
						|
			GetOrigin(player, playerPos);
 | 
						|
			playerPos[2] += 48;
 | 
						|
			if(IsTargetInSight(fly.entity, selfPos, playerPos))
 | 
						|
				playerArr.Push(player);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if(playerArr.Length > 0)
 | 
						|
	{
 | 
						|
		fly.retarget = 8;
 | 
						|
		int target = playerArr.Get(GetRandomInt(0, playerArr.Length - 1));
 | 
						|
		delete playerArr;
 | 
						|
		
 | 
						|
		return target;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		delete playerArr;
 | 
						|
		
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
public void MoveForward(Fly_base fly, float blocker1, float blocker2)
 | 
						|
{
 | 
						|
	if(!IsValidEntity(fly.entity))
 | 
						|
		return;
 | 
						|
	
 | 
						|
	float pos1[3], pos2[3], selfPos[3], selfFwd[3];
 | 
						|
	GetOrigin(fly.entity, selfPos);
 | 
						|
	GetForwardVector(fly.entity, selfFwd);
 | 
						|
	ScaleVector(selfFwd, blocker1);
 | 
						|
	AddVectors(selfPos, selfFwd, pos1);
 | 
						|
	GetForwardVector(fly.entity, selfFwd);
 | 
						|
	ScaleVector(selfFwd, blocker2);
 | 
						|
	AddVectors(selfPos, selfFwd, pos2);
 | 
						|
	
 | 
						|
	if (TraceLine(pos1, pos2, fly.entity) < 1.0)
 | 
						|
	{
 | 
						|
		
 | 
						|
		fly.speed = 0.0;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		float newpos[3];
 | 
						|
		GetForwardVector(fly.entity, selfFwd);
 | 
						|
		ScaleVector(selfFwd, fly.speed);
 | 
						|
		AddVectors(selfPos, selfFwd, newpos);
 | 
						|
		SetOrigin(fly.entity, newpos);
 | 
						|
	}
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
public void MoveDir(Fly_base fly, float[3] dir)
 | 
						|
{
 | 
						|
	if(!IsValidEntity(fly.entity))
 | 
						|
		return;
 | 
						|
	
 | 
						|
	if(fly.speed < fly.max_speed) fly.speed += fly.speed_acceleration;
 | 
						|
	float currentAngle[3], origin[3], newpos[3], dir_copy[3];
 | 
						|
	dir_copy[0] = dir[0];
 | 
						|
	dir_copy[1] = dir[1];
 | 
						|
	dir_copy[2] = dir[2];
 | 
						|
	GetForwardVector(fly.entity, currentAngle);
 | 
						|
	currentAngle[2] = 0.0;
 | 
						|
	SetForwardVector(fly.entity, currentAngle);
 | 
						|
	GetOrigin(fly.entity, origin);
 | 
						|
	ScaleVector(dir_copy, fly.speed / 4.0);
 | 
						|
	AddVectors(origin, dir_copy, newpos);
 | 
						|
	SetOrigin(fly.entity, newpos);
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
public void GetNewDir(Fly_base fly, const float[3] targetDir, const float[3] currentDir, float[3] newDir)
 | 
						|
{
 | 
						|
	if(!IsValidEntity(fly.entity))
 | 
						|
		return;
 | 
						|
	
 | 
						|
	float rotDir = currentDir[0] * targetDir[1] - currentDir[1] * targetDir[0];
 | 
						|
	if (FloatAbs(rotDir) > 0.3)
 | 
						|
	{
 | 
						|
		if (fly.speed > 0)
 | 
						|
			fly.speed -= 0.6 * fly.speed_acceleration;
 | 
						|
		if (fly.rotation_speed < fly.rot_speed_max)
 | 
						|
			fly.rotation_speed += fly.rot_speed_acceleration;			
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		if (fly.speed < fly.max_speed)
 | 
						|
			fly.speed += fly.speed_acceleration;
 | 
						|
		if (fly.rotation_speed > fly.rot_speed_min)
 | 
						|
			fly.rotation_speed -= fly.rot_speed_acceleration;
 | 
						|
	}
 | 
						|
	
 | 
						|
	if (rotDir > fly.rot_err || rotDir >= 0 && fly.previous_distance_to_target < fly.current_distance_to_target)
 | 
						|
	{
 | 
						|
		Rotate2D(currentDir, fly.rotation_speed, newDir);
 | 
						|
	}
 | 
						|
	else if (rotDir < -fly.rot_err || rotDir < 0 && fly.previous_distance_to_target < fly.current_distance_to_target)
 | 
						|
	{
 | 
						|
		Rotate2D(currentDir, -fly.rotation_speed, newDir);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		newDir[0] = currentDir[0];
 | 
						|
		newDir[1] = currentDir[1];
 | 
						|
		newDir[2] = currentDir[2];
 | 
						|
	}
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
public void Rotate2D(const float[3] vector, const float angle, float[3] buffer)
 | 
						|
{
 | 
						|
	buffer[0] = vector[0] * Cosine(angle) - vector[1] * Sine(angle);
 | 
						|
	buffer[1] = vector[0] * Sine(angle) + vector[1] * Cosine(angle);
 | 
						|
}
 | 
						|
 | 
						|
public int GetRandomValue(const int max){
 | 
						|
	return GetRandomInt(0, max + 1);
 | 
						|
}
 | 
						|
 | 
						|
public bool IsElementInArray(const any element, const ArrayList arr)
 | 
						|
{
 | 
						|
	for (int i = 0; i < arr.Length; i++)
 | 
						|
	{
 | 
						|
		if (element == arr.Get(i))
 | 
						|
			return true;
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
methodmap Microwave < Basic
 | 
						|
{
 | 
						|
	public Microwave(int entity)
 | 
						|
	{
 | 
						|
		Basic myclass = new Basic();
 | 
						|
		myclass.SetInt("iEntity", entity);
 | 
						|
		myclass.SetBool("bDead", false);
 | 
						|
		myclass.SetBool("bStarted", false);
 | 
						|
		myclass.SetInt("iHealth", 69);
 | 
						|
		return view_as<Microwave>(myclass);
 | 
						|
	}
 | 
						|
	
 | 
						|
	property int entity
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iEntity");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iEntity", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	property bool dead
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bDead");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bDead", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property bool started
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetBool("bStarted");
 | 
						|
		}
 | 
						|
		public set(bool val)
 | 
						|
		{
 | 
						|
			this.SetBool("bStarted", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	property int health
 | 
						|
	{
 | 
						|
		public get()
 | 
						|
		{
 | 
						|
			return this.GetInt("iHealth");
 | 
						|
		}
 | 
						|
		public set(int val)
 | 
						|
		{
 | 
						|
			this.SetInt("iHealth", val);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void Start()
 | 
						|
	{
 | 
						|
		this.started = true;
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void AddHealth(int hp)
 | 
						|
	{
 | 
						|
		this.health += hp;
 | 
						|
	}
 | 
						|
	
 | 
						|
	public void Hit(int hp)
 | 
						|
	{
 | 
						|
		if (this.started && !this.dead)
 | 
						|
		{
 | 
						|
			this.health -= hp;
 | 
						|
			if (this.health < 0)
 | 
						|
			{
 | 
						|
				this.health = 0;
 | 
						|
			}
 | 
						|
			char msg[250];
 | 
						|
			Format(msg, sizeof(msg), "message Microwave %d HP", this.health);
 | 
						|
			EntFire("fly_text", "AddOutput", msg, "0.0", -1);
 | 
						|
			EntFire("fly_text", "Display", "", "0.01", -1);
 | 
						|
		}
 | 
						|
		
 | 
						|
		if (this.health <= 0 && !this.dead)
 | 
						|
		{
 | 
						|
			EntFire("microwave_dead_relay", "Trigger", "", "0.0", -1);
 | 
						|
			this.dead = true;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
public Action Tick_Cb(Handle timer, Fly_base fly_base)
 | 
						|
{
 | 
						|
	KillTimer(timer);
 | 
						|
	if(fly_base)
 | 
						|
	{
 | 
						|
		switch(fly_base.type)
 | 
						|
		{
 | 
						|
			case eFlySmall:
 | 
						|
			{
 | 
						|
				Fly_Small fly = view_as<Fly_Small>(fly_base);
 | 
						|
				if(fly.doNextTick)
 | 
						|
				{
 | 
						|
					
 | 
						|
					fly.Tick();
 | 
						|
				}
 | 
						|
				else 
 | 
						|
				{
 | 
						|
					
 | 
						|
					delete fly;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			case eFly:
 | 
						|
			{
 | 
						|
				Fly fly = view_as<Fly>(fly_base);
 | 
						|
				if(fly.doNextTick)
 | 
						|
				{
 | 
						|
					
 | 
						|
					fly.Tick();
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					
 | 
						|
					fly.KillFly();
 | 
						|
				}
 | 
						|
			}
 | 
						|
			case eFlyEnd:
 | 
						|
			{
 | 
						|
				Fly_End fly = view_as<Fly_End>(fly_base);
 | 
						|
				if(fly.doNextTick)
 | 
						|
				{
 | 
						|
					
 | 
						|
					fly.Tick();
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					
 | 
						|
					fly.KillFly();
 | 
						|
				}
 | 
						|
			}
 | 
						|
			//case eFlyEndHovno:
 | 
						|
			//{
 | 
						|
				//Fly_End_Hovno fly = view_as<Fly_End_Hovno>(fly_base);
 | 
						|
				//if(fly.doNextTick)
 | 
						|
				//{
 | 
						|
					//
 | 
						|
					//fly.Tick();
 | 
						|
				//}
 | 
						|
				//else
 | 
						|
				//{
 | 
						|
					//
 | 
						|
					//delete fly;
 | 
						|
				//}
 | 
						|
			//}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return Plugin_Stop;
 | 
						|
} |