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