mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 14:23:21 +00:00
Add methodmap for peek cam
This commit is contained in:
parent
90d191002a
commit
a1a7fde449
5 changed files with 143 additions and 95 deletions
Binary file not shown.
|
@ -6,14 +6,117 @@ bool isEnabled, lateLoaded;
|
|||
// Internal State
|
||||
char currentSet[16] = "default";
|
||||
char nextRoundMap[64];
|
||||
int seekerCam = INVALID_ENT_REFERENCE;
|
||||
bool isNavBlockersEnabled = true, isPropsEnabled = true, isPortalsEnabled = true;
|
||||
|
||||
int g_iLaserIndex;
|
||||
|
||||
// Gamemode state
|
||||
bool isPendingPlay[MAXPLAYERS+1];
|
||||
bool isViewingCam[MAXPLAYERS+1];
|
||||
|
||||
|
||||
// PeekCam specifics
|
||||
PeekCamera PeekCam;
|
||||
static int seekerCam = INVALID_ENT_REFERENCE;
|
||||
static bool isViewingCam[MAXPLAYERS+1];
|
||||
static int seekerTarget;
|
||||
|
||||
enum PeekPerspective {
|
||||
Cam_Unknown,
|
||||
Cam_FirstPerson,
|
||||
Cam_ThirdPerson
|
||||
}
|
||||
|
||||
methodmap PeekCamera {
|
||||
property int Target {
|
||||
public get() {
|
||||
return GetClientOfUserId(seekerTarget);
|
||||
}
|
||||
public set(int client) {
|
||||
this.Create();
|
||||
seekerTarget = GetClientUserId(client);
|
||||
|
||||
AcceptEntityInput(seekerCam, "ClearParent");
|
||||
AcceptEntityInput(seekerCam, "Disable");
|
||||
}
|
||||
}
|
||||
|
||||
property PeekPerspective Perspective {
|
||||
public set(PeekPerspective perspective) {
|
||||
this.SetPerspective(perspective);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPerspective(PeekPerspective perspective) {
|
||||
float pos[3], ang[3];
|
||||
int client = this.Target;
|
||||
GetClientEyePosition(client, pos);
|
||||
GetClientEyeAngles(client, ang);
|
||||
|
||||
if(perspective == Cam_FirstPerson) {
|
||||
|
||||
TeleportEntity(seekerCam, pos, ang, NULL_VECTOR);
|
||||
SetParent(seekerCam, client);
|
||||
SetParentAttachment(seekerCam, "primary", false);
|
||||
} else if(perspective == Cam_ThirdPerson) {
|
||||
float endPos[3];
|
||||
TR_TraceRayFilter(pos, ang, CONTENTS_PLAYERCLIP | MASK_SOLID | MASK_VISIBLE, RayType_Infinite, Filter_IgnoreAll);
|
||||
if(TR_DidHit()) {
|
||||
TR_GetEndPosition(endPos);
|
||||
}
|
||||
endPos[2] += 50.0;
|
||||
|
||||
ang[0] = 0.0;
|
||||
float deltaA = endPos[0] - pos[0];
|
||||
float deltaB = endPos[1] - pos[1];
|
||||
float deltaC = endPos[2] - pos[2];
|
||||
ang[0] = RadToDeg(ArcTangent(deltaC / GetVectorDistance(endPos, pos, false) ));
|
||||
ang[1] = RadToDeg(ArcTangent2(deltaA, deltaB));
|
||||
TeleportEntity(seekerCam, endPos, ang, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetViewing(int client, bool active) {
|
||||
if(seekerCam != INVALID_ENT_REFERENCE) {
|
||||
AcceptEntityInput(seekerCam, "Enable", client); // Need to always activate before deactivating to fix a semi-common bug
|
||||
if(!active) {
|
||||
AcceptEntityInput(seekerCam, "Disable", client);
|
||||
AcceptEntityInput(seekerCam, "Kill");
|
||||
seekerCam = INVALID_ENT_REFERENCE;
|
||||
}
|
||||
} else {
|
||||
PrintToServer("WARN: SetPeekCamActive(%d, %b) when seekerCam invalid", client, active);
|
||||
}
|
||||
isViewingCam[client] = active;
|
||||
}
|
||||
|
||||
public bool IsViewing(int client) {
|
||||
return isViewingCam[client];
|
||||
}
|
||||
|
||||
public void Create() {
|
||||
if(seekerCam == INVALID_ENT_REFERENCE || !IsValidEntity(seekerCam)) {
|
||||
seekerCam = CreateEntityByName("point_viewcontrol_survivor");
|
||||
DispatchKeyValue(seekerCam, "targetname", "hscam");
|
||||
DispatchSpawn(seekerCam);
|
||||
for(int i = 0; i <= MaxClients; i++) {
|
||||
isViewingCam[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Exists() {
|
||||
return seekerCam != INVALID_ENT_REFERENCE && IsValidEntity(seekerCam)
|
||||
}
|
||||
|
||||
public void Destroy() {
|
||||
if(seekerCam == INVALID_ENT_REFERENCE || !IsValidEntity(seekerCam)) {
|
||||
seekerTarget = 0;
|
||||
AcceptEntityInput(seekerCam, "Disable");
|
||||
AcceptEntityInput(seekerCam, "Kill");
|
||||
seekerCam = INVALID_ENT_REFERENCE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum struct EntityConfig {
|
||||
|
@ -39,3 +142,19 @@ MapConfig mapConfig;
|
|||
ArrayList validMaps;
|
||||
ArrayList validSets;
|
||||
|
||||
stock void SetParent(int child, int parent) {
|
||||
SetVariantString("!activator");
|
||||
AcceptEntityInput(child, "SetParent", parent);
|
||||
}
|
||||
|
||||
stock void SetParentAttachment(int child, const char[] attachment, bool withOffset = false) {
|
||||
SetVariantString(attachment);
|
||||
if(withOffset)
|
||||
AcceptEntityInput(child, "SetParentAttachmentMaintainOffset");
|
||||
else
|
||||
AcceptEntityInput(child, "SetParentAttachment");
|
||||
}
|
||||
|
||||
stock void ClearParent(int child) {
|
||||
AcceptEntityInput(child, "ClearParent");
|
||||
}
|
|
@ -217,17 +217,17 @@ public Action Command_HideAndSeek(int client, int args) {
|
|||
if(IsBotsEnabled()) ReplyToCommand(client, "Bots are enabled");
|
||||
else ReplyToCommand(client, "Bots are disabled");
|
||||
} else if(StrEqual(subcmd, "peekfix")) {
|
||||
if(seekerCam == INVALID_ENT_REFERENCE) {
|
||||
SetPeekCamTarget(client);
|
||||
if(!PeekCam.Exists()) {
|
||||
PeekCam.Target = client;
|
||||
}
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i)) {
|
||||
SetPeekCamActive(client, false);
|
||||
SetPeekCamActive(client, false);
|
||||
PeekCam.SetViewing(client, true);
|
||||
PeekCam.SetViewing(client, false);
|
||||
}
|
||||
}
|
||||
AcceptEntityInput(seekerCam, "Kill");
|
||||
PeekCam.Destroy();
|
||||
ReplyToCommand(client, "Killing active camera");
|
||||
} else if(StrEqual(subcmd, "seeker")) {
|
||||
if(args == 2) {
|
||||
|
|
|
@ -12,11 +12,8 @@ void Cleanup() {
|
|||
EntFire("hsprop", "kill");
|
||||
EntFire("hsblocker", "kill");
|
||||
EntFire("hsportal", "kill");
|
||||
if(seekerCam != INVALID_ENT_REFERENCE && IsValidEntity(seekerCam)) {
|
||||
AcceptEntityInput(seekerCam, "Disable");
|
||||
AcceptEntityInput(seekerCam, "Kill");
|
||||
seekerCam = INVALID_ENT_REFERENCE;
|
||||
}
|
||||
PeekCam.Destroy();
|
||||
|
||||
}
|
||||
|
||||
GameState GetState() {
|
||||
|
@ -196,75 +193,6 @@ stock void GetHorizontalPositionFromClient(int client, float units, float finalP
|
|||
finalPosition = pos;
|
||||
}
|
||||
|
||||
stock void SetParent(int child, int parent) {
|
||||
SetVariantString("!activator");
|
||||
AcceptEntityInput(child, "SetParent", parent);
|
||||
}
|
||||
|
||||
stock void SetParentAttachment(int child, const char[] attachment, bool withOffset = false) {
|
||||
SetVariantString(attachment);
|
||||
if(withOffset)
|
||||
AcceptEntityInput(child, "SetParentAttachmentMaintainOffset");
|
||||
else
|
||||
AcceptEntityInput(child, "SetParentAttachment");
|
||||
}
|
||||
|
||||
stock void ClearParent(int child) {
|
||||
AcceptEntityInput(child, "ClearParent");
|
||||
}
|
||||
|
||||
void SetPeekCamTarget(int target, bool showFPOV = false) {
|
||||
if(seekerCam == INVALID_ENT_REFERENCE || !IsValidEntity(seekerCam)) {
|
||||
seekerCam = CreateEntityByName("point_viewcontrol_survivor");
|
||||
DispatchKeyValue(seekerCam, "targetname", "hscam");
|
||||
DispatchSpawn(seekerCam);
|
||||
for(int i = 0; i <= MaxClients; i++) {
|
||||
isViewingCam[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
AcceptEntityInput(seekerCam, "ClearParent");
|
||||
AcceptEntityInput(seekerCam, "Disable");
|
||||
|
||||
float pos[3], endPos[3], ang[3];
|
||||
GetClientEyePosition(target, pos);
|
||||
GetClientEyeAngles(target, ang);
|
||||
if(showFPOV) {
|
||||
TeleportEntity(seekerCam, pos, ang, NULL_VECTOR);
|
||||
SetParent(seekerCam, target);
|
||||
SetParentAttachment(seekerCam, "primary", false);
|
||||
} else {
|
||||
TR_TraceRayFilter(pos, ang, CONTENTS_PLAYERCLIP | MASK_SOLID | MASK_VISIBLE, RayType_Infinite, Filter_IgnoreAll);
|
||||
if(TR_DidHit()) {
|
||||
TR_GetEndPosition(endPos);
|
||||
}
|
||||
endPos[2] += 50.0;
|
||||
|
||||
ang[0] = 0.0;
|
||||
float deltaA = endPos[0] - pos[0];
|
||||
float deltaB = endPos[1] - pos[1];
|
||||
float deltaC = endPos[2] - pos[2];
|
||||
ang[0] = RadToDeg(ArcTangent(deltaC / GetVectorDistance(endPos, pos, false) ));
|
||||
ang[1] = RadToDeg(ArcTangent2(deltaA, deltaB));
|
||||
|
||||
TeleportEntity(seekerCam, endPos, ang, NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
// int GetClientsInRange(const float origin[3], ClientRangeType rangeType, int[] clients, int size)
|
||||
void SetPeekCamActive(int client, bool active) {
|
||||
if(seekerCam != INVALID_ENT_REFERENCE) {
|
||||
AcceptEntityInput(seekerCam, "Enable", client); // Need to always activate before deactivating to fix a semi-common bug
|
||||
if(!active) {
|
||||
AcceptEntityInput(seekerCam, "Disable", client);
|
||||
}
|
||||
} else {
|
||||
PrintToServer("WARN: SetPeekCamActive(%d, %b) when seekerCam invalid", client, active);
|
||||
}
|
||||
isViewingCam[client] = active;
|
||||
}
|
||||
|
||||
|
||||
stock void GetAnglesLookAt(int iClient, int iTarget, float fFinalPos[3]) {
|
||||
static float fTargetPos[3];
|
||||
static float fTargetAngles[3];
|
||||
|
|
|
@ -145,7 +145,6 @@ public void OnClientDisconnect(int client) {
|
|||
public void OnMapStart() {
|
||||
if(!isEnabled) return;
|
||||
|
||||
seekerCam = INVALID_ENT_REFERENCE;
|
||||
currentSeeker = 0;
|
||||
|
||||
if(cvar_abm_autohard != null) {
|
||||
|
@ -187,7 +186,7 @@ public void OnMapStart() {
|
|||
int seeker = GetSlasher();
|
||||
if(seeker > -1) {
|
||||
currentSeeker = seeker;
|
||||
SetPeekCamTarget(currentSeeker);
|
||||
PeekCam.Target = currentSeeker;
|
||||
PrintToServer("[H&S] Late load, found seeker %N", currentSeeker);
|
||||
}
|
||||
if(IsGameSoloOrPlayersLoading()) {
|
||||
|
@ -269,11 +268,10 @@ const float DEATH_CAM_MIN_DIST = 150.0;
|
|||
public Action Timer_StopPeekCam(Handle h) {
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i)) {
|
||||
SetPeekCamActive(i, false);
|
||||
PeekCam.SetViewing(i, false);
|
||||
}
|
||||
}
|
||||
AcceptEntityInput(seekerCam, "Kill");
|
||||
seekerCam = INVALID_ENT_REFERENCE;
|
||||
PeekCam.Destroy();
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
|
@ -282,20 +280,21 @@ public void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast
|
|||
int attacker = GetClientOfUserId(event.GetInt("attacker"));
|
||||
|
||||
if(!gameOver && client && GetClientTeam(client) == 2) {
|
||||
SetPeekCamTarget(attacker > 0 ? attacker : client, true);
|
||||
PeekCam.Target = attacker > 0 ? attacker : client;
|
||||
PeekCam.Perspective = Cam_FirstPerson;
|
||||
|
||||
int alive = 0;
|
||||
float pos[3], checkPos[3];
|
||||
if(attacker <= 0) attacker = client;
|
||||
GetClientAbsOrigin(attacker, pos);
|
||||
SetPeekCamActive(attacker, true);
|
||||
PeekCam.SetViewing(attacker, true);
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
if(attacker > 0 && attacker != client) {
|
||||
if(cvar_peekCam.IntValue & 2) {
|
||||
GetClientAbsOrigin(i, checkPos);
|
||||
if(GetVectorDistance(checkPos, pos) > DEATH_CAM_MIN_DIST) {
|
||||
SetPeekCamActive(i, true);
|
||||
PeekCam.SetViewing(i, true);
|
||||
}
|
||||
}
|
||||
alive++;
|
||||
|
@ -319,7 +318,8 @@ public void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast
|
|||
CPrintToChatAll("{green}The seeker %N won!", currentSeeker);
|
||||
}
|
||||
if(cvar_peekCam.IntValue & 1) {
|
||||
SetPeekCamTarget(client, false);
|
||||
PeekCam.Target = client;
|
||||
PeekCam.Perspective = Cam_ThirdPerson;
|
||||
}
|
||||
gameOver = true;
|
||||
return;
|
||||
|
@ -360,7 +360,7 @@ public void Event_ItemPickup(Event event, const char[] name, bool dontBroadcast)
|
|||
} else if(currentSeeker != client) {
|
||||
PrintToChatAll("[H&S] Seeker does not equal axe-receiver. Possible seeker: %N", client);
|
||||
}
|
||||
SetPeekCamTarget(currentSeeker);
|
||||
PeekCam.Target = currentSeeker;
|
||||
if(!ignoreSeekerBalance && cvar_seekerBalance.BoolValue) {
|
||||
if(hasBeenSeeker[currentSeeker]) {
|
||||
ArrayList notPlayedSeekers = new ArrayList(1);
|
||||
|
@ -399,7 +399,7 @@ public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast
|
|||
if(client > 0 && mapConfig.hasSpawnpoint) {
|
||||
TeleportEntity(client, mapConfig.spawnpoint, NULL_VECTOR, NULL_VECTOR);
|
||||
}
|
||||
isViewingCam[client] = false;
|
||||
PeekCam.SetViewing(client, false);
|
||||
}
|
||||
|
||||
public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) {
|
||||
|
@ -427,7 +427,7 @@ public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) {
|
|||
for(int i = 1; i <= MaxClients; i++) {
|
||||
isNearbyPlaying[i] = false;
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 1) {
|
||||
SetPeekCamActive(i, false);
|
||||
PeekCam.SetViewing(i, false);
|
||||
if(isPendingPlay[i]) {
|
||||
ChangeClientTeam(i, 2);
|
||||
L4D_RespawnPlayer(i);
|
||||
|
@ -437,6 +437,7 @@ public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) {
|
|||
isPendingPlay[i] = false;
|
||||
}
|
||||
}
|
||||
PeekCam.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,7 +481,7 @@ public Action Timer_Music(Handle h) {
|
|||
if(prevState == State_Hiding) {
|
||||
changedToHunting = true;
|
||||
ShowBeacon(currentSeeker);
|
||||
SetPeekCamTarget(currentSeeker);
|
||||
PeekCam.Target = currentSeeker;
|
||||
}
|
||||
EmitSoundToClient(currentSeeker, SOUND_SUSPENSE_1, currentSeeker, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_CHANGEPITCH, 0.2, 90, currentSeeker, seekerLoc, seekerLoc, true);
|
||||
}
|
||||
|
@ -490,7 +491,7 @@ public Action Timer_Music(Handle h) {
|
|||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && i != currentSeeker) {
|
||||
if(changedToHunting)
|
||||
SetPeekCamActive(i, true);
|
||||
PeekCam.SetViewing(i, true);
|
||||
playerCount++;
|
||||
GetClientAbsOrigin(i, playerLoc);
|
||||
float dist = GetVectorDistance(seekerLoc, playerLoc, true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue