sm-plugins/VScripts/scripting/include/vscripts/Fly.inc
2020-08-24 11:49:13 +02:00

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