hi, looking for someone to write a plugin which basically allows admins to spawn some amount of "prop_dynamic_override" entities ( to client origin/angles prob for better posing or aim) with any wanted special infected "model", and "DefaultAnim" for a specific animation if possible and saves these to a cfg file kv. Once enough models are placed it should spawn the 'camera' another entity that the client's view will be forced at ( SetClientViewEntity() ) when the round ends.
sm_spawnmodel <hunter> <def anim optional>
There's a server that switches your view automatically at the end of a survival round - to some special infected prompts. This only serves the purpose of making sure that when a player takes a screenshot of their survival time - they're not using any unlegit SI skins (bright skins, neon skins, etc) which would disqualify their record.
// this 'm_nSequence' part only works if you're spawned // as the infected you're making a prompt for, but makes it capture // what position you're in (e.g. if you're crouching)
int currentSequence = GetEntProp(client, Prop_Send, "m_nSequence"); SetEntProp(iEntity, Prop_Send, "m_nSequence", currentSequence);
I didn't think it was worth the time to code the entire plugin with the survival community being so small these days and all.
The most time consuming part of making the plugin would me making a helper menu (need to spawn yourself as an SI to properly capture your 'm_nSequence') and the KV file (maybe a database would be preferred).
I think the simplest way to do this would be to spawn all the models at once and have the survivor camera positions angled so it only captures one area the SI prompts are spawned in (so they don't overlap).
Last edited by dustinandband; 09-20-2019 at 01:07.
Reason: updated function and edited some info
We did end up writing the plugin but there's one issue with spectators - their camera gets stuck in walls sometimes (this only happens to spectators and not survivors). This only happens after the camera scene (not 100% of the time) and there's no way to unstuck except to either join the survivor team, or reconnect. Example: https://youtu.be/wOJ6y4lAHEs
As a workaround we made it so the point_viewcontrol_multiplayer (camera) entity gets disabled right before the round resets: https://github.com/graviti666/l4d2-s...Posing.sp#L403
From the video, you can tell there's a brief moment where the camera goes into third-shoulder spectate mode before going back to the survivor's POV: https://youtu.be/fwW9s1H9g68
The original author we're copying seems to have not needed this, you can tell in his server it goes straight from the camera to the survivor's first person view: https://youtu.be/llAIsqJiwJ4
Just learned today that spectators can still get stuck in walls with our work-around, and I don't want to disable the camera entity any sooner than I already am. The example server ('ohm server example' video) doesn't disable the camera entity early either - so I'm wondering if anyone has suggestions for any workarounds at this point? I'd rather the camera go straight back to the survivor's POV (without that little third-person shoulder spectate moment) like the third video link example shows.
Kind of hard to test this cause it only happens once in a blue moon and I've already spent one day trying to debug the issue before. Unfortuantely there's barely any code snippets on google that contain "point_viewcontrol_multiplayer" so i was hoping one of you had a suggestion.
(Side note that I already tried manually teleporting any spectators once the round restarts but even that doesn't work: https://youtu.be/0M6vlQ-HGug )
What do you mean about getting stuck in walls? They are not able to move or just has the view spawn bug?
One of the possibilities is that the spectator is being teleported to the "0, 0, 0" position, which depending on the map can be "inside wall".
Maybe what you can do is to use the "SetTransmit" method and don't send the camera entity to spec players
yeah - they're unable to move once they're spawned inside the walls
the "Hook_SetTransmit" hook isn't picking up point_viewcontrol_multiplayer entity. I verified that it gets picked up with "OnEntityCreated" though
Spoiler
PHP Code:
#include <sourcemod> #include <sdkhooks>
// this doesn't detect the entity: public void OnClientPutInServer(int client) { SDKHook(client, SDKHook_SetTransmit, Hook_SetTransmit); }
public Action Hook_SetTransmit(int entity, int client) { if( IsValidEdict(entity)) { char sEntityClass[56]; GetEntityClassname(entity, sEntityClass, sizeof(sEntityClass));
if (StrEqual(sEntityClass, "point_viewcontrol_multiplayer")) { PrintToChatAll("IsEntityCamera function - ent ID %i, %s", entity, sEntityClass); } } // returning plugin_continue cause this is a detection test return Plugin_Continue; }
// works public void OnEntityCreated(int entity, const char[] classname) { if (StrEqual(classname, "point_viewcontrol_multiplayer")) { PrintToChatAll("OnEntityCreated function - ent ID %i, class: %s", entity, classname); } }
I did find out there's 5 additional point_viewcontrol_multiplayer entities that get called when the round's in the process of resetting. Though I don't think I got their location vectors correctly (probably cause I'm using the wrong classname when calling FindSendPropInfo()). But anyway it's an interesting thing to note. Maybe these interfere with the one that was just created beforehand?
public void OnClientPutInServer(int client) { SDKHook(client, SDKHook_SetTransmit, Hook_SetTransmit); }
public Action Hook_SetTransmit(int entity, int client) { if (IsEntityCamera(entity)) { return Plugin_Continue; // returning continue cause this is a test for now }
return Plugin_Continue; /* if (client && IsClientInGame(client) && GetClientTeam(client) == 1 && IsEntityCamera(entity)) { PrintToChatAll("client %N is a spectator - not transmitting to him", client); return Plugin_Handled; } return Plugin_Continue;*/ }
PrintToChatAll("\x01Camera entity detected: id \x04%i\x01, \x04position\x01: %f %f %f \x04angles\x01: %f %f %f", entity, position[0], position[1], position[2], angle[0], angle[1], angle[2]); LogToFile(g_sDebugLog, "Camera entity detected: id %i, position: %f %f %f angles: %f %f %f", entity, position[0], position[1], position[2], angle[0], angle[1], angle[2]); /* Camera entity detected: id 443 -- end round SI pose camera
Camera entity detected: id 256 -- these ones where called when the round resets... Camera entity detected: id 306 Camera entity detected: id 307 Camera entity detected: id 625 Camera entity detected: id 626 */
} }
// teleporting to see where these are getting spawned at public Action TeleportToCameraEnt(Handle timer, DataPack pack) { float position[3]; float angle[3];
I did some tests with the source code you provided (awesome) and I wasn't getting stuck while being spec.
Maybe is another plugin that is causing this issue? Try to test with a clean SM install. (aka removing the other plugins, except the default ones).
Also I had to comment the time check, because it wasn't firing the camera event. (still shows twice, is better to check that with a bool value maybe)
My test server is completely vanilla with minimal plugins / extensions installed.
The only cvars I'm using at the moment are these to keep the server from shutting down when I go to spectate and there's no other human survivors.
Though on another server I had the same issue happen and I didn't have any of these cvars enabled:
using this test plugin in the video. In most of the clips on that YouTube link I'm already on team spectate:
Spoiler
PHP Code:
#include <sourcemod>
#include <sdktools>
#pragma semicolon 1
#pragma newdecls required
#define SPEC 1
#define SURV 2
#define INF 3
public Plugin myinfo = {
name = "camera test",
author = "dustin",
description = "quick test",
version = "1.0",
url = ""
};
public void OnPluginStart()
{
RegAdminCmd("sm_spawncamera", Command_SpawnCamera, ADMFLAG_GENERIC);
}
public Action Command_SpawnCamera(int client, int args)
{
if (!client || !IsClientInGame(client))
{
ReplyToCommand(client, "can only use this command in-game.");
return Plugin_Handled;
}
public Action Timer_SlayAll(Handle timer, any data)
{
for (int i = 1; i <= MaxClients; i++)
{
if (!IsClientInGame(i)) continue;
if (GetClientTeam(i) == SURV || GetClientTeam(i) == INF)
ForcePlayerSuicide(i);
}
return Plugin_Handled;
}
Sorry for all the bumps but it's important to me that this plugin actually works.
I'm out of ideas on how to debug the issue further and have already tried hacky stuff like teleporting spectators shortly after "rout_start" gets called which didn't work.
edit:
Issue appears to only occur on linux servers. The "ohm's server example" video and Martt both used windows and they couldn't reproduce the issue. ohm looked at the source code for his plugin and said his method of dispatching the "point_viewcontrol_multiplayer" entity was exactly the same and he doesn't use any special methods of disabling it beforhand (just lets it kill itself when the round resets).
Last edited by dustinandband; 11-14-2019 at 14:47.