/* ** */ #if defined _FLY_MM_included #endinput #endif #define _FLY_MM_included #include #include #include #include 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(eFlyBase)); myclass.SetBool("bDoNextTick", true); return view_as(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(this.GetInt("iType")); } public set(Fly_Type val) { this.SetInt("iType", view_as(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(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(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(this.GetHandle("lGrabbed_players")); } public set(ArrayList list) { this.SetHandle("lGrabbed_players", list); } } property ArrayList grabbed_players_dead { public get() { return view_as(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(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(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(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(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_base); if(fly.doNextTick) { fly.Tick(); } else { delete fly; } } case eFly: { Fly fly = view_as(fly_base); if(fly.doNextTick) { fly.Tick(); } else { fly.KillFly(); } } case eFlyEnd: { Fly_End fly = view_as(fly_base); if(fly.doNextTick) { fly.Tick(); } else { fly.KillFly(); } } //case eFlyEndHovno: //{ //Fly_End_Hovno fly = view_as(fly_base); //if(fly.doNextTick) //{ // //fly.Tick(); //} //else //{ // //delete fly; //} //} } } return Plugin_Stop; }