From 11bb8be7867815c46a312ec77859117799599adb Mon Sep 17 00:00:00 2001 From: TatLead Date: Tue, 18 Jun 2019 05:27:11 +0800 Subject: [PATCH] Add files via upload --- plugins/TF2Sandbox-SecurityLaser.smx | Bin 0 -> 10839 bytes scripting/TF2Sandbox-SecurityLaser.sp | 247 ++++++++++++++++++++++++++ scripting/include/build.inc | 140 +++++++++++++++ 3 files changed, 387 insertions(+) create mode 100644 plugins/TF2Sandbox-SecurityLaser.smx create mode 100644 scripting/TF2Sandbox-SecurityLaser.sp create mode 100644 scripting/include/build.inc diff --git a/plugins/TF2Sandbox-SecurityLaser.smx b/plugins/TF2Sandbox-SecurityLaser.smx new file mode 100644 index 0000000000000000000000000000000000000000..24d6e1a0c936d717dcd51687b2ca4062d140846c GIT binary patch literal 10839 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 literal 0 HcmV?d00001 diff --git a/scripting/TF2Sandbox-SecurityLaser.sp b/scripting/TF2Sandbox-SecurityLaser.sp new file mode 100644 index 0000000..3d9cdce --- /dev/null +++ b/scripting/TF2Sandbox-SecurityLaser.sp @@ -0,0 +1,247 @@ +#pragma semicolon 1 + +#define DEBUG + +#define PLUGIN_AUTHOR "BattlefieldDuck" +#define PLUGIN_VERSION "1.0" + +#include +#include +#include +#include +#include + +#pragma newdecls required + +public Plugin myinfo = +{ + name = "[TF2] Sandbox - Security Laser", + author = PLUGIN_AUTHOR, + description = "Security Laser is not expensive in TF2Sandbox", + version = PLUGIN_VERSION, + url = "https://github.com/tf2-sandbox-studio/Module-SecurityLaser" +}; + +#define MODEL_POINTER "models/props_lab/tpplug.mdl" + +ConVar cvfRefreshRate; + +char g_strLaserModel[][] = +{ + "materials/sprites/physbeam.vmt", + "materials/sprites/healbeam.vmt", + "materials/sprites/plasmabeam.vmt", + "materials/sprites/bluelaser1.vmt", + "materials/sprites/crystal_beam1.vmt", + "materials/sprites/laser.vmt", + "materials/sprites/laserbeam.vmt", + "materials/sprites/laserdot.vmt", + "materials/sprites/lgtning.vmt", + "materials/sprites/tp_beam001.vmt" +}; + +char g_strHaloModel[][] = +{ + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt", + "materials/sprites/halo01.vmt" +}; + +int g_iModelIndex[sizeof(g_strLaserModel)]; +int g_iHaloIndex[sizeof(g_strHaloModel)]; + +public void OnPluginStart() +{ + RegAdminCmd("sm_laser", Command_SpawnSecurityLaser, 0, "Spawn Security Laser"); + + cvfRefreshRate = CreateConVar("sm_tf2sb_laser_refreshrate", "0.25", "Security Laser refresh rate", 0, true, 0.1, true, 1.5); +} + +public void OnMapStart() +{ + PrecacheModel(MODEL_POINTER); + + for (int i = 0; i < sizeof(g_strLaserModel); i++) + { + g_iModelIndex[i] = PrecacheModel(g_strLaserModel[i]); + g_iHaloIndex[i] = PrecacheModel(g_strHaloModel[i]); + } + + int index = -1; + while ((index = FindEntityByClassname(index, "prop_dynamic")) != -1) + { + char strModel[64]; + GetEntPropString(index, Prop_Data, "m_ModelName", strModel, sizeof(strModel)); + + if (StrEqual(strModel, MODEL_POINTER)) + { + CreateTimer(0.0, Timer_SecurityLaser, EntIndexToEntRef(index)); + } + } +} + +public void OnEntityCreated(int entity, const char[] classname) +{ + if (StrEqual(classname, "prop_dynamic") || StrEqual(classname, "prop_dynamic_override")) + { + SDKHook(entity, SDKHook_SpawnPost, OnLaserPointerSpawn); + } +} + +public void OnLaserPointerSpawn(int entity) +{ + if(IsValidEntity(entity)) + { + char strModel[64]; + GetEntPropString(entity, Prop_Data, "m_ModelName", strModel, sizeof(strModel)); + + if (StrEqual(strModel, MODEL_POINTER)) + { + CreateTimer(0.0, Timer_SecurityLaser, EntIndexToEntRef(entity)); + } + } +} + +public Action Command_SpawnSecurityLaser(int client, int args) +{ + if(client <= 0 || client > MaxClients || !IsClientInGame(client) || !IsPlayerAlive(client)) + { + return Plugin_Continue; + } + + SpawnLaserPointer(client); + + return Plugin_Continue; +} + +public Action Timer_SecurityLaser(Handle timer, int pointerref) +{ + int pointer = EntRefToEntIndex(pointerref); + if (pointer == INVALID_ENT_REFERENCE) + { + return Plugin_Continue; + } + + float fpointerpos[3], fpointerang[3]; + GetEntPropVector(pointer, Prop_Send, "m_vecOrigin", fpointerpos); + GetEntPropVector(pointer, Prop_Data, "m_angRotation", fpointerang); + + float fSize = GetEntPropFloat(pointer, Prop_Send, "m_flModelScale"); + + int iSkin = GetEntProp(pointer, Prop_Send, "m_nSkin"); + if (iSkin < 0) iSkin = 0; + if (iSkin >= sizeof(g_strLaserModel)) iSkin = sizeof(g_strLaserModel) - 1; + + int g_iLaserColor[4]; + GetEntityRenderColor(pointer, g_iLaserColor[0], g_iLaserColor[1], g_iLaserColor[2], g_iLaserColor[3]); + + TE_SetupBeamPoints(fpointerpos, GetPointAimPosition(fpointerpos, fpointerang, 999999.9, pointer), g_iModelIndex[iSkin], g_iHaloIndex[iSkin], 0, 0, cvfRefreshRate.FloatValue*2, fSize, fSize, 0, 0.0, g_iLaserColor, 0); + TE_SendToAll(); + + CreateTimer(cvfRefreshRate.FloatValue, Timer_SecurityLaser, pointerref); + + return Plugin_Continue; +} + +float[] GetClientEyePositionEx(int client) +{ + float pos[3]; + GetClientEyePosition(client, pos); + + return pos; +} + +float[] GetClientEyeAnglesEx(int client) +{ + float angles[3]; + GetClientEyeAngles(client, angles); + + return angles; +} + +float[] GetPointAimPosition(float pos[3], float angles[3], float maxtracedistance, int client) +{ + Handle trace = TR_TraceRayFilterEx(pos, angles, MASK_SOLID, RayType_Infinite, TraceEntityFilter, client); + + if(TR_DidHit(trace)) + { + float endpos[3]; + TR_GetEndPosition(endpos, trace); + + if(!((GetVectorDistance(pos, endpos) <= maxtracedistance) || maxtracedistance <= 0)) + { + float eyeanglevector[3]; + GetAngleVectors(angles, eyeanglevector, NULL_VECTOR, NULL_VECTOR); + NormalizeVector(eyeanglevector, eyeanglevector); + ScaleVector(eyeanglevector, maxtracedistance); + AddVectors(pos, eyeanglevector, endpos); + } + + if (client > MaxClients) + { + float fSize = GetEntPropFloat(client, Prop_Send, "m_flModelScale"); + SetLaserDamageToClient(pos, endpos, fSize); + } + + CloseHandle(trace); + return endpos; + } + + CloseHandle(trace); + return pos; +} + +public bool TraceEntityFilter(int entity, int mask, int client) +{ + return (entity > MaxClients && entity != client); +} + +void SetLaserDamageToClient(float startpos[3], float endpos[3], float damage) +{ + Handle trace = TR_TraceRayFilterEx(startpos, endpos, MASK_SOLID, RayType_EndPoint, SetClientDamageFilter, damage); + CloseHandle(trace); +} + +public bool SetClientDamageFilter(int entity, int mask, float damage) +{ + if (entity > 0 && entity <= MaxClients && IsClientInGame(entity)) + { + SDKHooks_TakeDamage(entity, entity, entity, damage, DMG_BURN); + TF2_AddCondition(entity, TFCond_Bleeding, 2.0); + } + + return false; +} + +int SpawnLaserPointer(int client) +{ + int pointer = CreateEntityByName("prop_dynamic_override"); + + if (IsValidEntity(pointer)) + { + SetEntProp(pointer, Prop_Send, "m_nSolidType", 6); + SetEntProp(pointer, Prop_Data, "m_nSolidType", 6); + + if (Build_RegisterEntityOwner(pointer, client)) + { + SetEntityModel(pointer, MODEL_POINTER); + + TeleportEntity(pointer, GetPointAimPosition(GetClientEyePositionEx(client), GetClientEyeAnglesEx(client), 99999.9, client), NULL_VECTOR, NULL_VECTOR); + + DispatchSpawn(pointer); + + return pointer; + } + + AcceptEntityInput(pointer, "Kill"); + } + + return -1; +} \ No newline at end of file diff --git a/scripting/include/build.inc b/scripting/include/build.inc new file mode 100644 index 0000000..e6c720b --- /dev/null +++ b/scripting/include/build.inc @@ -0,0 +1,140 @@ +#define BUILDMODAPI_VER 3 +#define BUILDMOD_VER "0.75.5" +#define MAX_HOOK_ENTITIES 4096 + +/** + * Register an entity owner. + * + * @param entity_index Entity index. + * @param client_index Client index. + * @param Doll Is prop_ragdoll? + * @return Ture on success. False on failure. + */ +native bool:Build_RegisterEntityOwner(entity_index, client_index, bool:Doll = false); + +/** + * Get an entity owner. + * + * @param entity_index Entity index. + * @return -1 on failure. Any other value indicates a Entity index owner. + */ +native Build_ReturnEntityOwner(entity_index); + +/** + * Set client props limit. + * + * @param client_index Client index. + * @param amount Amount to increase or decrease. If amount = 0 then set limit to 0. + * @param Doll Is prop_ragdoll? + * @noreturn + */ +native Build_SetLimit(client_index, amount, bool:Doll = false); + +/** + * Check client can use BuildMod. + * + * @param client_index Client index. + * @return True on success. False on failure. + */ +native bool:Build_AllowToUse(client_index); + +/** + * Check client can use Fly. + * + * @param client_index Client index. + * @return True on success. False on failure. + */ +native bool:Build_AllowFly(client_index); + +/** + * Get client admin. + * + * @param client_index Client index. + * @param Level2 Level 2 access. + * @return True on admin. False on not. + */ +native bool:Build_IsAdmin(client_index, bool:Level2 = false); + +/** + * Get client aim entity. + * + * @param client_index Client index. + * @param show_message Show a message when entity invalid? + * @param included_clients Allow native to getting clients? + * @return -1 on failure. Any other value indicates a Entity index. + */ +native Build_ClientAimEntity(client_index, bool:show_message = true, bool:included_clients = false); + +/** + * Get an entity of owner is equal client. + * + * @param client_index Client index. + * @param entity_index Entity index. + * @param bIngoreCvar Ingore 'bm_nonowner' cvar? + * @return True on owner. False on not. + */ +native bool:Build_IsEntityOwner(client_index, entity_index, bool:bIngoreCvar = false); + +/** + * Logging commands and args. + * + * @param client_index Client index. + * @param command Command to log. + * @param args Args to log. + * @noreturn + */ +native Build_Logging(client_index, const String:command[], const String:args[]); + +/** + * Prints a message with the BuildMod tag. + * + * @param client_index Client index. + * @param format Formatting rules. + * @param ... Variable number of format parameters. + * @noreturn + */ +native Build_PrintToChat(client_index, const String:format[], any:...); + +/** + * Prints a message to all clients with the BuildMod tag. + * + * @param format Formatting rules. + * @param ... Variable number of format parameters. + * @noreturn + */ +native Build_PrintToAll(const String:format[], any:...); + +/** + * Add client to blacklist. + * + * @param client_index Client index. + * @return True on success. False on failure. + */ +native Build_AddBlacklist(client_index); + +/** + * Remove client from blacklist. + * + * @param client_index Client index. + * @return True on success. False on failure. + */ +native Build_RemoveBlacklist(client_index); + +/** + * Get client is blacklisted. + * + * @param client_index Client index. + * @return True on blacklisted. False on not. + */ +native bool:Build_IsBlacklisted(client_index); + +/** + * Check is target client valid. + * + * @param client_index Client index. + * @param target_index Target index. + * @param Alive Check is target alive. + * @param ReplyTarget Alive result reply target client or self. + * @return True if target valid. Otherwise false. + */ +native bool:Build_IsClientValid(client_index, target_index, bool:Alive = false, bool:ReplyTarget = false);