Skip to content
Closed
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
5 changes: 5 additions & 0 deletions addons/sourcemod/scripting/saxtonhale.sp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ ConVar tf_arena_preround_time;
#include "vsh/bosses/boss_yeti.sp"
#include "vsh/bosses/boss_zombie.sp"
#include "vsh/bosses/boss_merasmus.sp"
#include "vsh/bosses/boss_teuton.sp"

#include "vsh/bossesmulti/bossmulti_mannbrothers.sp"
#include "vsh/bossesmulti/bossmulti_seemanseeldier.sp"
Expand Down Expand Up @@ -451,6 +452,7 @@ ConVar tf_arena_preround_time;
#include "vsh/queue.sp"
#include "vsh/sdk.sp"
#include "vsh/stocks.sp"
#include "vsh/teuton.sp"

public Plugin myinfo =
{
Expand Down Expand Up @@ -526,6 +528,7 @@ public void OnPluginStart()
TagsCore_Init();
TagsDamage_Init();
TagsName_Init();
Teuton_Init();

SaxtonHaleFunction func;

Expand Down Expand Up @@ -686,6 +689,7 @@ public void OnPluginStart()
SaxtonHale_RegisterClass("AnnouncerMinion", VSHClassType_Boss);
SaxtonHale_RegisterClass("MinionRanger", VSHClassType_Boss);
SaxtonHale_RegisterClass("Zombie", VSHClassType_Boss);
SaxtonHale_RegisterClass("Teuton", VSHClassType_Boss);

//Register ability
SaxtonHale_RegisterClass("BodyEat", VSHClassType_Ability);
Expand Down Expand Up @@ -951,6 +955,7 @@ public void OnMapStart()
g_iSpritesGlow = PrecacheModel("materials/sprites/glow01.vmt", true);

Dome_MapStart();
Teuton_MapStart();

CreateTimer(60.0, Timer_WelcomeMessage);
CreateTimer(240.0, Timer_WelcomeMessage, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
Expand Down
97 changes: 97 additions & 0 deletions addons/sourcemod/scripting/vsh/bosses/boss_teuton.sp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//static int g_iTeutonCape;
static int g_iTeutonHelmet;

public void Teuton_Create(SaxtonHaleBase boss)
{
boss.CreateClass("WallClimb");
boss.SetPropFloat("WallClimb", "MaxHeight", 600.0);
boss.SetPropFloat("WallClimb", "HorizontalSpeedMult", 1.0);
boss.SetPropFloat("WallClimb", "MaxHorizontalVelocity", 400.0);

boss.iBaseHealth = 1;
boss.nClass = TFClass_DemoMan;
boss.flSpeed = 340.0;
boss.flSpeedMult = 0.0;
boss.iMaxRageDamage = -1;
boss.bMinion = true;
}

public void Teuton_GetModel(SaxtonHaleBase boss, char[] sModel, int length)
{
strcopy(sModel, length, DEMO_ROBOT_MODEL);
}

public void Teuton_Precache(SaxtonHaleBase boss)
{
PrecacheModel(DEMO_ROBOT_MODEL);

//g_iTeutonCape = PrecacheModel("models/workshop/player/items/soldier/bak_caped_crusader/bak_caped_crusader.mdl");
g_iTeutonHelmet = PrecacheModel("models/workshop/player/items/soldier/dec17_brass_bucket/dec17_brass_bucket.mdl");
}

public bool Teuton_IsBossHidden(SaxtonHaleBase boss)
{
return true;
}

public void Teuton_OnSpawn(SaxtonHaleBase boss)
{
int iItem = boss.CallFunction("CreateWeapon", 132, "tf_weapon_sword", 5, TFQual_Unique, "1 ; 0.3076 ; 5 ; 1.3 ; 412 ; 0.0 ; 775 ; 0.0 ; 820 ; 1");
if (iItem > MaxClients)
{
SetEntPropEnt(boss.iClient, Prop_Send, "m_hActiveWeapon", iItem);
SetEntityRenderMode(iItem, RENDER_TRANSCOLOR);
SetEntityRenderColor(iItem, _, _, _, 128);
}

//iItem = boss.CallFunction("CreateWeapon", 30727, "tf_wearable", 5, TFQual_Unique, "");
//if (iItem > MaxClients)
// SetEntProp(iItem, Prop_Send, "m_nModelIndexOverrides", g_iTeutonCape);

iItem = boss.CallFunction("CreateWeapon", 30969, "tf_wearable", 5, TFQual_Unique, "");
if (iItem > MaxClients)
{
SetEntProp(iItem, Prop_Send, "m_nModelIndexOverrides", g_iTeutonHelmet);
SetEntityRenderMode(iItem, RENDER_TRANSCOLOR);
SetEntityRenderColor(iItem, _, _, _, 128);
}

SetEntPropFloat(boss.iClient, Prop_Send, "m_flModelScale", 0.6);
SetEntityCollisionGroup(boss.iClient, COLLISION_GROUP_DEBRIS);
TF2_AddCondition(boss.iClient, TFCond_DisguisedAsDispenser); // Makes Sentries ignore the player
SetEntityRenderMode(boss.iClient, RENDER_TRANSCOLOR);
SetEntityRenderColor(boss.iClient, _, _, _, 128);
}

public Action Teuton_OnAttackDamage(SaxtonHaleBase boss, int victim, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom)
{
if (damagecustom == TF_CUSTOM_TAUNT_BARBARIAN_SWING)
{
return Plugin_Stop;
}

return Plugin_Continue;
}

public Action Teuton_OnVoiceCommand(SaxtonHaleBase boss, char sCmd1[8], char sCmd2[8])
{
return Plugin_Handled;
}

public Action Teuton_CanHealTarget(SaxtonHaleBase boss, int iTarget, bool &bResult)
{
if (SaxtonHale_IsValidBoss(iTarget))
{
bResult = false;
return Plugin_Changed;
}

return Plugin_Continue;
}

public void Teuton_Destroy(SaxtonHaleBase boss)
{
SetEntPropFloat(boss.iClient, Prop_Send, "m_flModelScale", 1.0);
SetEntityCollisionGroup(boss.iClient, COLLISION_GROUP_PLAYER);
SetEntityRenderColor(boss.iClient, _, _, _, 255);
}
4 changes: 2 additions & 2 deletions addons/sourcemod/scripting/vsh/dome.sp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ void Dome_Init()
g_ConfigConvar.Create("vsh_dome_enable", "1", "Enable dome?", _, true, 0.0, true, 1.0);
g_ConfigConvar.Create("vsh_dome_centre", "", "Map centre pos for Dome/CP (blank for CP's default centre)");
g_ConfigConvar.Create("vsh_dome_cp_radius", "250", "If vsh_dome_centre specified, new radius from CP to capture");
g_ConfigConvar.Create("vsh_dome_cp_unlock", "60", "Time in second to unlock CP on round start", _, true, 0.0);
g_ConfigConvar.Create("vsh_dome_cp_unlockplayer", "5", "Time in second to add on every player to unlock CP on round start", _, true, 0.0);
g_ConfigConvar.Create("vsh_dome_cp_unlock", "180", "Time in second to unlock CP on round start", _, true, 0.0);
g_ConfigConvar.Create("vsh_dome_cp_unlockplayer", "10", "Time in second to add on every player to unlock CP on round start", _, true, 0.0);
g_ConfigConvar.Create("vsh_dome_cp_captime", "15", "How long to capture CP", _, true, 0.0);
g_ConfigConvar.Create("vsh_dome_cp_bossrate", "3", "Capture value for boss", _, true, 1.0);
g_ConfigConvar.Create("vsh_dome_color_neu", "192 192 192 255", "Color of dome in RGBA if nobody owns the capture point");
Expand Down
9 changes: 9 additions & 0 deletions addons/sourcemod/scripting/vsh/event.sp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ public void Event_RoundArenaStart(Event event, const char[] sName, bool bDontBro
Hud_Display(i, CHANNEL_INTRO, sMessage, flHUD, 5.0, iColor, 0, 0.0, flFade);

Dome_RoundArenaStart();
Teuton_RoundArenaStart();

//Display chat on who is next boss
int iNextPlayer = Queue_GetPlayerFromRank(1);
Expand Down Expand Up @@ -634,6 +635,9 @@ public Action Event_PlayerDeath(Event event, const char[] sName, bool bDontBroad
SetVariantInt(999999);
AcceptEntityInput(iSentry, "RemoveHealth");
}

if (!bDeadRinger && g_bRoundStarted)
Teuton_PlayerDeath(iVictim);

if (bossVictim.bValid)
{
Expand Down Expand Up @@ -718,8 +722,13 @@ public Action Event_PlayerDeath(Event event, const char[] sName, bool bDontBroad
{
//Kill any minions that are still alive
for (int i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && IsPlayerAlive(i) && i != iVictim && GetClientTeam(i) == iVictimTeam)
{
SDKHooks_TakeDamage(i, 0, i, 99999.0);
ForcePlayerSuicide(i);
}
}
}
}

Expand Down
13 changes: 11 additions & 2 deletions addons/sourcemod/scripting/vsh/stocks.sp
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,21 @@ stock ArrayList GetValidSummonableClients(bool bAllowBoss = false)
{
if (IsClientInGame(iClient)
&& TF2_GetClientTeam(iClient) > TFTeam_Spectator
&& !IsPlayerAlive(iClient)
&& Preferences_Get(iClient, VSHPreferences_Revival)
&& !Client_HasFlag(iClient, ClientFlags_Punishment))
{
// Minions ignore alive check
if (!SaxtonHale_IsValidBoss(iClient, false) || !SaxtonHaleBase(iClient).bMinion)
{
if (!IsPlayerAlive(iClient))
continue;
}

if (!bAllowBoss)
if (SaxtonHale_IsValidBoss(iClient, false)) continue;
{
if (SaxtonHale_IsValidBoss(iClient, false))
continue;
}

aClients.Push(iClient);
}
Expand Down
79 changes: 79 additions & 0 deletions addons/sourcemod/scripting/vsh/teuton.sp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
void Teuton_Init()
{
g_ConfigConvar.Create("vsh_teuton_enable", "1", "Enable Teuton Knights?", _, true, 0.0, true, 1.0);
}

void Teuton_MapStart()
{
int iEntity = FindEntityByClassname(-1, "tf_player_manager");
if(iEntity != -1)
SDKHook(iEntity, SDKHook_ThinkPost, Teuton_PlayerManagerThink);
}

void Teuton_RoundArenaStart()
{
if (!g_ConfigConvar.LookupBool("vsh_teuton_enable") || g_ConfigConvar.LookupBool("vsh_dome_enable"))
return;

// If we have Dome disabled and Teutons enabled, block the cap overall
GameRules_SetPropFloat("m_flCapturePointEnableTime", GetGameTime() + 999.9);
}

void Teuton_PlayerDeath(int iVictim)
{
if (!g_ConfigConvar.LookupBool("vsh_teuton_enable") || SaxtonHale_IsValidBoss(iVictim, false))
return;

CreateTimer(6.0, Teuton_SpawnTimer, GetClientUserId(iVictim), TIMER_FLAG_NO_MAPCHANGE);
}

static Action Teuton_SpawnTimer(Handle timer, int iUserID)
{
int iClient = GetClientOfUserId(iUserID);
if (iClient && g_bRoundStarted && !IsPlayerAlive(iClient) && TF2_GetClientTeam(iClient) > TFTeam_Spectator)
{
SaxtonHaleBase boss = SaxtonHaleBase(iClient);
if (boss.bValid)
boss.DestroyAllClass();

TF2_ChangeClientTeam(iClient, TFTeam_Attack);

boss.CreateClass("Teuton");
TF2_RespawnPlayer(iClient);

int iCount;
int[] iTargets = new int[MaxClients];
for (int iTarget = 1; iTarget <= MaxClients; iTarget++)
{
if(iTarget != iClient && IsClientInGame(iTarget) && IsPlayerAlive(iTarget) && TF2_GetClientTeam(iTarget) == TFTeam_Attack)
{
iTargets[iCount++] = iTarget;
}
}

if (iCount != 0)
TF2_TeleportToClient(iClient, iTargets[GetURandomInt() % iCount]);
}

return Plugin_Continue;
}

static void Teuton_PlayerManagerThink(int iEntity)
{
static int iOffset = -1;
if (iOffset == -1)
iOffset = FindSendPropInfo("CTFPlayerResource", "m_bAlive");

bool[] bAlive = new bool[MaxClients+1];

for (int iClient = 1; iClient <= MaxClients; iClient++)
{
if (IsClientInGame(iClient))
{
// Alive and not a minion boss
bAlive[iClient] = (IsPlayerAlive(iClient) && (!SaxtonHaleBase(iClient).bValid || !SaxtonHaleBase(iClient).bMinion));
}
}

SetEntDataArray(iEntity, iOffset, bAlive, MaxClients + 1);
}