forked from PMArkive/random-shavit-bhoptimer-stuff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tpfix_csgo.sp
171 lines (137 loc) · 4.82 KB
/
tpfix_csgo.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <sdktools>
#pragma newdecls required
#pragma semicolon 1
public Plugin myinfo =
{
name = "TPFix",
author = "rio",
description = "Ensure all teleport destinations are a minimum distance off the ground so players dont get stopped",
version = "1.0.2",
url = ""
};
#define BOTTOM_PAD 2.0
#define TOP_PAD 0.01
bool g_bLate;
ArrayList teleportTargets;
ArrayList fixedEntities;
char currentmap[64];
float MINS[3] = { -16.0, -16.0, -BOTTOM_PAD };
float MAXS[3] = { 16.0, 16.0, TOP_PAD };
float HEIGHT = 72.0; // height of the player's bounding box while uncrouched
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
g_bLate = late;
return APLRes_Success;
}
public void OnPluginStart()
{
teleportTargets = new ArrayList(64);
fixedEntities = new ArrayList();
if (g_bLate)
{
int entity = -1;
while ((entity = FindEntityByClassname(entity, "trigger_teleport")) != -1) CheckTeleport(entity);
}
}
public void OnMapStart()
{
teleportTargets.Clear();
fixedEntities.Clear();
GetCurrentMap(currentmap, sizeof(currentmap));
}
public void OnTeleportCreated_Delayed(int entity)
{
if (IsValidEntity(entity)) CheckTeleport(entity);
}
public void OnEntityCreated_Delayed(int entity)
{
if (IsValidEntity(entity))
{
char name[64];
GetEntPropString(entity, Prop_Data, "m_iName", name, sizeof(name));
if (teleportTargets.FindString(name) != -1) CheckDestination(entity);
}
}
public void OnEntityCreated(int entity, const char[] classname)
{
// delay entity checking so datamaps can be initialized
if (StrEqual(classname, "trigger_teleport")) RequestFrame(OnTeleportCreated_Delayed, entity);
RequestFrame(OnEntityCreated_Delayed, entity);
}
public bool PlayerFilter(int entity, int mask)
{
return !(0 < entity <= MaxClients);
}
void CheckTeleport(int teleportEnt)
{
char target[64], landmark[64];
if (GetEntPropString(teleportEnt, Prop_Data, "m_target", target, sizeof(target)) == 0) return;
if (target[0] == '\0') return;
// ignore landmarked teleporters
if (GetEntPropString(teleportEnt, Prop_Data, "m_iLandmark", landmark, sizeof(landmark)) != 0) return;
char target2[64];
for (int targetEnt = 1; targetEnt <= 2048; targetEnt++)
{
if (!IsValidEntity(targetEnt)) continue;
if (GetEntPropString(targetEnt, Prop_Data, "m_iName", target2, sizeof(target2)) == 0) continue;
if (target2[0] == '\0') continue;
if (StrEqual(target2, target)) CheckDestination(targetEnt);
}
// store the teleport target name so we can check entities that haven't loaded at this point when they do load
teleportTargets.PushString(target);
}
void CheckDestination(int targetEnt)
{
int ref = EntIndexToEntRef(targetEnt);
if (fixedEntities.FindValue(ref) != -1) return;
fixedEntities.Push(ref);
// if a teleporter is the target of another teleporter, the mapper probably messed up
// there isn't an easy way to know if it really was a mistake though, so just dont move it
char classname[128];
GetEntPropString(targetEnt, Prop_Data, "m_iClassname", classname, sizeof(classname));
if (StrEqual(classname, "trigger_teleport")) return;
char name[64];
GetEntPropString(targetEnt, Prop_Data, "m_iName", name, sizeof(name));
if (StrEqual(currentmap, "bhop_kz_ethereal", false) && StrEqual(name, "room", false)) return; // ???
if (StrEqual(currentmap, "surf_asrown", false) && StrEqual(name, "part2", false)) return; // ???
float origin[3], to[3], end[3];
GetEntPropVector(targetEnt, Prop_Send, "m_vecOrigin", origin);
origin[2] = origin[2] + HEIGHT/2;
float bottom, top;
to[0] = origin[0];
to[1] = origin[1];
to[2] = origin[2] - HEIGHT/2 - 10;
TR_TraceHullFilter(origin, to, MINS, MAXS, MASK_PLAYERSOLID_BRUSHONLY, PlayerFilter);
if (TR_DidHit())
{
TR_GetEndPosition(end);
if (origin[2] - end[2] < HEIGHT/2) bottom = HEIGHT/2 - (origin[2] - end[2]);
}
to[0] = origin[0];
to[1] = origin[1];
to[2] = origin[2] + HEIGHT/2 + 10;
TR_TraceHullFilter(origin, to, MINS, MAXS, MASK_PLAYERSOLID_BRUSHONLY, PlayerFilter);
if (TR_DidHit())
{
TR_GetEndPosition(end);
if (end[2] - origin[2] < HEIGHT/2) top = HEIGHT/2 - (end[2] - origin[2]);
}
origin[2] = origin[2] - HEIGHT/2;
if (top > 0.0 && bottom > 0.0)
{
//PrintToServer("[TPFix] Cannot fix teleport destination \"%s\" (%u)", name, ref);
return;
}
else if (top > 0.0)
{
//PrintToServer("[TPFix] Adjusting teleport destination \"%s\" (%u) DOWN by %.2f", name, ref, top);
origin[2] = origin[2] - top;
TeleportEntity(targetEnt, origin, NULL_VECTOR, NULL_VECTOR);
}
else if (bottom > 0.0)
{
//PrintToServer("[TPFix] Adjusting teleport destination \"%s\" (%u) UP by %.2f", name, ref, bottom);
origin[2] = origin[2] + bottom;
TeleportEntity(targetEnt, origin, NULL_VECTOR, NULL_VECTOR);
}
}