AMXX-BG.INFO superspawns.inc Raw include

superspawns.inc

Original include source with line numbers.

Back Download .inc
1 #if defined _superspawns_included
2 #endinput
3 #endif
4 #define _superspawns_included
5
6 #include <amxmodx>
7 #include <amxmisc>
8 #include <fakemeta>
9 #include <engine>
10 #include <cellarray>
11 #include <xs>
12
13 #define SS_VERSION "1.0"
14 #define SS_MIN_DISTANCE 500.0
15 #define SS_MAX_LOOPS 100000
16
17 new Array:g_vecSsOrigins
18 new Array:g_vecSsSpawns
19 new Array:g_vecSsUsed
20 new Float:g_flSsMinDist
21 new g_iSsTime
22
23 new const g_szStarts[][] = { "info_player_start", "info_player_deathmatch" }
24 new const Float:g_flOffsets[] = { 3500.0, 3500.0, 1500.0 }
25
26 public SsInit(Float:mindist)
27 {
28 new cmd[32]
29 format(cmd, 15, "_ss_dump%c%c%c%c", random_num('A', 'Z'), random_num('A', 'Z'), random_num('A', 'Z'), random_num('A', 'Z'))
30 register_cvar("sv_superspawns", SS_VERSION, (FCVAR_SERVER|FCVAR_SPONLY))
31 register_concmd(cmd, "SsDump")
32
33 g_flSsMinDist = mindist
34 g_vecSsOrigins = ArrayCreate(3, 1)
35 g_vecSsSpawns = ArrayCreate(3, 1)
36 g_vecSsUsed = ArrayCreate(3, 1)
37 }
38
39 stock SsClean()
40 {
41 g_flSsMinDist = 0.0
42 ArrayClear(g_vecSsOrigins)
43 ArrayClear(g_vecSsSpawns)
44 ArrayClear(g_vecSsUsed)
45 }
46
47 stock SsGetOrigin(Float:origin[3])
48 {
49 new Float:data[3], size
50 new ok = 1
51
52 while((size = ArraySize(g_vecSsOrigins)))
53 {
54 new idx = random_num(0, size - 1)
55
56 ArrayGetArray(g_vecSsOrigins, idx, origin)
57
58 new used = ArraySize(g_vecSsUsed)
59 for(new i = 0; i < used; i++)
60 {
61 ok = 0
62 ArrayGetArray(g_vecSsUsed, i, data)
63 if(get_distance_f(data, origin) >= g_flSsMinDist)
64 {
65 ok = 1
66 break
67 }
68 }
69
70 ArrayDeleteItem(g_vecSsOrigins, idx)
71 if(ok)
72 {
73 ArrayPushArray(g_vecSsUsed, origin)
74 return true
75 }
76 }
77 return false
78 }
79
80 public SsDump()
81 {
82 new Float:origin[3]
83 new count = ArraySize(g_vecSsOrigins)
84 server_print("-------------------------------------------------------")
85 for(new i = 0; i < count; i++)
86 {
87 ArrayGetArray(g_vecSsOrigins, i, origin)
88 server_print("Origin: %f %f %f", origin[0], origin[1], origin[2])
89 }
90 server_print("-------------------------------------------------------")
91 server_print("Number of origins: %i", count)
92 server_print("Time: %i", g_iSsTime)
93 server_print("-------------------------------------------------------")
94 }
95
96 public SsScan()
97 {
98 new start, Float:origin[3], starttime
99 starttime = get_systime()
100 for(start = 0; start < sizeof(g_szStarts); start++)
101 {
102 server_print("Searching for %s", g_szStarts[start])
103 new ent
104 if((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", g_szStarts[start])))
105 {
106 new counter
107 pev(ent, pev_origin, origin)
108 ArrayPushArray(g_vecSsSpawns, origin)
109 while(counter < SS_MAX_LOOPS)
110 {
111 counter = GetLocation(origin, counter)
112 }
113 }
114 }
115 g_iSsTime = get_systime()
116 g_iSsTime -= starttime
117 }
118
119 GetLocation(Float:start[3], &counter)
120 {
121 new Float:end[3]
122 for(new i = 0; i < 3; i++)
123 {
124 end[i] += random_float(0.0 - g_flOffsets[i], g_flOffsets[i])
125 }
126
127 if(IsValid(start, end))
128 {
129 start[0] = end[0]
130 start[1] = end[1]
131 start[2] = end[2]
132 ArrayPushArray(g_vecSsOrigins, end)
133 }
134 counter++
135 return counter
136 }
137
138 IsValid(Float:start[3], Float:end[3])
139 {
140 SetFloor(end)
141 end[2] += 36.0
142 new point = engfunc(EngFunc_PointContents, end)
143 if(point == CONTENTS_EMPTY)
144 {
145 if(CheckPoints(end) && CheckDistance(end) && CheckVisibility(start, end))
146 {
147 if(!trace_hull(end, HULL_LARGE, -1))
148 {
149 return true
150 }
151 }
152 }
153 return false
154 }
155
156 CheckVisibility(Float:start[3], Float:end[3])
157 {
158 new tr
159 engfunc(EngFunc_TraceLine, start, end, IGNORE_GLASS, -1, tr)
160 return (get_tr2(tr, TR_pHit) < 0)
161 }
162
163 SetFloor(Float:start[3])
164 {
165 new tr, Float:end[3]
166 end[0] = start[0]
167 end[1] = start[1]
168 end[2] = -99999.9
169 engfunc(EngFunc_TraceLine, start, end, DONT_IGNORE_MONSTERS, -1, tr)
170 get_tr2(tr, TR_vecEndPos, start)
171 }
172
173 CheckPoints(Float:origin[3])
174 {
175 new Float:data[3], tr, point
176 data[0] = origin[0]
177 data[1] = origin[1]
178 data[2] = 99999.9
179 engfunc(EngFunc_TraceLine, origin, data, DONT_IGNORE_MONSTERS, -1, tr)
180 get_tr2(tr, TR_vecEndPos, data)
181 point = engfunc(EngFunc_PointContents, data)
182 if(point == CONTENTS_SKY && get_distance_f(origin, data) < 250.0)
183 {
184 return false
185 }
186 data[2] = -99999.9
187 engfunc(EngFunc_TraceLine, origin, data, DONT_IGNORE_MONSTERS, -1, tr)
188 get_tr2(tr, TR_vecEndPos, data)
189 point = engfunc(EngFunc_PointContents, data)
190 if(point < CONTENTS_SOLID)
191 return false
192
193 return true
194 }
195
196 CheckDistance(Float:origin[3])
197 {
198 new Float:dist, Float:data[3]
199 new count = ArraySize(g_vecSsSpawns)
200 for(new i = 0; i < count; i++)
201 {
202 ArrayGetArray(g_vecSsSpawns, i, data)
203 dist = get_distance_f(origin, data)
204 if(dist < SS_MIN_DISTANCE)
205 return false
206 }
207
208 count = ArraySize(g_vecSsOrigins)
209 for(new i = 0; i < count; i++)
210 {
211 ArrayGetArray(g_vecSsOrigins, i, data)
212 dist = get_distance_f(origin, data)
213 if(dist < SS_MIN_DISTANCE)
214 return false
215 }
216
217 return true
218 }
219