Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework & Add Last Yeti #413

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions addons/sourcemod/scripting/saxtonhale.sp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
}
}
}
Expand Down
241 changes: 241 additions & 0 deletions addons/sourcemod/scripting/vsh/abilities/ability_rage_meteor.sp
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
// 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", 400.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;

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];
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(vecTargetOrigin, vecAngles, (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_GRATE), RayType_Infinite, TraceRay_HitWallOnly);
TR_GetEndPosition(vecSpawnPos, trace);
delete trace;

flDistance = GetVectorDistance(vecTargetOrigin, vecSpawnPos);
if (flDistance >= minDistance)
{
foundValidPoint = true;
ConstrainDistance(vecTargetOrigin, vecSpawnPos, flDistance, minDistance);
break;
}
}

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] > (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);
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);
}
63 changes: 41 additions & 22 deletions addons/sourcemod/scripting/vsh/bosses/boss_yeti.sp
Original file line number Diff line number Diff line change
Expand Up @@ -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",
};
Expand All @@ -46,13 +48,9 @@ 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.SetPropFloat("GroundPound", "JumpCooldown", 0.0);

boss.iHealthPerPlayer = 650;
boss.flHealthExponential = 1.05;
Expand All @@ -67,26 +65,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- Brave Jump (Not Reduced by Ground Pound)");
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 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");
}

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<float>(GetRandomInt(7500, 7615)));
SetEntPropEnt(boss.iClient, Prop_Send, "m_hActiveWeapon", iWeapon);
}
/*
Fist attributes:

Expand All @@ -107,6 +105,32 @@ 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)
{
KillIconShared(event, true);
}

public void Yeti_OnDestroyObject(SaxtonHaleBase boss, Event event)
{
KillIconShared(event, false);
}

static void KillIconShared(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)
Expand Down Expand Up @@ -174,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]);
Expand All @@ -196,9 +221,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;
}