123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /**
- * [CSRD] Soldier Statue Spawner
- *
- * Provides some tooling to spawn Rick May tribute statues on maps that don't support it.
- * Only available when the holiday is active.
- */
- #pragma semicolon 1
- #include <sourcemod>
- #include <tf2_stocks>
- #pragma newdecls required
- #include <sdktools>
- #include <stocksoup/maps>
- #include <stocksoup/log_server>
- #define PLUGIN_VERSION "1.0.0"
- public Plugin myinfo = {
- name = "[CSRD] Soldier Statue Spawner",
- author = "nosoop",
- description = "Spawns the Rick May tribute statue in custom locations.",
- version = PLUGIN_VERSION,
- url = "https://git.csrd.science/"
- }
- // CREATE TABLE IF NOT EXIST locations (map TEXT NOT NULL UNIQUE, xpos REAL, ypos REAL, zpos REAL, pitchang REAL, yawang REAL, rollang REAL);
- Database g_SpawnLocations;
- public void OnPluginStart() {
- RegAdminCmd("csrd_statue_place_aim", CommandSetPositionAim, ADMFLAG_ROOT);
- RegAdminCmd("csrd_statue_reload", ReloadStatuePosition, ADMFLAG_ROOT);
-
- char error[128];
- g_SpawnLocations = SQLite_UseDatabase("soldier_statues", error, sizeof(error));
- if (!g_SpawnLocations) {
- SetFailState("Failed to open soldier_statues database: %s", error);
- }
- }
- public void OnMapStart() {
- if (!TF2_IsHolidayActive(0x0C)) {
- return;
- }
-
- char mapName[PLATFORM_MAX_PATH];
- GetCurrentMapDisplayName(mapName, sizeof(mapName));
-
- char query[256];
- g_SpawnLocations.Format(query, sizeof(query),
- "SELECT xpos, ypos, zpos, pitchang, yawang, rollang "
- ... "FROM locations WHERE map == '%s';", mapName);
-
- g_SpawnLocations.Query(OnSpawnLocationLoaded, query);
- }
- public Action CommandSetPositionAim(int client, int argc) {
- float position[3], origin[3];
- GetClientAbsOrigin(client, origin);
- GetClientAimEndPosition(client, position);
-
- float direction[3], angles[3];
- MakeVectorFromPoints(position, origin, direction);
- GetVectorAngles(direction, angles);
- SetStatuePosition(position, angles);
-
- return Plugin_Handled;
- }
- public Action ReloadStatuePosition(int client, int argc) {
- char mapName[PLATFORM_MAX_PATH];
- GetCurrentMapDisplayName(mapName, sizeof(mapName));
-
- char query[256];
- g_SpawnLocations.Format(query, sizeof(query),
- "SELECT xpos, ypos, zpos, pitchang, yawang, rollang "
- ... "FROM locations WHERE map == '%s';", mapName);
-
- g_SpawnLocations.Query(OnSpawnLocationLoaded, query);
-
- return Plugin_Handled;
- }
- void SetStatuePosition(const float position[3], const float angles[3]) {
- TeleportEntity(GetSoldierStatueEntity(), position, angles, NULL_VECTOR);
-
- char mapName[PLATFORM_MAX_PATH];
- GetCurrentMapDisplayName(mapName, sizeof(mapName));
-
- char query[256];
- g_SpawnLocations.Format(query, sizeof(query),
- "REPLACE INTO locations(map, xpos, ypos, zpos, pitchang, yawang, rollang)"
- ... "VALUES ('%s', %f, %f, %f, %f, %f, %f);",
- mapName, position[0], position[1], position[2], angles[0], angles[1], angles[2]);
- g_SpawnLocations.Query(OnSpawnLocationSaved, query);
- }
- int GetSoldierStatueEntity() {
- int statue = FindEntityByClassname(-1, "entity_soldier_statue");
- if (!IsValidEntity(statue)) {
- statue = CreateEntityByName("entity_soldier_statue");
- DispatchSpawn(statue);
- }
- return statue;
- }
- public void OnSpawnLocationLoaded(Database db, DBResultSet results, const char[] error,
- any data) {
- if (!results.FetchRow()) {
- if (FindEntityByClassname(-1, "entity_soldier_statue") == -1) {
- char mapName[PLATFORM_MAX_PATH];
- GetCurrentMapDisplayName(mapName, sizeof(mapName));
-
- LogServer("%s does not have a Soldier statue", mapName);
- }
- return;
- }
-
- float position[3], angles[3];
- position[0] = results.FetchFloat(0);
- position[1] = results.FetchFloat(1);
- position[2] = results.FetchFloat(2);
-
- angles[0] = results.FetchFloat(3);
- angles[1] = results.FetchFloat(4);
- angles[2] = results.FetchFloat(5);
-
- TeleportEntity(GetSoldierStatueEntity(), position, angles, NULL_VECTOR);
- LogServer("Spawned Soldier statue");
- }
- public void OnSpawnLocationSaved(Database db, DBResultSet results, const char[] error,
- any data) {
- return;
- }
- /**
- * Obtains the end position in the world that a client is looking at.
- *
- * @param client The client to check.
- * @param vecAimPoint The buffer to store the position in the world on success.
- * @param filter The trace entity filter function to call when performing the check.
- * @param data A value to pass into the filter function callback.
- *
- * @return true if a valid position is found
- */
- stock bool GetClientAimEndPosition(int client, float vecAimPoint[3],
- TraceEntityFilter filter = INVALID_FUNCTION, any data = 0) {
- float angEye[3], vecStartPosition[3];
- GetClientEyePosition(client, vecStartPosition);
- GetClientEyeAngles(client, angEye);
-
- Handle trace = TR_TraceRayFilterEx(vecStartPosition, angEye, MASK_SHOT, RayType_Infinite,
- filter != INVALID_FUNCTION? filter : TraceEntityFilterPlayer, data);
- bool result = TR_DidHit(trace);
- if (TR_DidHit(trace)) {
- TR_GetEndPosition(vecAimPoint, trace);
- }
- delete trace;
- return result;
- }
- /**
- * Returns a trace ray handle in the client's aim direction.
- */
- stock Handle GetClientAimEndTrace(int client, int flags,
- TraceEntityFilter filter = INVALID_FUNCTION, any data = 0) {
- float angEye[3], vecStartPosition[3];
- GetClientEyePosition(client, vecStartPosition);
- GetClientEyeAngles(client, angEye);
-
- return TR_TraceRayFilterEx(vecStartPosition, angEye, flags, RayType_Infinite,
- filter != INVALID_FUNCTION? filter : TraceEntityFilterPlayer, data);
- }
- /**
- * Internal callback function that ignores player entities.
- */
- static stock bool TraceEntityFilterPlayer(int entity, int contentsMask) {
- return entity > MaxClients;
- }
|