diff --git a/VScripts/scripting/VScript_ze_eternal_grove.sp b/VScripts/scripting/VScript_ze_eternal_grove.sp new file mode 100644 index 00000000..32f70662 --- /dev/null +++ b/VScripts/scripting/VScript_ze_eternal_grove.sp @@ -0,0 +1,218 @@ +#pragma semicolon 1 +#pragma newdecls required + +#define MAP_NAME "ze_eternal_grove_v3_css" +#define NADE_DAMAGE 300 +#define NADE_DAMGE_CRIT 800 +#define CLAMP_UP 500.0 +#define CLAMP_SIDE 350.0 + +#include +#include +#include +#include + +bool bValidMap = false; +int g_iNadeBonusDamage = 0; +int g_iWindsPushes[] = { + 54298, 54619, 54512, 216147, 215572, 222212, 220705, 220609, 220045, 218972, 53965, 59316, 58555, 58448, 58341, 58127, 55822, 55608, 54833, 62828, 62721, 62614, 62507 +}; + +public Plugin myinfo = +{ + name = "VScript - Eternal grove", + author = ".Rushaway", + description = "Clamp player velocity and display boss game_text", + version = "1.0", + url = "https://github.com/srcdslab/sm-plugin-VScript_ze_eternal_grove" +}; + +public void OnMapStart() +{ + char sCurMap[256]; + GetCurrentMap(sCurMap, sizeof(sCurMap)); + bValidMap = (strcmp(sCurMap, MAP_NAME, false) == 0); + if (bValidMap) + { + HookEvent("round_start", OnRoundStart, EventHookMode_PostNoCopy); + } +} + +public void OnRoundStart(Event hEvent, const char[] sEvent, bool bDontBroadcast) +{ + if (!bValidMap) + { + return; + } + InitHooks(); + CreateTimer(12.0, Timer_Credits, INVALID_HANDLE, TIMER_FLAG_NO_MAPCHANGE); +} + +public Action Timer_Credits(Handle timer) +{ + if (!bValidMap) + { + return Plugin_Handled; + } + CPrintToChatAll("{pink}[VScripts] {white}Original VScripts by Luffaren ported by .Rushaway"); + return Plugin_Stop; +} + +public void BossElevator_OnFullyOpen(const char[] output, int caller, int activator, float delay) +{ + CreateTimer(15.5, Timer_HookMinotaurodgod, INVALID_HANDLE, TIMER_FLAG_NO_MAPCHANGE); +} + +public void AdminRoom_OnPressed(const char[] output, int caller, int activator, float delay) +{ + CreateTimer(21.5, Timer_HookMinotaurodgod, INVALID_HANDLE, TIMER_FLAG_NO_MAPCHANGE); +} + +public Action Timer_HookMinotaurodgod(Handle timer) +{ + Hooks_Minotaurgod(); + return Plugin_Continue; +} + +stock void InitHooks() +{ + // Boss Eleavtor - boss_elevator + int iEntity = Vscripts_GetEntityIndexByHammerID(68255, "func_movelinear", INVALID_ENT_REFERENCE); + if (iEntity != INVALID_ENT_REFERENCE) + HookSingleEntityOutput(iEntity, "OnFullyOpen", BossElevator_OnFullyOpen, false); + + // Adminroom - admin_buttons_GoToBoss + iEntity = Vscripts_GetEntityIndexByHammerID(393420, "func_button", INVALID_ENT_REFERENCE); + if (iEntity != INVALID_ENT_REFERENCE) + HookSingleEntityOutput(iEntity, "OnPressed", AdminRoom_OnPressed, false); + + for (int i = 0; i < sizeof(g_iWindsPushes); i++) + { + iEntity = Vscripts_GetEntityIndexByHammerID(g_iWindsPushes[i], "trigger_push", INVALID_ENT_REFERENCE); + + if (iEntity != INVALID_ENT_REFERENCE) + HookSingleEntityOutput(iEntity, "OnEndTouch", WindsPushes_OnEndTouch, false); + } +} + +stock void Hooks_Minotaurgod() +{ + // i_minotaurgod_hp + int iEntity = Vscripts_GetEntityIndexByHammerID(918186, "func_physbox", INVALID_ENT_REFERENCE); + if (iEntity != INVALID_ENT_REFERENCE) + HookSingleEntityOutput(iEntity, "OnHealthChanged", Minotaurgod_OnHealthChanged, false); + + // i_minotaurgod_nadehp + iEntity = Vscripts_GetEntityIndexByHammerID(918241, "func_breakable", INVALID_ENT_REFERENCE); + if (iEntity != INVALID_ENT_REFERENCE) + { + g_iNadeBonusDamage = 0; + + HookSingleEntityOutput(iEntity, "OnUser1", MinotaurgodNadeHP_OnUser1, false); + HookSingleEntityOutput(iEntity, "OnUser2", MinotaurgodNadeHP_OnUser2, false); + } +} + +stock void Minotaurgod_OnHealthChanged(const char[] output, int caller, int activator, float delay) +{ + if (!IsValidClient(activator)) + return; + + // text_boss_hp + int iGameText = Vscripts_GetEntityIndexByHammerID(918088, "game_text", INVALID_ENT_REFERENCE); + if (!IsValidEntity(iGameText)) + return; + + int iHP = GetEntProp(caller, Prop_Data, "m_iHealth"); + char sBuffer[252]; + Format(sBuffer, sizeof(sBuffer), "message MINOTAUR GOD = %d", iHP); + SetVariantString(sBuffer); + AcceptEntityInput(iGameText, "AddOutput"); + AcceptEntityInput(iGameText, "Display"); +} + +stock void MinotaurgodNadeHP_OnUser1(const char[] output, int caller, int activator, float delay) +{ + if (!IsValidClient(activator)) + return; + + g_iNadeBonusDamage = (g_iNadeBonusDamage + NADE_DAMAGE); + + // text_boss_crit + int iGameText = Vscripts_GetEntityIndexByHammerID(918047, "game_text", INVALID_ENT_REFERENCE); + if (!IsValidEntity(iGameText)) + return; + + char sBuffer[252]; + Format(sBuffer, sizeof(sBuffer), "message BONUS DAMAGE = %d", g_iNadeBonusDamage); + SetVariantString(sBuffer); + AcceptEntityInput(iGameText, "AddOutput"); + AcceptEntityInput(iGameText, "Display"); +} + +stock void MinotaurgodNadeHP_OnUser2(const char[] output, int caller, int activator, float delay) +{ + if (!IsValidClient(activator)) + return; + + g_iNadeBonusDamage = (g_iNadeBonusDamage + NADE_DAMGE_CRIT); + + // text_boss_crit + int iGameText = Vscripts_GetEntityIndexByHammerID(918047, "game_text", INVALID_ENT_REFERENCE); + if (!IsValidEntity(iGameText)) + return; + + char sBuffer[252]; + Format(sBuffer, sizeof(sBuffer), "message BONUS DAMAGE = %d", g_iNadeBonusDamage); + SetVariantString(sBuffer); + AcceptEntityInput(iGameText, "AddOutput"); + AcceptEntityInput(iGameText, "Display"); +} + +stock void WindsPushes_OnEndTouch(const char[] output, int caller, int activator, float delay) +{ + if (!IsValidClient(activator)) + return; + + float fVelocity[3]; + GetVelocity(activator, fVelocity); + + bool setVelocity = false; + + // Laterally clamp the player's velocity + if (FloatAbs(fVelocity[0] + fVelocity[1]) > CLAMP_SIDE) + { + fVelocity[0] *= 0.90; // X axis - Limit sideways velocity + fVelocity[1] *= 0.90; // Y axis - Limit sideways velocity + setVelocity = true; + } + + // Vertically clamp the player's velocity + if (fVelocity[2] > CLAMP_UP) + { + fVelocity[2] = CLAMP_UP; // Z axis - Limit upwards velocity + setVelocity = true; + } + + if (setVelocity) + SetVelocity(activator, fVelocity); +} + +stock bool IsValidClient(int client) +{ + return (client > 0 && client <= MaxClients && IsClientInGame(client) && IsPlayerAlive(client)); +} + +stock void GetVelocity(int client, float fVelocity[3]) +{ + fVelocity[0] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[0]"); + fVelocity[1] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[1]"); + fVelocity[2] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[2]"); +} + +stock void SetVelocity(int client, const float fVelocity[3]) +{ + SetEntPropFloat(client, Prop_Send, "m_vecVelocity[0]", fVelocity[0]); + SetEntPropFloat(client, Prop_Send, "m_vecVelocity[1]", fVelocity[1]); + SetEntPropFloat(client, Prop_Send, "m_vecVelocity[2]", fVelocity[2]); +}