-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathrampjudge.sp
156 lines (132 loc) · 4.73 KB
/
rampjudge.sp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#pragma semicolon 1
#include <sourcemod>
#include <sdkhooks>
#include <sdktools>
#define PLUGIN_VERSION "1.0"
ConVar g_cvGravity;
ConVar g_cvMaxVelocity;
new Handle:Hud;
float playerPrevPos[MAXPLAYERS + 1][3];
float playerPrevVel[MAXPLAYERS + 1][3];
float playerRampEnergy[MAXPLAYERS + 1];
float playerRampStartEnergy[MAXPLAYERS + 1];
float playerRampPostStartEnergy[MAXPLAYERS + 1];
bool playerPrevOnRamp[MAXPLAYERS + 1];
bool playerPrevOnRamp2[MAXPLAYERS + 1];
public Plugin:myinfo =
{
name = "Ramp testing",
author = "not_a_zombie",
description = "",
version = PLUGIN_VERSION,
url = ""
}
public OnPluginStart()
{
PrintToChatAll("plugin start");
Hud = CreateHudSynchronizer();
g_cvGravity = FindConVar("sv_gravity");
g_cvMaxVelocity = FindConVar("sv_maxvelocity");
}
public OnMapStart()
{
}
public Action OnPlayerRunCmd(int client)
{
if(IsClientObserver(client)){
if(EntRefToEntIndex(GetEntPropEnt(client,Prop_Send,"m_hObserverTarget",0)) > 0){
PrintEnergyLossTo(EntRefToEntIndex(GetEntPropEnt(client,Prop_Send,"m_hObserverTarget",0)),client);
}
}else{
PrintEnergyLoss(client);
}
return Plugin_Continue;
}
public void PrintEnergyLossTo(int client, int clientMessage){
if(playerPrevOnRamp2[client]){
SetHudTextParams(0.2, 0.4, 0.9, 255, 255, 255, 255, 0,0,0,0);
ShowSyncHudText(clientMessage, Hud, "Ramp Entry: %f\nRamp Loss: %f", playerRampStartEnergy[client]-playerRampPostStartEnergy[client], playerRampPostStartEnergy[client]-playerRampEnergy[client]);
}
}
public void PrintEnergyLoss(int client){
float pos[3];
float vel[3];
float playerMins[3];
float playerMaxs[3];
float playerTarget[3];
float onRamp = false;
GetClientAbsOrigin(client, pos);
GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", vel);
StartGravity(client,vel);
ScaleVector(vel, GetTickInterval());
GetClientMins(client, playerMins);
GetClientMaxs(client, playerMaxs);
AddVectors(pos, vel, playerTarget);
TR_TraceHullFilter(pos, playerTarget, playerMins, playerMaxs, MASK_SOLID_BRUSHONLY,PlayerFilter);
float nrm[3];
if (TR_DidHit())
{
TR_GetPlaneNormal(null, nrm);
if(nrm[2] < 0.7){
onRamp = true;
}
}
playerRampEnergy[client] = GetEnergy(client);
//they're about to get on the ramp
if(!playerPrevOnRamp[client] && onRamp){
playerRampStartEnergy[client] = playerRampEnergy[client];
}
//they just got on the ramp, post-velocity change
if(!playerPrevOnRamp2[client] && playerPrevOnRamp[client]){
playerRampPostStartEnergy[client] = playerRampEnergy[client];
//PrintToChatAll("%f %f",playerRampStartEnergy[client],playerRampPostStartEnergy[client]);
}
if(playerPrevOnRamp[client]){
SetHudTextParams(0.2, 0.4, 0.9, 255, 255, 255, 255, 0,0,0,0);
ShowSyncHudText(client, Hud, "Ramp Entry: %f\nRamp Loss: %f", playerRampStartEnergy[client]-playerRampPostStartEnergy[client], playerRampPostStartEnergy[client]-playerRampEnergy[client]);
}
playerPrevPos[client] = pos;
playerPrevVel[client] = vel;
playerPrevOnRamp2[client] = playerPrevOnRamp[client];
playerPrevOnRamp[client] = onRamp;
}
//lifted from rio's rngfix, thx
public bool PlayerFilter(int entity, int mask)
{
return !(1 <= entity <= MaxClients);
}
void StartGravity(int client, float velocity[3])
{
float localGravity = GetEntPropFloat(client, Prop_Data, "m_flGravity");
if (localGravity == 0.0) localGravity = 1.0;
velocity[2] -= localGravity * g_cvGravity.FloatValue * 0.5 * GetTickInterval() ;
float baseVelocity[3];
GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", baseVelocity);
velocity[2] += baseVelocity[2] * GetTickInterval();
// baseVelocity[2] would get cleared here but we shouldn't do that since this is just a prediction.
CheckVelocity(velocity);
}
void CheckVelocity(float velocity[3])
{
for (int i = 0; i < 3; i++)
{
if (velocity[i] > g_cvMaxVelocity.FloatValue) velocity[i] = g_cvMaxVelocity.FloatValue;
else if (velocity[i] < -g_cvMaxVelocity.FloatValue) velocity[i] = -g_cvMaxVelocity.FloatValue;
}
}
//this does not account for teleports or modified gravity
float GetEnergy(int client){
float playerVelocity[3];
float playerPosition[3];
float PlayerfSpeed;
GetEntPropVector(client, Prop_Data, "m_vecVelocity", playerVelocity);
GetEntPropVector(client, Prop_Data, "m_vecOrigin", playerPosition);
PlayerfSpeed = SquareRoot(playerVelocity[0]*playerVelocity[0] + playerVelocity[1]*playerVelocity[1] + playerVelocity[2]*playerVelocity[2]);
//the unit of the result is the height at which a player with 0 velocity would have the same energy as the current player
//this means that the kinetic energy is dependent on gravity
//PE = mgh
//KE = 1/2 mv^2
//1/2 v^2 = gh
//h = 1/2 v^2/g # h is the additional height equivalent of the kinetic energy
return PlayerfSpeed * PlayerfSpeed / g_cvGravity.IntValue / 2 + playerPosition[2];
}