From 70683dc46a56e94ac804afe2c36d413cd4765fa9 Mon Sep 17 00:00:00 2001 From: Batfoxkid Date: Tue, 19 Nov 2024 11:51:23 -0800 Subject: [PATCH 1/4] Early Christmas --- addons/sourcemod/scripting/saxtonhale.sp | 2 + .../vsh/abilities/ability_rage_meteor.sp | 220 ++++++++++++++++++ .../scripting/vsh/bosses/boss_yeti.sp | 54 +++-- 3 files changed, 254 insertions(+), 22 deletions(-) create mode 100644 addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp diff --git a/addons/sourcemod/scripting/saxtonhale.sp b/addons/sourcemod/scripting/saxtonhale.sp index 6de3357d..52851c4a 100644 --- a/addons/sourcemod/scripting/saxtonhale.sp +++ b/addons/sourcemod/scripting/saxtonhale.sp @@ -377,6 +377,7 @@ ConVar tf_arena_preround_time; #include "vsh/abilities/ability_rage_gas.sp" #include "vsh/abilities/ability_rage_ghost.sp" #include "vsh/abilities/ability_rage_light.sp" +#include "vsh/abilities/ability_rage_meteor.sp" #include "vsh/abilities/ability_rage_scare.sp" #include "vsh/abilities/ability_teleport_swap.sp" #include "vsh/abilities/ability_teleport_view.sp" @@ -710,6 +711,7 @@ public void OnPluginStart() SaxtonHale_RegisterClass("RageGas", VSHClassType_Ability); SaxtonHale_RegisterClass("RageGhost", VSHClassType_Ability); SaxtonHale_RegisterClass("LightRage", VSHClassType_Ability); + SaxtonHale_RegisterClass("RageMeteor", VSHClassType_Ability); SaxtonHale_RegisterClass("ScareRage", VSHClassType_Ability); SaxtonHale_RegisterClass("TeleportSwap", VSHClassType_Ability); SaxtonHale_RegisterClass("TeleportView", VSHClassType_Ability); diff --git a/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp b/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp new file mode 100644 index 00000000..e49d290b --- /dev/null +++ b/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp @@ -0,0 +1,220 @@ +// Inspired by ff2_sarysamods4's Meteor Shower ability + +static const char g_sRocketModels[][] = +{ + "models/props_wasteland/rockgranite03a.mdl", + "models/props_wasteland/rockgranite03b.mdl", + "models/props_wasteland/rockgranite03c.mdl" +}; + +static Handle g_hFreezeTimer[MAXPLAYERS]; +static int g_iRocketCount[MAXPLAYERS]; +static float g_flNextRocketIn[MAXPLAYERS]; +static int g_iRocketModels[3]; + +public void RageMeteor_Precache(SaxtonHaleBase boss) +{ + PrecacheSound(FREEZE_SOUND); + + for (int i = 0; i < sizeof(g_sRocketModels); i++) + { + g_iRocketModels[i] = PrecacheModel(g_sRocketModels[i]); + } +} + +public void RageMeteor_Create(SaxtonHaleBase boss) +{ + g_iRocketCount[boss.iClient] = 0; + g_flNextRocketIn[boss.iClient] = 0.0; + + boss.SetPropFloat("RageMeteor", "Damage", 50.0); + boss.SetPropFloat("RageMeteor", "Speed", 550.0); + boss.SetPropFloat("RageMeteor", "SpawnRadius", 800.0); + boss.SetPropFloat("RageMeteor", "MinAngle", 45.0); + boss.SetPropFloat("RageMeteor", "FreezeTime", 4.0); + boss.SetPropFloat("RageMeteor", "SpawnDelay", 0.094); + boss.SetPropFloat("RageMeteor", "SpawnDelaySuper", 0.077); + boss.SetPropInt("RageMeteor", "SpawnCount", 70); + boss.SetPropInt("RageMeteor", "SpawnCountSuper", 130); +} + +public void RageMeteor_OnRage(SaxtonHaleBase boss) +{ + g_iRocketCount[boss.iClient] = boss.GetPropInt("RageMeteor", boss.bSuperRage ? "SpawnCountSuper" : "SpawnCount"); + g_flNextRocketIn[boss.iClient] = GetGameTime(); +} + +public void RageMeteor_OnThink(SaxtonHaleBase boss) +{ + if (g_iRocketCount[boss.iClient] == 0) + return; + + float flGameTime = GetGameTime(); + if (g_flNextRocketIn[boss.iClient] < flGameTime) + { + g_flNextRocketIn[boss.iClient] += boss.GetPropFloat("RageMeteor", boss.bSuperRage ? "SpawnDelaySuper" : "SpawnDelay"); + g_iRocketCount[boss.iClient]--; + SpawnRocket(boss); + } +} + +public Action RageMeteor_OnTakeDamage(SaxtonHaleBase boss, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + if (boss.iClient == attacker && IsValidEntity(inflictor)) + { + char sClassname[36]; + GetEntityClassname(inflictor, sClassname, sizeof(sClassname)); + + if (strcmp(sClassname, "tf_projectile_rocket") == 0) + { + return Plugin_Handled; + } + } + + return Plugin_Continue; + +} + +public Action RageMeteor_OnAttackDamage(SaxtonHaleBase boss, int victim, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + if (IsValidEntity(inflictor)) + { + char sClassname[36]; + GetEntityClassname(inflictor, sClassname, sizeof(sClassname)); + + if (strcmp(sClassname, "tf_projectile_rocket") == 0) + { + float flDuration = boss.GetPropFloat("RageMeteor", "FreezeTime"); + if (flDuration > 0.0) + { + if (!g_hFreezeTimer[victim]) + { + float vecOrigin[3]; + GetClientAbsOrigin(victim, vecOrigin); + TF2_SpawnParticle(FREEZE_PARTICLE_01, vecOrigin); + TF2_SpawnParticle(FREEZE_PARTICLE_02, vecOrigin); + TF2_SpawnParticle(FREEZE_PARTICLE_03, vecOrigin); + EmitAmbientSound(FREEZE_SOUND, vecOrigin); + + SetEntityRenderColor(victim, 128, 176, 255, 255); + SetEntityMoveType(victim, MOVETYPE_NONE); + } + + TF2_StunPlayer(victim, flDuration, 1.0, TF_STUNFLAG_SLOWDOWN); + + delete g_hFreezeTimer[victim]; + + DataPack pack; + g_hFreezeTimer[victim] = CreateDataTimer(flDuration, Timer_UnfreezeVictim, pack); + pack.WriteCell(victim); + pack.WriteCell(GetClientUserId(victim)); + } + } + } + + return Plugin_Continue; +} + +public void RageMeteor_OnPlayerKilled(SaxtonHaleBase boss, Event event, int iVictim) +{ + if(g_hFreezeTimer[iVictim]) + TriggerTimer(g_hFreezeTimer[iVictim]); +} + +static Action Timer_UnfreezeVictim(Handle hTimer, DataPack pack) +{ + pack.Reset(); + int iClient = pack.ReadCell(); + if (iClient == GetClientOfUserId(pack.ReadCell())) + { + SetEntityMoveType(iClient, MOVETYPE_WALK); + SetEntityRenderColor(iClient, 255, 255, 255, 255); + + float vecOrigin[3]; + GetClientAbsOrigin(iClient, vecOrigin); + EmitAmbientSound(UNFREEZE_SOUND, vecOrigin); + } + + g_hFreezeTimer[iClient] = null; + return Plugin_Continue; +} + +static void SpawnRocket(SaxtonHaleBase boss) +{ + float vecBossOrigin[3]; + GetEntPropVector(boss.iClient, Prop_Send, "m_vecOrigin", vecBossOrigin); + vecBossOrigin[2] += 41.5; + + // Find any valid spots + float vecSpawnPos[3], vecAngles[3]; + float radius = boss.GetPropFloat("RageMeteor", "SpawnRadius"); + bool foundValidPoint = false; + for (int a = 0; a < 5; a++) + { + vecAngles[1] = GetRandomFloat(-179.9, 179.9); + float minDistance = GetRandomFloat(0.0, radius); + for (int b = 0; b < 3; b++) + { + static const float Angles[] = { 0.0, 25.0, -25.0 }; + vecAngles[0] = Angles[b]; + + Handle trace = TR_TraceRayFilterEx(vecBossOrigin, vecAngles, (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_GRATE), RayType_Infinite, TraceRay_HitWallOnly); + TR_GetEndPosition(vecSpawnPos, trace); + delete trace; + + float traceDistance = GetVectorDistance(vecBossOrigin, vecSpawnPos); + if (traceDistance >= minDistance) + { + foundValidPoint = true; + ConstrainDistance(vecBossOrigin, vecSpawnPos, traceDistance, minDistance); + break; // TODO: Test add this + } + } + + if (foundValidPoint) + break; + } + + // Failed to spawn, close quarters area (usually would get nuked anyways) + if (!foundValidPoint) + return; + + // Spawn close to the ceiling + vecAngles[0] = -89.9; + Handle trace = TR_TraceRayFilterEx(vecSpawnPos, vecAngles, (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_GRATE), RayType_Infinite, TraceRay_HitWallOnly); + TR_GetEndPosition(vecSpawnPos, trace); + delete trace; + vecSpawnPos[2] -= 20.0; + + // TOO high up + if(vecSpawnPos[2] > (vecBossOrigin[2] + 1500.0)) + vecSpawnPos[2] = vecBossOrigin[2] + 1500.0; + + vecAngles[0] = GetRandomFloat(boss.GetPropFloat("RageMeteor", "MinAngle"), 89.9); + vecAngles[1] = GetRandomFloat(-179.9, 179.9); + vecAngles[2] = 0.0; + + float vecVelocity[3]; + GetAngleVectors(vecAngles, vecVelocity, NULL_VECTOR, NULL_VECTOR); + ScaleVector(vecVelocity, boss.GetPropFloat("RageMeteor", "Speed")); + + int rocket = CreateEntityByName("tf_projectile_rocket"); + TeleportEntity(rocket, vecSpawnPos, vecAngles, vecVelocity); + SetEntDataFloat(rocket, FindSendPropInfo("CTFProjectile_Rocket", "m_iDeflected") + 4, boss.GetPropFloat("RageMeteor", "Damage"), true); + SetEntProp(rocket, Prop_Send, "m_nSkin", GetClientTeam(boss.iClient) - 2); + SetEntPropEnt(rocket, Prop_Send, "m_hOwnerEntity", boss.iClient); + SetEntProp(rocket, Prop_Send, "m_iTeamNum", GetClientTeam(boss.iClient)); + DispatchSpawn(rocket); + + // Use any weapon attributes + SetEntPropEnt(rocket, Prop_Send, "m_hOriginalLauncher", GetPlayerWeaponSlot(boss.iClient, TFWeaponSlot_Melee)); + SetEntPropEnt(rocket, Prop_Send, "m_hLauncher", GetPlayerWeaponSlot(boss.iClient, TFWeaponSlot_Melee)); + + // Set the model without hitbox changing + SetEntProp(rocket, Prop_Send, "m_nModelIndex", g_iRocketModels[GetURandomInt() % sizeof(g_iRocketModels)]); + SetEntityRenderMode(rocket, RENDER_TRANSCOLOR); + SetEntityRenderColor(rocket, 200, 255, 255, 200); + + // Dies when the rocket dies + TF2_SpawnParticle("coin_large_blue", vecSpawnPos, .iEntity = rocket); +} diff --git a/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp b/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp index 8a33b54a..57d0e0d4 100644 --- a/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp +++ b/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp @@ -45,14 +45,7 @@ static char g_strYetiFootsteps[][] = { public void Yeti_Create(SaxtonHaleBase boss) { boss.CreateClass("BraveJump"); - boss.CreateClass("GroundPound"); - boss.CreateClass("RageFreeze"); - - //CRageAddCond should last as long as slow + freeze - boss.CreateClass("RageAddCond"); - RageAddCond_AddCond(boss, TFCond_RuneHaste); - boss.SetPropFloat("RageAddCond", "RageCondDuration", boss.GetPropFloat("RageFreeze", "SlowDuration") + boss.GetPropFloat("RageFreeze", "FreezeDuration")); - boss.SetPropFloat("RageAddCond", "RageCondSuperRageMultiplier", boss.GetPropFloat("RageFreeze", "RageFreezeSuperRageMultiplier")); + boss.CreateClass("RageMeteor"); boss.iHealthPerPlayer = 650; boss.flHealthExponential = 1.05; @@ -67,26 +60,26 @@ public void Yeti_GetBossName(SaxtonHaleBase boss, char[] sName, int length) public void Yeti_GetBossInfo(SaxtonHaleBase boss, char[] sInfo, int length) { - StrCat(sInfo, length, "\nHealth: High"); + StrCat(sInfo, length, "\nHealth: Medium"); StrCat(sInfo, length, "\n "); StrCat(sInfo, length, "\nAbilities"); StrCat(sInfo, length, "\n- Brave Jump"); - StrCat(sInfo, length, "\n- Ground Pound (Passive)"); StrCat(sInfo, length, "\n "); StrCat(sInfo, length, "\nRage"); StrCat(sInfo, length, "\n- Damage requirement: 2500"); - StrCat(sInfo, length, "\n- Slows players at medium range for 3 seconds"); - StrCat(sInfo, length, "\n- Affected players get frozen for 4 seconds"); - StrCat(sInfo, length, "\n- 200%% Rage: Extended range and freeze duration increased to 6 seconds"); + StrCat(sInfo, length, "\n- Rains hail down on to players around you"); + StrCat(sInfo, length, "\n- Players hit will get frozen for 3 seconds"); + StrCat(sInfo, length, "\n- 200%% Rage: Increased projectile count and spawn rate"); } public void Yeti_OnSpawn(SaxtonHaleBase boss) { - char attribs[128]; - Format(attribs, sizeof(attribs), "2 ; 2.80 ; 252 ; 0.5 ; 259 ; 1.0 ; 214 ; %d", GetRandomInt(7500, 7615)); - int iWeapon = boss.CallFunction("CreateWeapon", 195, NULL_STRING, 100, TFQual_Strange, attribs); + int iWeapon = boss.CallFunction("CreateWeapon", 195, NULL_STRING, 100, TFQual_Strange, "2 ; 2.80 ; 252 ; 0.5 ; 259 ; 1.0"); if (iWeapon > MaxClients) + { + TF2Attrib_SetByDefIndex(iWeapon, 214, view_as(GetRandomInt(7500, 7615))); SetEntPropEnt(boss.iClient, Prop_Send, "m_hActiveWeapon", iWeapon); + } /* Fist attributes: @@ -109,6 +102,29 @@ public void Yeti_OnRage(SaxtonHaleBase boss) FakeClientCommand(boss.iClient, "voicemenu 2 1"); } +public void Yeti_OnPlayerKilled(SaxtonHaleBase boss, Event event, int iVictim) +{ + KillIconShared(boss, event, true); +} + +public void Yeti_OnDestroyObject(SaxtonHaleBase boss, Event event) +{ + KillIconShared(boss, event, false); +} + +static void KillIconShared(SaxtonHaleBase boss, Event event, bool bLog) +{ + int iWeaponId = event.GetInt("weaponid"); + + if (iWeaponId == TF_WEAPON_ROCKETLAUNCHER) + { + if (bLog) + event.SetString("weapon_logclassname", "meteor"); + + event.SetString("weapon", "krampus_ranged"); + } +} + public void Yeti_GetModel(SaxtonHaleBase boss, char[] sModel, int length) { strcopy(sModel, length, YETI_MODEL); @@ -196,9 +212,3 @@ public void Yeti_Precache(SaxtonHaleBase boss) AddFileToDownloadsTable("models/player/kirillian/boss/yeti_modded.phy"); AddFileToDownloadsTable("models/player/kirillian/boss/yeti_modded.vvd"); } - -public bool Yeti_IsBossHidden(SaxtonHaleBase boss) -{ - return true; -} - From b2d9762b4e5615b3dfd000db4c8def272e2c6250 Mon Sep 17 00:00:00 2001 From: Batfoxkid Date: Tue, 19 Nov 2024 11:52:20 -0800 Subject: [PATCH 2/4] It's Good --- addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp b/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp index e49d290b..5ee2d953 100644 --- a/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp +++ b/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp @@ -167,7 +167,7 @@ static void SpawnRocket(SaxtonHaleBase boss) { foundValidPoint = true; ConstrainDistance(vecBossOrigin, vecSpawnPos, traceDistance, minDistance); - break; // TODO: Test add this + break; } } From 7d9f3dbc215dc75fba404ef0d9f7be3f04cecbfb Mon Sep 17 00:00:00 2001 From: Batfoxkid Date: Tue, 19 Nov 2024 12:12:58 -0800 Subject: [PATCH 3/4] And the one passive --- .../scripting/vsh/abilities/ability_groundpound.sp | 9 ++++++--- addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp | 11 +++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/vsh/abilities/ability_groundpound.sp b/addons/sourcemod/scripting/vsh/abilities/ability_groundpound.sp index cdc56d41..89a50609 100644 --- a/addons/sourcemod/scripting/vsh/abilities/ability_groundpound.sp +++ b/addons/sourcemod/scripting/vsh/abilities/ability_groundpound.sp @@ -12,6 +12,7 @@ public void GroundPound_Create(SaxtonHaleBase boss) boss.SetPropFloat("GroundPound", "StartTimer", 2.8); boss.SetPropFloat("GroundPound", "GravityMultiplier", 8.0); + boss.SetPropFloat("GroundPound", "JumpCooldown", 5.0); boss.SetPropFloat("GroundPound", "ImpactPush", 500.0); boss.SetPropFloat("GroundPound", "ImpactVelocity", 750.0); @@ -100,15 +101,17 @@ public void GroundPound_OnButton(SaxtonHaleBase boss, int &buttons) g_flClientBossWeighDownTimer[boss.iClient] = 0.0; SetEntityGravity(boss.iClient, GetEntityGravity(boss.iClient) * boss.GetPropFloat("GroundPound", "GravityMultiplier")); TF2_AddCondition(boss.iClient, TFCond_SpeedBuffAlly, TFCondDuration_Infinite); + + float flJumpCooldown = boss.GetPropFloat("GroundPound", "JumpCooldown"); // Add brave jump cooldown to it - if (boss.HasClass("BraveJump")) + if (flJumpCooldown > 0.0 && boss.HasClass("BraveJump")) { float flCooldownWait = boss.GetPropFloat("BraveJump", "CooldownWait"); if (flCooldownWait) { - boss.SetPropFloat("BraveJump", "CooldownWait", flCooldownWait + 5.0); - boss.CallFunction("UpdateHudInfo", 1.0, flCooldownWait + 5.0); //Update every second for cooldown duration + boss.SetPropFloat("BraveJump", "CooldownWait", flCooldownWait + flJumpCooldown); + boss.CallFunction("UpdateHudInfo", 1.0, flCooldownWait + flJumpCooldown); //Update every second for cooldown duration } } } diff --git a/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp b/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp index 57d0e0d4..6fb1a2ee 100644 --- a/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp +++ b/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp @@ -45,7 +45,10 @@ static char g_strYetiFootsteps[][] = { public void Yeti_Create(SaxtonHaleBase boss) { boss.CreateClass("BraveJump"); + boss.CreateClass("GroundPound"); boss.CreateClass("RageMeteor"); + + boss.SetPropFloat("GroundPound", "JumpCooldown", 0.0); boss.iHealthPerPlayer = 650; boss.flHealthExponential = 1.05; @@ -63,7 +66,7 @@ public void Yeti_GetBossInfo(SaxtonHaleBase boss, char[] sInfo, int length) StrCat(sInfo, length, "\nHealth: Medium"); StrCat(sInfo, length, "\n "); StrCat(sInfo, length, "\nAbilities"); - StrCat(sInfo, length, "\n- Brave Jump"); + StrCat(sInfo, length, "\n- Brave Jump (Not Reduced by Ground Pound)"); StrCat(sInfo, length, "\n "); StrCat(sInfo, length, "\nRage"); StrCat(sInfo, length, "\n- Damage requirement: 2500"); @@ -104,15 +107,15 @@ public void Yeti_OnRage(SaxtonHaleBase boss) public void Yeti_OnPlayerKilled(SaxtonHaleBase boss, Event event, int iVictim) { - KillIconShared(boss, event, true); + KillIconShared(event, true); } public void Yeti_OnDestroyObject(SaxtonHaleBase boss, Event event) { - KillIconShared(boss, event, false); + KillIconShared(event, false); } -static void KillIconShared(SaxtonHaleBase boss, Event event, bool bLog) +static void KillIconShared(Event event, bool bLog) { int iWeaponId = event.GetInt("weaponid"); From 7a046b454774db2cc9a7bb301ff79806b19dc249 Mon Sep 17 00:00:00 2001 From: Batfoxkid Date: Wed, 20 Nov 2024 05:48:44 -0800 Subject: [PATCH 4/4] You can now aim + Better rage sound --- .../vsh/abilities/ability_rage_meteor.sp | 37 +++++++++++++++---- .../scripting/vsh/bosses/boss_yeti.sp | 10 ++++- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp b/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp index 5ee2d953..0119b967 100644 --- a/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp +++ b/addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp @@ -29,7 +29,7 @@ public void RageMeteor_Create(SaxtonHaleBase boss) boss.SetPropFloat("RageMeteor", "Damage", 50.0); boss.SetPropFloat("RageMeteor", "Speed", 550.0); - boss.SetPropFloat("RageMeteor", "SpawnRadius", 800.0); + boss.SetPropFloat("RageMeteor", "SpawnRadius", 400.0); boss.SetPropFloat("RageMeteor", "MinAngle", 45.0); boss.SetPropFloat("RageMeteor", "FreezeTime", 4.0); boss.SetPropFloat("RageMeteor", "SpawnDelay", 0.094); @@ -144,9 +144,30 @@ static void SpawnRocket(SaxtonHaleBase boss) float vecBossOrigin[3]; GetEntPropVector(boss.iClient, Prop_Send, "m_vecOrigin", vecBossOrigin); vecBossOrigin[2] += 41.5; + + float vecTargetOrigin[3], vecAngles[3]; + GetClientEyePosition(boss.iClient, vecTargetOrigin); + GetClientEyeAngles(boss.iClient, vecAngles); + + // Take crosshair location + TR_TraceRayFilter(vecTargetOrigin, vecAngles, MASK_PLAYERSOLID, RayType_Infinite, TraceRay_DontHitEntity, boss.iClient); + if(TR_DidHit()) + { + TR_GetEndPosition(vecTargetOrigin); + vecTargetOrigin[2] += 20.0; + } + else + { + vecTargetOrigin = vecBossOrigin; + } + + // Stay close to the boss + float flDistance = GetVectorDistance(vecTargetOrigin, vecBossOrigin); + if (flDistance > 500.0) + ConstrainDistance(vecBossOrigin, vecTargetOrigin, flDistance, 500.0); // Find any valid spots - float vecSpawnPos[3], vecAngles[3]; + float vecSpawnPos[3]; float radius = boss.GetPropFloat("RageMeteor", "SpawnRadius"); bool foundValidPoint = false; for (int a = 0; a < 5; a++) @@ -158,15 +179,15 @@ static void SpawnRocket(SaxtonHaleBase boss) static const float Angles[] = { 0.0, 25.0, -25.0 }; vecAngles[0] = Angles[b]; - Handle trace = TR_TraceRayFilterEx(vecBossOrigin, vecAngles, (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_GRATE), RayType_Infinite, TraceRay_HitWallOnly); + Handle trace = TR_TraceRayFilterEx(vecTargetOrigin, vecAngles, (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_GRATE), RayType_Infinite, TraceRay_HitWallOnly); TR_GetEndPosition(vecSpawnPos, trace); delete trace; - float traceDistance = GetVectorDistance(vecBossOrigin, vecSpawnPos); - if (traceDistance >= minDistance) + flDistance = GetVectorDistance(vecTargetOrigin, vecSpawnPos); + if (flDistance >= minDistance) { foundValidPoint = true; - ConstrainDistance(vecBossOrigin, vecSpawnPos, traceDistance, minDistance); + ConstrainDistance(vecTargetOrigin, vecSpawnPos, flDistance, minDistance); break; } } @@ -187,8 +208,8 @@ static void SpawnRocket(SaxtonHaleBase boss) vecSpawnPos[2] -= 20.0; // TOO high up - if(vecSpawnPos[2] > (vecBossOrigin[2] + 1500.0)) - vecSpawnPos[2] = vecBossOrigin[2] + 1500.0; + if(vecSpawnPos[2] > (vecTargetOrigin[2] + 1500.0)) + vecSpawnPos[2] = vecTargetOrigin[2] + 1500.0; vecAngles[0] = GetRandomFloat(boss.GetPropFloat("RageMeteor", "MinAngle"), 89.9); vecAngles[1] = GetRandomFloat(-179.9, 179.9); diff --git a/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp b/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp index 6fb1a2ee..c24ea9cc 100644 --- a/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp +++ b/addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp @@ -23,6 +23,8 @@ static char g_strYetiKill[][] = { "player/taunt_yeti_roar_beginning.wav" }; +static char g_strYetiRage[] = "ambient/atmosphere/terrain_rumble1.wav"; + static char g_strYetiLastMan[][] = { "ambient_mp3/lair/animal_call_yeti2.mp3", }; @@ -70,8 +72,8 @@ public void Yeti_GetBossInfo(SaxtonHaleBase boss, char[] sInfo, int length) StrCat(sInfo, length, "\n "); StrCat(sInfo, length, "\nRage"); StrCat(sInfo, length, "\n- Damage requirement: 2500"); - StrCat(sInfo, length, "\n- Rains hail down on to players around you"); - StrCat(sInfo, length, "\n- Players hit will get frozen for 3 seconds"); + StrCat(sInfo, length, "\n- Rains hail down on to players in front of you"); + StrCat(sInfo, length, "\n- Players hit will get frozen for 4 seconds"); StrCat(sInfo, length, "\n- 200%% Rage: Increased projectile count and spawn rate"); } @@ -103,6 +105,9 @@ public void Yeti_OnThink(SaxtonHaleBase boss) public void Yeti_OnRage(SaxtonHaleBase boss) { FakeClientCommand(boss.iClient, "voicemenu 2 1"); + + EmitSoundToAll(g_strYetiRage); + EmitSoundToAll(g_strYetiRage); } public void Yeti_OnPlayerKilled(SaxtonHaleBase boss, Event event, int iVictim) @@ -193,6 +198,7 @@ public void Yeti_Precache(SaxtonHaleBase boss) PrecacheModel(YETI_MODEL); PrepareMusic(YETI_THEME, false); + PrecacheSound(g_strYetiRage); for (int i = 0; i < sizeof(g_strYetiRoundStart); i++)PrecacheSound(g_strYetiRoundStart[i]); for (int i = 0; i < sizeof(g_strYetiWin); i++)PrecacheSound(g_strYetiWin[i]);