AMXX-BG.INFO rog.inc Raw include

rog.inc

Original include source with line numbers.

Back Download .inc
1 #if defined _rog_included
2 #endinput
3 #endif
4 #define _rog_included
5
6 #include <amxmodx>
7 #include <fakemeta>
8 #include <engine>
9 #include <fun>
10
11 new const PrimaryDefaultMapEntities[][] =
12 {
13 "func_bomb_target",
14 "func_hostage_rescue",
15 "info_player_start",
16 "info_player_deathmatch",
17 "func_escapezone",
18 "func_vip_safetyzone",
19 "info_vip_start"
20 }
21
22 new const SecondaryDefaultMapEntities[][] =
23 {
24 "info_bomb_target",
25 "info_hostage_rescue"
26 }
27
28 new Array:DefaultMapEntitiesArray
29 new Array:FoundOriginsArray
30
31 new CurrentPositionInArray
32
33 stock ROGInitialize(Float:MinDistance, const CheckFunction[] = "")
34 {
35 new i
36 if(DefaultMapEntitiesArray == Invalid_Array)
37 {
38 //We find the origin of default map entities and search around this places
39 DefaultMapEntitiesArray = ArrayCreate()
40 for(i = 0; i < sizeof PrimaryDefaultMapEntities; i++)
41 {
42 if(!AddEntityIfFound(PrimaryDefaultMapEntities[i]))
43 {
44 if(i < 2)
45 {
46 AddEntityIfFound(SecondaryDefaultMapEntities[i])
47 }
48 }
49 }
50 }
51
52 new Size = ArraySize(DefaultMapEntitiesArray)
53 if(Size)
54 {
55 new Float:EntityOrigin[3], Float:OriginToCompare[3], EntityIndex, j
56 if(FoundOriginsArray == Invalid_Array)
57 {
58 FoundOriginsArray = ArrayCreate(3)
59 }
60 else
61 {
62 //Support for multiple calls for ROGInitialize
63 ArrayClear(FoundOriginsArray)
64 }
65
66 for(i = 0; i < Size; i++)
67 {
68 EntityIndex = ArrayGetCell(DefaultMapEntitiesArray, i)
69 pev(EntityIndex, pev_origin, EntityOrigin)
70
71 SearchForOrigins(EntityOrigin, 5000.0, CheckFunction)
72 }
73
74 //Remove origins that are too close
75 for(i = 0; i < ArraySize(FoundOriginsArray) - 1; i++)
76 {
77 ArrayGetArray(FoundOriginsArray, i, EntityOrigin)
78
79 for(j = i + 1; j < ArraySize(FoundOriginsArray); j++)
80 {
81 ArrayGetArray(FoundOriginsArray, j, OriginToCompare)
82
83 if(get_distance_f(EntityOrigin, OriginToCompare) < MinDistance)
84 {
85 ArrayDeleteItem(FoundOriginsArray, j)
86 j = j - 1
87 }
88 }
89 }
90 }
91 }
92
93 stock ROGGetOrigin(Float:Origin[3])
94 {
95 if(CurrentPositionInArray >= ArraySize(FoundOriginsArray))
96 {
97 CurrentPositionInArray = 0
98 }
99
100 ArrayGetArray(FoundOriginsArray, CurrentPositionInArray, Origin)
101 CurrentPositionInArray = CurrentPositionInArray + 1
102 }
103
104 stock ROGShuffleOrigins()
105 {
106 new Size = ArraySize(FoundOriginsArray), j, Float:FirstOrigin[3], Float:SecondOrigin[3]
107 for (new i = Size - 1; i > 0; i--)
108 {
109 j = random_num(0, i)
110 ArrayGetArray(FoundOriginsArray, i, FirstOrigin)
111 ArrayGetArray(FoundOriginsArray, j, SecondOrigin)
112 ArraySetArray(FoundOriginsArray, i, SecondOrigin)
113 ArraySetArray(FoundOriginsArray, j, FirstOrigin)
114 }
115 }
116
117 stock ROGDumpOriginData()
118 {
119 new Float:EntityOrigin[3], i
120 new Size = ArraySize(FoundOriginsArray)
121
122 for(i = 0; i < Size; i++)
123 {
124 ArrayGetArray(FoundOriginsArray, i, EntityOrigin)
125 server_print("[%d] %f %f %f", i, EntityOrigin[0], EntityOrigin[1], EntityOrigin[2])
126 }
127
128 server_print("Generated %d random origins", i)
129 }
130
131 stock AddEntityIfFound(const ClassName[])
132 {
133 new Entity = find_ent_by_class(-1, ClassName)
134 if(pev_valid(Entity))
135 {
136 ArrayPushCell(DefaultMapEntitiesArray, Entity)
137 return 1
138 }
139
140 return 0
141 }
142
143 stock SearchForOrigins(Float:ReferenceOrigin[3], Float:Radius, const CheckFunction[])
144 {
145 new Float:RandomOrigin[3], Float:SkyOrigin[3], Float:FloorOrigin[3], j
146 new CallState, CallReturnValue
147
148 for(new i = 1; i <= 10000; i++)
149 {
150 RandomOrigin = ReferenceOrigin
151 for(j = 0; j < 3; j++)
152 {
153 //Get a random origin started from a reference point
154 RandomOrigin[j] += random_float((-1) * Radius, Radius)
155 }
156
157 //Detect the floor, so we don't spawn the player in air
158 FloorOrigin[0] = RandomOrigin[0]
159 FloorOrigin[1] = RandomOrigin[1]
160 FloorOrigin[2] = -8192.0
161
162 engfunc(EngFunc_TraceLine, RandomOrigin, FloorOrigin, DONT_IGNORE_MONSTERS, 0, 0)
163 get_tr2(0, TR_vecEndPos, RandomOrigin)
164 RandomOrigin[2] += 38.0 //make sure we don't spawn in ground
165
166 if(PointContents(RandomOrigin) == CONTENTS_EMPTY)
167 {
168 if(ValidSpotFound(RandomOrigin))
169 {
170 //Find where the sky/roof is
171 SkyOrigin[0] = RandomOrigin[0]
172 SkyOrigin[1] = RandomOrigin[1]
173 SkyOrigin[2] = 8192.0
174
175 engfunc(EngFunc_TraceLine, RandomOrigin, SkyOrigin, DONT_IGNORE_MONSTERS, 0, 0)
176 get_tr2(0, TR_vecEndPos, SkyOrigin)
177
178 if(PointContents(SkyOrigin) == CONTENTS_SKY)
179 {
180 if(get_distance_f(RandomOrigin, SkyOrigin) < 250)
181 {
182 //On maps like de_dust2 players could spawn on the map texture
183 //All this points are less than 249 units from the sky
184 //By detecting where the sky is and checking the distance we avoid this scenario
185 continue
186 }
187 }
188
189 if(CheckFunction[0] != EOS)
190 {
191 CallState = callfunc_begin(CheckFunction)
192 if(CallState == 1)
193 {
194 callfunc_push_array(_:RandomOrigin, sizeof(RandomOrigin))
195 CallReturnValue = callfunc_end()
196 if(!CallReturnValue)
197 {
198 continue
199 }
200 }
201 }
202
203 ArrayPushArray(FoundOriginsArray, RandomOrigin)
204 }
205 }
206 }
207 }
208
209 stock bool:ValidSpotFound(Float:Origin[3])
210 {
211 new HandleTraceHull
212 engfunc(EngFunc_TraceHull, Origin, Origin, DONT_IGNORE_MONSTERS, HULL_HUMAN, 0, HandleTraceHull)
213 if(get_tr2(HandleTraceHull, TR_InOpen) && !(get_tr2(HandleTraceHull, TR_StartSolid) || get_tr2(HandleTraceHull, TR_AllSolid)))
214 {
215 return true
216 }
217
218 return false
219 }