[Half-Life AMXX] / mpbhops.sma Repository:
ViewVC logotype

Annotation of /mpbhops.sma

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (view) (download)

1 : ian 1 /*
2 :     MultiPlayer Bunny Hops v1.2
3 :     Copyright (C) 2007 Ian (Juan) Cammarata
4 :    
5 :     This program is free software; you can redistribute it and/or modify it under
6 :     the terms of the GNU General Public License as published by the Free Software
7 :     Foundation; either version 2 of the License, or (at your option) any later
8 :     version.
9 :    
10 :     This program is distributed in the hope that it will be useful, but WITHOUT ANY
11 :     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
12 :     PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 :    
14 :     You should have received a copy of the GNU General Public License along with
15 :     this program; go to http://www.opensource.org/licenses/gpl-license.php
16 :     --------------------------------------------------------------------------------
17 :    
18 :     http://ian.cammarata.us/projects/mpbhops
19 :     Sep 23 14:06
20 :    
21 :    
22 :     Description:
23 :     This plugin allows clients to jump across sections of bhops without the blocks being triggered. The blocks stay in place all the time making it much more suitable for multiplayer. If a player tries to stand on or jump on a block twice, then they are teleported off to the side. It is intended for bhop maps (Not BCM plugins), and also provides semiclip detection for map blocks as well as BCM blocks.
24 :    
25 :     See it in Action:
26 :     1337bunnies server: 66.55.131.63:27015
27 :    
28 :     Commands:
29 :     Not Applicable.
30 :    
31 :    
32 :     Cvars:
33 :     mpbhops <0|1> Disables/enables bhop handling.
34 :    
35 :    
36 :     Requirements:
37 :     Engine module
38 :    
39 :    
40 :     Notes:
41 :     This is a stand alone version of the code from my climb plugin, for those who don't want all the features it offers.
42 :     http://ian.cammarata.us/projects/climb
43 :    
44 :    
45 :     Credits:
46 :     Thanks to Lola for letting me use her awesome server for testing purposes.
47 :     http://1337bunnies.com
48 :     66.55.131.63:27015
49 :     Thanks to r33d and Woofie for testing.
50 :    
51 :    
52 :     Supported Languages:
53 :     Not Applicable.
54 :    
55 :    
56 :     Change Log:
57 :     Key (+ added | - removed | c changed | f fixed)
58 :    
59 :     v1.2 (SEPT 23, 2007)
60 :     +: Semiclip support for BCM plugins by Emp` and Necro.
61 :    
62 :     v1.1 (SEPT 23, 2007)
63 :     c: Increased fail check time from 0.1 seconds to 0.2 seconds. Should fix some people getting fail when doing a standupbhop.
64 :     f: Teleporting to world origin rarely when hopping back and forth between func_door and world brush.
65 :     f: Touch is detected even when clients aren't solid. (No more semiclip exploit)
66 :    
67 :     v1.0 (SEPT 21, 2007)
68 :     !: Initial release
69 :     */
70 :    
71 :     #include <amxmodx>
72 :     #include <engine>
73 :     #include <fakemeta>
74 :    
75 :     #define VERSION "1.2"
76 :    
77 :     #define MAX_DOORS 500
78 :    
79 :     #define TSK_BHOP 50
80 :     #define TSK_CLEAR_FAIL 100
81 :    
82 :     //func_doors[x]{ id, speed, angles }
83 :     new door_count = 0, func_doors[MAX_DOORS][3], Float:door_tp_pos[MAX_DOORS][3]
84 :     new bhop_failid[32], bool:bhop_fail[32]
85 :     new p_enabled
86 :     new MAXPLAYERS
87 :    
88 :     public plugin_init( )
89 :     {
90 :     MAXPLAYERS = get_maxplayers( )
91 :    
92 :     register_plugin( "MP Bhops", VERSION, "Ian Cammarata" )
93 :     register_cvar( "mpbhops_version", VERSION, FCVAR_SERVER )
94 :    
95 :     p_enabled = register_cvar( "mpbhops", "0", FCVAR_SERVER )
96 :     }
97 :    
98 :     public pfn_keyvalue( ent )
99 :     {
100 :     static last_ent
101 :     new class[31], key[31], val[31]
102 :     copy_keyvalue( class, 30, key, 30, val, 30 )
103 :    
104 :     if( ent != last_ent && func_doors[door_count][0] && door_count < MAX_DOORS )
105 :     door_count++
106 :    
107 :     if( equal( class, "func_door" ) )
108 :     {
109 :     if( ent != last_ent ) func_doors[door_count][0] = ent
110 :    
111 :     if( equal( key, "speed" ) )
112 :     func_doors[door_count][1] = str_to_num(val)
113 :     if( equal( key, "dmg" ) )
114 :     func_doors[door_count][0] = 0
115 :     if( equal( key, "angles" ) )
116 :     {
117 :     new angles[5]
118 :     parse( val, angles, 4 )
119 :     func_doors[door_count][2] = str_to_num( angles )
120 :     }
121 :     last_ent = ent
122 :     }
123 :    
124 :     return PLUGIN_CONTINUE
125 :     }
126 :    
127 :     public plugin_cfg( )
128 :     {
129 :     if( func_doors[door_count][0] && door_count < MAX_DOORS )
130 :     door_count++
131 :    
132 :     new ent, ent2, tmpstr[33]
133 :     new Float:dmins[3], Float:dmaxs[3]
134 :    
135 :     //Find tp spots for doors, in case they're used for bhop
136 :     for( new i = 0; i < door_count; i++ )
137 :     {
138 :     ent = func_doors[i][0]
139 :     if( !is_valid_ent( ent ) ) func_doors[i][0] = 0
140 :     else
141 :     {
142 :     entity_get_vector( ent, EV_VEC_mins, dmins )
143 :     entity_get_vector( ent, EV_VEC_maxs, dmaxs )
144 :    
145 :     new dwid = floatround( dmaxs[0] - dmins[0] )
146 :     new dlen = floatround( dmaxs[1] - dmins[1] )
147 :    
148 :     //If the door moves up, or is thin, remove it's id from the array
149 :     if( func_doors[i][2] < 0 || dwid < 24 || dlen < 24 )
150 :     func_doors[i][0] = 0
151 :     //Otherwise find a safe tp spot in case it's a bhop door
152 :     else
153 :     {
154 :     //If it has a targetname, change the id in array to targeter
155 :     entity_get_string( ent, EV_SZ_targetname, tmpstr, 32 )
156 :     if( strlen( tmpstr ) )
157 :     {
158 :     ent2 = find_ent_by_target( -1, tmpstr )
159 :     if( ent2 )
160 :     {
161 :     func_doors[i][0] = ent2
162 :    
163 :     //If targeter is a button, remove it's id from the array
164 :     entity_get_string( ent2, EV_SZ_classname, tmpstr, 32 )
165 :     if( equal( tmpstr, "func_button" ) )
166 :     func_doors[i][0] = 0
167 :     }
168 :     }
169 :    
170 :     new Float:tmpvec[3], Float:tmpvec2[3]
171 :    
172 :     new Float:dr_tc[3]
173 :     dr_tc[0] = ( dmaxs[0] + dmins[0] ) / 2
174 :     dr_tc[1] = ( dmaxs[1] + dmins[1] ) / 2
175 :     dr_tc[2] = dmaxs[2]
176 :    
177 :     tmpvec[0] = ( dmaxs[0] + dmins[0] ) / 2
178 :     tmpvec[1] = dmaxs[1] + 20
179 :     tmpvec[2] = dmaxs[2] + 20
180 :     trace_line( ent, dr_tc, tmpvec, tmpvec2 )
181 :     if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] )
182 :     door_tp_pos[i] = tmpvec
183 :     else
184 :     {
185 :     tmpvec[1] = dmins[1] - 20
186 :     trace_line( ent, dr_tc, tmpvec, tmpvec2 )
187 :     if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] )
188 :     door_tp_pos[i] = tmpvec
189 :     else
190 :     {
191 :     tmpvec[0] = dmaxs[0] + 20
192 :     tmpvec[1] = ( dmaxs[1] + dmins[1] ) / 2
193 :     trace_line( ent, dr_tc, tmpvec, tmpvec2 )
194 :     if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] )
195 :     door_tp_pos[i] = tmpvec
196 :     else
197 :     {
198 :     tmpvec[0] = dmins[0] - 20
199 :     door_tp_pos[i] = tmpvec
200 :     }
201 :     }
202 :     }
203 :     }
204 :     }
205 :     }
206 :     }
207 :    
208 :     //This is a semiclip fix
209 :     public client_PreThink( id )
210 :     {
211 :     //If they're on the ground and not solid...
212 :     if( ( pev( id, pev_flags ) & FL_ONGROUND ) && !pev( id, pev_solid ) )
213 :     {
214 :     new Float:orig[3]
215 :     entity_get_vector( id, EV_VEC_origin, orig )
216 :    
217 :     //do a hull trace 1 unit below their origin
218 :     orig[2] -= 1
219 :     engfunc( EngFunc_TraceHull, orig, orig, DONT_IGNORE_MONSTERS, HULL_HUMAN, id, 0 )
220 :     new ent = get_tr2( 0, TR_pHit )
221 :    
222 :     //if all we hit is world or another player, who cares, exit
223 :     if( ent <= MAXPLAYERS ) return PLUGIN_CONTINUE
224 :    
225 :     //if we hit a door in the array, send it to the handler then exit
226 :     new dpos = door_in_array( ent )
227 :     if( dpos > -1 )
228 :     {
229 :     bhop_check_fail( id, ent, dpos )
230 :     return PLUGIN_CONTINUE
231 :     }
232 :    
233 :     //if we hit a BCM entity, force touch so the BCM plugin can handle it
234 :     new class[32]
235 :     entity_get_string( ent, EV_SZ_classname, class, 31 )
236 :     if( equal( class, "bcm" ) || equal( class, "bm_block" ) )
237 :     fake_touch( ent, id )
238 :     }
239 :    
240 :     return PLUGIN_CONTINUE
241 :     }
242 :    
243 :     public pfn_touch( ent, id )
244 :     {
245 :     if( !get_pcvar_num( p_enabled ) || !ent || !id )
246 :     return PLUGIN_CONTINUE
247 :    
248 :     //Make sure id is player and ent is object
249 :     if( 0 < ent <= MAXPLAYERS )
250 :     {
251 :     new tmp = id
252 :     id = ent
253 :     ent = tmp
254 :     }
255 :     else if( !( 0 < id <= MAXPLAYERS ) )
256 :     return PLUGIN_CONTINUE
257 :    
258 :     //Bhop stuff
259 :     new dpos = door_in_array( ent )
260 :     if( dpos > -1 )
261 :     {
262 :     bhop_check_fail( id, ent, dpos )
263 :     return PLUGIN_HANDLED
264 :     }
265 :    
266 :     return PLUGIN_CONTINUE
267 :     }
268 :    
269 :     public bhop_check_fail( id, ent, dpos )
270 :     {
271 :     if( bhop_failid[id-1] != ent )
272 :     {
273 :     bhop_failid[id-1] = ent
274 :     bhop_fail[id-1] = false
275 :    
276 :     new tskid = TSK_BHOP + id
277 :     if( task_exists( tskid ) )
278 :     remove_task( tskid )
279 :     set_task( 0.2, "bhop_set_fail", tskid )
280 :     tskid = TSK_CLEAR_FAIL + id
281 :     if( task_exists( tskid ) )
282 :     remove_task( tskid )
283 :     set_task( 0.7, "bhop_clear_fail", tskid )
284 :     }
285 :     else if( bhop_fail[id-1] )
286 :     {
287 :     //Teleport to fail position
288 :     entity_set_vector( id, EV_VEC_velocity, Float:{0.0, 0.0, 0.0} )
289 :     entity_set_vector( id, EV_VEC_origin, door_tp_pos[dpos] )
290 :    
291 :     //Reset fail vars
292 :     bhop_failid[id-1] = 0
293 :     bhop_fail[id-1] = false
294 :     }
295 :     }
296 :    
297 :     public door_in_array( door )
298 :     {
299 :     for( new i = 0; i < door_count; i++ )
300 :     if( func_doors[i][0] == door )
301 :     return i
302 :     return -1
303 :     }
304 :    
305 :     public bhop_set_fail( tskid )
306 :     {
307 :     bhop_fail[ tskid - TSK_BHOP - 1 ] = true
308 :     return PLUGIN_HANDLED
309 :     }
310 :    
311 :     public bhop_clear_fail( tskid )
312 :     {
313 :     new id = tskid - TSK_CLEAR_FAIL
314 :     bhop_failid[id-1] = 0
315 :     bhop_fail[id-1] = false
316 :     return PLUGIN_HANDLED
317 :     }

Contact
ViewVC Help
Powered by ViewVC 1.0.4