[Half-Life AMXX] / compiled / climb_2_0_a2 / amxmodx / scripting / climb.sma Repository:
ViewVC logotype

Annotation of /compiled/climb_2_0_a2/amxmodx/scripting/climb.sma

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (view) (download)

1 : ian 1 /*
2 :     Climb v2.0a2
3 :     Copyright (C) 2006 Ian (Juan) Cammarata
4 :    
5 :     This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
6 :    
7 :     This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8 :    
9 :     You should have received a copy of the GNU General Public License along with this program; go to http://www.opensource.org/licenses/gpl-license.php
10 :     */
11 :     /*
12 :     *To do:
13 :     * Recalc limiter/timeout on stats pages.
14 :     * Flags for weapons used
15 :     * Save user/pass login data for sessions (don't require login ever map change)
16 :     * Account management for accounts with user/pass login. email, change password, password recovery
17 :     * Unsolid as function of position and velocity
18 :     * Respawn vehicles if they go out of the map
19 :     *===============================================================================
20 :     * Climb v2.0a2
21 :     * Created by Ian (Juan) Cammarata
22 :     * http://ian.cammarata.us
23 :     * AMXX 1.76
24 :     * 3/2/2007 1:23:06 AM
25 :     *===============================================================================
26 :     * Description:
27 :     * This plugin is designed for use in climbing maps like those available from
28 :     * www.kreedz.com. If you want to disable this plugin for the duration of a
29 :     * map you can set cvar "climb 0", this will disable the ability to make and
30 :     * recall checkpoints and the automatic respawning.
31 :     *===============================================================================
32 :     * Commands:
33 :     * say /checkpoint : Save your position
34 :     * say /gocheck : Teleport you to your last saved position
35 :     * say /stuck : Teleport you to your previous checkpoint in case
36 :     * you get stuck in a wall
37 :     *===============================================================================
38 :     * Cvars:
39 :     * climb <1|0> : Enables|Disables all climb.amx functionality.
40 :     * climb_boost <1|0> : Enables|Disables boosting.
41 :     * climb_cpprice <0|...> : Set to dollar amount for cost of checkpoints.
42 :     * climb_startmoney <1337|0-16000> : Money amount set when players start timer.
43 :     *
44 :     * climb_render <0|1> : Changes unsolid rendering style, 0=classic, other=new more see through rendering.
45 :     * climb_sounds <1|0> : Enables|Disables sounds build in to the Climb plugin.
46 :     *
47 :     * climb_webmod <0|1> : Disables|Enables web mod interoperability.
48 :     * climb_stats_path <NULL|...> : Path to save generated stats pages. (If using
49 :     * WebMod, enter path to webmods www folder.)
50 :     * climb_stats_url <NULL|...> : URL to send clients to for stats pages. Only
51 :     * use if you have a web server running on the
52 :     * same machine as the game server.
53 :     * IF WEBMOD=1 THIS IS IGNORED.
54 :     * climb_stats_hsurl <NULL|...> : "%s" will be replaced with map name. Set
55 :     * to send client to URL if you have a page
56 :     * that automatically generates high scores via
57 :     * direct DB access.
58 :     * IF WEBMOD=1 THIS IS IGNORED.
59 :     * climb_stats_msg <NULL|...> : Message to display on scoreboard. Use HTML
60 :     *
61 :     * ip_internal <localhost|...> : Set to internal network IP or hostname. (If server behind NAT)
62 :     * ip_external <localhost|...> : Set to external network IP or hostname.
63 :     *
64 :     * climb_msg_r <0|0-255> : Display message red value.
65 :     * climb_msg_g <150|0-255> : Display message green value.
66 :     * climb_msg_b <250|0-255> : Display message blue value.
67 :     * climb_msg_x <0.05|0-1> : Display message x position.
68 :     * climb_msg_y <0.5|0-1> : Display message y position.
69 :     *
70 :     * *The following cvars are only read at plugin load, changes will not take
71 :     * effect until the map is changed.
72 :     * climb_save <1|0> : Enables|Disables saving of stats to a database.
73 :     *
74 :     * climb_db_type <sqlite|mysql> : Database type.
75 :     * climb_db_host <127.0.0.1> : Database host name/ip.
76 :     * climb_db_user <NULL|...> : Database user name.
77 :     * climb_db_pass <NULL|...> : Database password.
78 :     * climb_db_name <climb|...> : Database name.
79 :     * climb_db_prefix <climb_|...> : Table name prefix.
80 :     *===============================================================================
81 :     * Requirements:
82 :     * Modules:
83 :     * Engine
84 :     * Fakemeta
85 :     * DB Module (MySQL or SQLite/Only need to use stats.)
86 :     * AMXX 1.76 or higher
87 :     *===============================================================================
88 :     * Notes:
89 :     * Enjoy!
90 :     *===============================================================================
91 :     * Change Log:
92 :     * Key (+ added | - removed | c changed | f fixed | r refactored)
93 :     *
94 :     * v2.0a2 (FEB 16, 2007)
95 :     * +: 2 addition boost types. Super jump and double jump. (No partner needed for boosting anymore)
96 :     * +: Boosts are counted. (Not logged in DB yet.)
97 :     * +: Stats saving in database. MySQL or SQLite. (MySQL not tested yet. Only works with single db module enabled)
98 :     * +: Players now get rewarded for finishing even without starting the timer.
99 :     * +: Cvars for message color and position. (climb_msg_r, ..._g, ..._b, ..._x, ..._y)
100 :     * +: Cvar climb_startmoney - Value to set money to when players start timer.
101 :     * +: Cvar climb_stats_msg - Message to display on the HTML scoreboards.
102 :     * +: Cvar climb_unsolid_type - Change rendering style for unsolid players.
103 :     * +: Cvar climb_sounds - Disabled Climb plugin sounds.
104 :     * +: Several cvars for database settings.
105 :     * +: All players spawn at spawn point closest to the start button. (Eliminates cheat in maps with a spawn point at the finish button.)
106 :     * +: Additional spawns added during map load to fix maps without enough spawns.
107 :     * +: Timeouts for respawning and boosting.
108 :     * +: Command "help". Displays HTML help pages.
109 :     * -: AMX compatability. (AMX is officially dead)
110 :     * c: Cvars now prefixed with climb_ instead of amx_.
111 :     * c: Minor code optimizations.
112 :     * c: Command "Boost" now takes players to the boost help page instead of activating solid boost.
113 :     * r: All internal cvar handling is now done with pointers. (With the acception of cvars used only during init functions.)
114 :     * r: Solid boost only lasts 15 seconds at a time now since its usage is being tracked.
115 :     * r: Major internal rewrite (Probably added a few bugs. More major rewrites coming in next release.)
116 :     * v1.9.19 (AUG 02, 2006)
117 :     * +: New public cvar 'climb_version' to aid in searching for server with this plugin.
118 :     * +: Show checkpoints, gochecks, and finish stats (Stats will be more extensive in next version) with finish announcement.
119 :     * -: Global chat. Use AllChat plugin instead.
120 :     * -: Cvar: amx_climb_globchat
121 :     * c: The /spec command now obeys the cvar "allow_spectators", clients with reserved slot always allowed.
122 :     * c: Shows number of checks and gocheck on client finish announcement.
123 :     * f: Bug caused by using stop command while paused.
124 :     * r: Client commands reworked. Everything functions the same, but with more functionality. For example the gc command can be entered as any of the following: gc, /gc, \gc, say gc, say /gc, say \gc, say_team gc, etc...
125 :     * v1.9.18 (MAY 15, 2006)
126 :     * r: Recoded the way health is handled. Should work for any map now.
127 :     * v1.9.17 (APR 07, 2006)
128 :     * c: Plugin is now compatible with both AMX and AMXX.
129 :     * c: The /spectate command can now be used by anyone. Admin no longer required.
130 :     * v1.9.16a
131 :     * f: Added health fix for kz_cfl_yamakasi.
132 :     * c: New CSS theme for html scoreboard.
133 :     * v1.9.16
134 :     * +: Counts usage of CP and GC commands(only displayed on html scoreboard).
135 :     * f: Added health fix for kz_lighthouse and kz_phoogi.
136 :     * v1.9.15
137 :     * +: Colorized global chat. ADMIN_RESERVATION has name in green instead of team color.
138 :     * +: /stop command. Resets timer to zero, end climbing session.
139 :     * c: Reset function. /stop + /respawn. Client is now reset automatically when pressing the start button if they are not already started.
140 :     * f: YOU CAN'T GET STUCK ANYMORE!!! (Well almost. Doing gocheck a second time gets you unstuck.)
141 :     * f: Global chat is now logged correctly and shows up in HLSW.
142 :     * v1.9.14
143 :     * +: Hook is taken away when client starts timer, given back if they reset.
144 :     * +: Max health fixes for several new maps.
145 :     * +: Sort clients on CS scoreboard by climb rank.
146 :     * +: Cvar amx_climb_boost - enable\disable boosting.
147 :     * +: Cvar amx_climb_cpprice - charge money for checkpoints.
148 :     * +: Custom configurable commands based on events. (climb.ini)
149 :     * +: Global chat. cvar: amx_climb_globchat <1|0>
150 :     * +: Client climb time is now shown using the round time HUD sprites.
151 :     * -: Command /mytime, not needed because of HUD sprite timer.
152 :     * -: Auto time display every 30 seconds, not needed because of HUD sprite timer.
153 :     * c: Added another start button sound.
154 :     * c: Super healing doors no longer removed. (Needed for shortcuts in some maps.)
155 :     * f: Admins can't be alive as spectator even with 3rd party respawn plugin.
156 :     * f: Keep godmode after respawning if finished map and not reset.
157 :     * f: Admins VIP display on CS scoreboard is now updated whenever clients connect.
158 :     * f: Health charger minimaps in kz_real_skyscraper & kz_northpole_b01.
159 :     * f: Not teleporting to exact cp position if another client is on your cp.
160 :     * f: Respawning outside of maps sometimes immediately after leaving spectator.
161 :     */
162 :     #include <amxmodx>
163 :     #include <fun>
164 :     #include <amxmisc>
165 :     #include <engine>
166 :     #include <fakemeta>
167 :     #include <sqlx>
168 :     #include <string2>
169 :     #include <cstrike>
170 :     #include <cstrike2>
171 :    
172 :     #define SF_MAX 50 //Maximum number of start/finish commands in climb.ini
173 :     #define VERSION "2.0a2"
174 :    
175 :     //DB variables
176 :     new Handle:db_tuple,db_prefix[10],bool:climb_save
177 :    
178 :     //Client flags arrays
179 :     new Float:origins[32][41],timer[32][13],time_stamps[33][2],Float:post_think_vel[32][3]
180 :    
181 :     //Temp save vars
182 :     new steamid[32][32],savepos=0,Float:originssave[32][41],timersave[32][13]
183 :    
184 :     //Touch for unsolid clients
185 :     new trig[100],trignum=0,brk[50],brknum=0
186 :    
187 :     //Other stuff
188 :     new hooked[32],hp=100
189 :     new sfactions[SF_MAX][50],sfcount=0
190 :     new score_ts,hscore_ts
191 :     new dyn_spawn_ids[32],dyn_spawn_count=-1,Float:spawn_tp_orig[3]
192 :    
193 :     //Cvar Pointers
194 :     new p_climb,p_webmod,p_boost,p_cpprice
195 :     new p_msg_r,p_msg_g,p_msg_b,p_msg_x,p_msg_y
196 :     new p_sounds,p_render
197 :     new p_ip_internal,p_ip_external,p_port
198 :     new p_allow_spectators,p_startmoney
199 :     new p_stats_path,p_stats_url,p_stats_hsurl,p_stats_msg
200 :    
201 :     //Model size
202 :     //standing 32x32x72
203 :     //crouched 32x32x36
204 :    
205 :     //timestamps[id][x]
206 :     #define TS_SPAWN 0
207 :     #define TS_BOOST 1
208 :    
209 :     //Tasks:
210 :     //#define TSK_AUTOHEAL 50 //50+ : Auto Heal
211 :     //#define TSK_AUTORSPN 100 //100+: Auto Respawn
212 :     //#define TSK_BOOSTTMR 150 //150+: Solid Boost Timer
213 :    
214 :     //timer[id][x]:
215 :     #define TMR_CFLAGS 0 //Status
216 :     #define TMR_STARTD 1 //Start Time
217 :     #define TMR_FINISH 2 //Finish Time
218 :     #define TMR_CPSCNT 3 //CP Count
219 :     #define TMR_GCSCNT 4 //GC Count
220 :     #define TMR_BSTTME 5 //Best Time
221 :     #define TMR_BSTCPS 6 //Best CP
222 :     #define TMR_BSTGCS 7 //Best GC
223 :     #define TMR_SESFIN 8 //Finished this session
224 :     #define TMR_MAPFIN 9 //Total times finished this map
225 :     #define TMR_DBUSER 10 //Database player ID; 0=not registered; -1=not registered & shared steam id
226 :     #define TMR_BOOSTS 11 //Number of boosts used
227 :     #define TMR_WPNUSE 12 //Bit sum of used weapons
228 :    
229 :     //Status timer[id][TMR_CFLAGS]&=x
230 :     #define CF_NULL 0 //Used to clear flags in change_status() and change_boost() functions
231 :     #define CF_STOP (1<<0) //STATUS FLAG: Not Started
232 :     #define CF_START (1<<1) //STATUS FLAG: Climbing
233 :     #define CF_PAUSE (1<<2) //STATUS FLAG: Paused
234 :     #define CF_SOLID (1<<3) //BOOST FLAG
235 :     #define CF_SUPER_JUMP (1<<4) //BOOST FLAG
236 :     #define CF_DOUBLE_JUMP (1<<5) //BOOST FLAG
237 :     #define CF_SPAWN_NO_GC (1<<6)
238 :     #define CF_NO_SCOUT (1<<7)
239 :     #define CF_NO_VIP (1<<8)
240 :    
241 :     public client_putinserver(id){
242 :     if(get_pcvar_num(p_climb)&&!is_user_bot(id)){
243 :     new ida[1]
244 :     ida[0]=id
245 :     set_task(20.0,"connect_advert",0,ida,1)
246 :     //Set CF_STOP status
247 :     change_status(id,CF_STOP)
248 :     //search steamid to position reference for match
249 :     new searchid[32]
250 :     get_user_authid(id,searchid,31)
251 :     for(new i=0;i<32;i++)
252 :     if(equal(searchid,steamid[i])){
253 :     //load origins & timer array if match found
254 :     origins[id]=originssave[i]
255 :     timer[id]=timersave[i]
256 :     return PLUGIN_CONTINUE
257 :     }
258 :     if(climb_save&&timer[id][TMR_DBUSER]<1)
259 :     set_task(5.0,"auto_login",0,ida,1)
260 :     }
261 :     return PLUGIN_CONTINUE
262 :     }
263 :     public connect_advert(ida[1]){
264 :     new id=ida[0]
265 :     new msg[51]
266 :     formatex(msg,50,"^x04 ^t^t^t^t^t^t^tThis server is using Climb v%s by:",VERSION)
267 :     saytext(id,id,msg)
268 :     saytext(id,id,"^x04 ^t^t^t^t^t^t^tIan (Juan) Cammarata (http://ian.cammarata.us)")
269 :     }
270 :     public auto_login(ida[1])
271 :     return client_cmd(ida[0],"login")
272 :     public client_disconnect(id){
273 :     if(get_pcvar_num(p_climb)&&!is_user_bot(id)){
274 :     savepos++
275 :     if(savepos==31)savepos=0
276 :     new saveid[32]
277 :     get_user_authid(id,saveid,32)
278 :     //erase previous save if exists
279 :     for(new i=0;i<32;i++)if(equal(saveid,steamid[i]))steamid[i]=""
280 :     //save steamid to position reference
281 :     steamid[savepos]=saveid
282 :     //save origins
283 :     originssave[savepos]=origins[id]
284 :     //save timer array/Pause if running
285 :     if(timer[id][TMR_CFLAGS]&CF_START)change_status(id,CF_PAUSE)
286 :     timersave[savepos]=timer[id]
287 :     //clear origins for new client in that slot
288 :     for(new i=0;i<8;i++)origins[id][i]=0.0
289 :     for(new i=0;i<11;i++)timer[id][i]=0
290 :     hooked[id]=0
291 :     }
292 :     return PLUGIN_HANDLED
293 :     }
294 :     public check(id){
295 :     if(get_pcvar_num(p_climb)&&isalive(id)&&notpaused(id)){
296 :     new cpprice=get_pcvar_num(p_cpprice)
297 :     if(cpprice>0){
298 :     new cash=cs_get_user_money(id)
299 :     if(cpprice>cash){
300 :     clmsg(id,"You don't have enough cash for more checkpoints.")
301 :     client_print(id,print_chat,"You don't have enough cash for more checkpoints.")
302 :     return PLUGIN_HANDLED
303 :     }
304 :     cs_set_user_money(id,cash-cpprice)
305 :     }
306 :     if(!hooked[id]){
307 :     new Float:vel[3]
308 :     entity_get_vector(id,EV_VEC_velocity,vel)
309 :     if(vel[2]>=0){
310 :     new Float:coords[3]
311 :     entity_get_vector(id,EV_VEC_origin,coords)
312 :     if(coords[0]||coords[1]||coords[2]){
313 :     for(new i=39;i>3;i--) origins[id][i]=origins[id][i-4]
314 :     for(new i=0;i<3;i++) origins[id][i]=coords[i]
315 :     origins[id][3]=entity_get_float(id, EV_FL_gravity)
316 :     new msg[100]="Checkpoint saved."
317 :     if(timer[id][TMR_CFLAGS]&CF_START){
318 :     timer[id][TMR_CPSCNT]++
319 :     formatex(msg,99,"Checkpoint saved. (%d CPS/ %d GCS/ %d Boosts)",timer[id][TMR_CPSCNT],timer[id][TMR_GCSCNT],timer[id][TMR_BOOSTS])
320 :     }
321 :     clmsg(id,msg)
322 :     }
323 :     else clmsg(id,"Can not save checkpoint at current location.")
324 :     }
325 :     else clmsg(id,"You can't make checkpoints while falling.")
326 :     }
327 :     else clmsg(id,"You can't make checkpoints while using hook.")
328 :     }
329 :     return PLUGIN_HANDLED
330 :     }
331 :     public gocheck(id){
332 :     if(get_pcvar_num(p_climb)&&isalive(id)&&notpaused(id)){
333 :     if(origins[id][0]||origins[id][1]||origins[id][2]){
334 :     new Float:coords[3]
335 :     for(new i=0;i<3;i++)coords[i]=origins[id][i]
336 :     entity_set_float(id,EV_FL_gravity,origins[id][3])
337 :     teleport(id,coords)
338 :     new msg[100]="Checkpoint restored."
339 :     if(timer[id][TMR_CFLAGS]&CF_START){
340 :     timer[id][TMR_GCSCNT]++
341 :     formatex(msg,99,"Checkpoint restored. (%d CPS/ %d GCS/ %d Boosts)",timer[id][TMR_CPSCNT],timer[id][TMR_GCSCNT],timer[id][TMR_BOOSTS])
342 :     }
343 :     clmsg(id,msg)
344 :     }
345 :     else{
346 :     clmsg(id,"You must make a checkpoint first.")
347 :     return 0
348 :     }
349 :     }
350 :     return 1
351 :     }
352 :     public stuck(id){
353 :     if(get_pcvar_num(p_climb)&&isalive(id)&&notpaused(id)){
354 :     if(origins[id][4]||origins[id][5]||origins[id][6]){
355 :     new Float:coords[3]
356 :     for(new i=0;i<36;i++) origins[id][i]=origins[id][i+4]
357 :     for(new i=0;i<3;i++) coords[i]=origins[id][i]
358 :     entity_set_float(id,EV_FL_gravity,origins[id][3])
359 :     teleport(id,coords)
360 :     new msg[100]="Previous checkpoint restored."
361 :     if(timer[id][TMR_CFLAGS]&CF_START){
362 :     timer[id][TMR_CPSCNT]--
363 :     formatex(msg,99,"Previous checkpoint restored. (%d CPS/ %d GCS/ %d Boosts)",timer[id][TMR_CPSCNT],timer[id][TMR_GCSCNT],timer[id][TMR_BOOSTS])
364 :     }
365 :     clmsg(id,msg)
366 :     new cpprice=get_pcvar_num(p_cpprice)
367 :     if(cpprice>0){
368 :     new cash=cs_get_user_money(id)
369 :     cs_set_user_money(id,cash+cpprice)
370 :     }
371 :     }
372 :     else clmsg(id,"You have no previous checkpoints remaining.")
373 :     }
374 :     return PLUGIN_HANDLED
375 :     }
376 :     //Respawn client when they die
377 :     public death_msg(){
378 :     if (get_pcvar_num(p_climb)){
379 :     new id=read_data(2)
380 :     new ida[1]
381 :     ida[0]=id
382 :     if(task_exists(100+id))remove_task(100+id)
383 :     if(isct(id)){
384 :     set_task(0.2,"respawn",100+id,ida,1)
385 :     }
386 :     }
387 :     return PLUGIN_HANDLED
388 :     }
389 :     public change_status(id,newstat){
390 :     new cflags=timer[id][TMR_CFLAGS]
391 :     if(cflags&CF_STOP)timer[id][TMR_CFLAGS]-=CF_STOP
392 :     else if(cflags&CF_START)timer[id][TMR_CFLAGS]-=CF_START
393 :     else if(cflags&CF_PAUSE)timer[id][TMR_CFLAGS]-=CF_PAUSE
394 :     if(newstat&CF_PAUSE){
395 :     if(cflags&CF_PAUSE){
396 :     timer[id][TMR_CFLAGS]+=CF_START
397 :     timer[id][TMR_STARTD]=get_systime()-timer[id][TMR_STARTD]
398 :     set_entity_flags(id,FL_FROZEN,0)
399 :     unsolid(id)
400 :     entity_set_float(id,EV_FL_gravity,origins[id][40])
401 :     clmsg(id,"UNPAUSED")
402 :     }
403 :     else if(cflags&CF_START){
404 :     cl_pause(id)
405 :     timer[id][TMR_CFLAGS]+=CF_PAUSE
406 :     }
407 :     else{
408 :     clmsg(id,"You must start the timer before you can pause.")
409 :     timer[id][TMR_CFLAGS]=cflags
410 :     }
411 :     }
412 :     else timer[id][TMR_CFLAGS]+=newstat
413 :     return PLUGIN_HANDLED
414 :     }
415 :     public cl_pause(id){
416 :     timer[id][TMR_STARTD]=get_systime()-timer[id][TMR_STARTD]
417 :     set_entity_flags(id,FL_FROZEN,1)
418 :     unsolid(id)
419 :     set_rendering(id,kRenderFxGlowShell,0,0,255,kRenderTransColor,1)
420 :     origins[id][40]=entity_get_float(id,EV_FL_gravity)
421 :     entity_set_float(id,EV_FL_gravity,0.0)
422 :     clmsg(id,"PAUSED")
423 :     return PLUGIN_HANDLED
424 :     }
425 :     public stop(id){
426 :     if(get_pcvar_num(p_climb)&&timer[id][TMR_CFLAGS]&CF_START/*&&notpaused(id)*/){
427 :     change_status(id,CF_STOP)
428 :     sfexec(id,4) //Execute commands from start/finish config
429 :     }
430 :     return PLUGIN_HANDLED
431 :     }
432 :     public reset(id){
433 :     if(get_pcvar_num(p_climb)&&check_timeout(id,get_systime(),time_stamps[id][TS_SPAWN],5)){
434 :     stop(id)
435 :     frespawn(id)
436 :     }
437 :     return PLUGIN_HANDLED
438 :     }
439 :     public frespawn(id){
440 :     if(get_pcvar_num(p_climb)&&check_timeout(id,get_systime(),time_stamps[id][TS_SPAWN],5)){
441 :     if(get_user_team(id)==3)cs_set_user_team(id,2)
442 :     timer[id][TMR_CFLAGS]+=CF_SPAWN_NO_GC
443 :     cs_user_spawn(id)
444 :     }
445 :     return PLUGIN_HANDLED
446 :     }
447 :     public respawn(ida[]){
448 :     new id=ida[0]
449 :     if(!get_user_team(id)||is_user_alive(id)||!isct(id))
450 :     return PLUGIN_HANDLED
451 :     cs_user_spawn(id)
452 :     //gocheck(id)
453 :     return PLUGIN_HANDLED
454 :     }
455 :     public spawned(id){
456 :     if(get_pcvar_num(p_climb)){
457 :     //Block Buying
458 :     new cflags=timer[id][TMR_CFLAGS]
459 :     set_msg_block(get_user_msgid("StatusIcon"),2)
460 :     if(is_user_alive(id)){
461 :     //Set them to CT if they're a spectator
462 :     if(get_user_team(id)==3)cs_set_user_team(id,2)
463 :     sortcssb()
464 :     //If they are paused freeze them again.
465 :     if(cflags&CF_PAUSE)cl_pause(id)
466 :     set_user_health(id,hp)
467 :     //Only admins can shoot other clients.
468 :     //if(!(get_user_flags(id)&ADMIN_SLAY))set_user_hitzones(id,0,0) //Keeps players from seeing eachothers names.
469 :     //Remove stuff dropped on death
470 :     remove_entity_name("weaponbox")
471 :     remove_entity_name("item_thighpack")
472 :     //Execute commands from start/finish config
473 :     sfexec(id,1)
474 :     //Show admin as VIP on Scoreboard.
475 :     if(get_user_flags(id)&ADMIN_SLAY)cs_set_user_scoreattrib(id,4)
476 :     //Equip Task
477 :     new ida[1]
478 :     ida[0]=id
479 :     set_task(0.1,"equip",_,ida,1)
480 :     time_stamps[id][TS_SPAWN]=get_systime()
481 :     //Teleport to safe place/old primary spawn position
482 :     if(cflags&CF_SPAWN_NO_GC){
483 :     if(vector_distance(spawn_tp_orig,Float:{0,0,0}))teleport(id,spawn_tp_orig)
484 :     timer[id][TMR_CFLAGS]-=CF_SPAWN_NO_GC
485 :     }
486 :     else if(!gocheck(id))if(!(cflags&CF_START&&!getusertime(id)))if(vector_distance(spawn_tp_orig,Float:{0,0,0}))teleport(id,spawn_tp_orig)
487 :     }
488 :     }
489 :     else set_msg_block(get_user_msgid("StatusIcon"),0)
490 :     return PLUGIN_CONTINUE
491 :     }
492 :     public equip(ida[]){ //Give equipment to client, delayed to prevent crash
493 :     new id=ida[0]
494 :     for(new i=0;i<2;i++)give_item(id,"weapon_scout")
495 :     give_item(id,"weapon_c4")
496 :     cs_set_user_nvg(id)
497 :     }
498 :     public check_timeout(id,time1,time2,freq){
499 :     if(time1<time2)return 1
500 :     new dif=time1-time2
501 :     if(dif<freq){
502 :     new msg[76]
503 :     format(msg,75,"You must wait %d more seconds to use this command again.",freq-dif)
504 :     if(id>0)clmsg(id,msg)
505 :     return 0
506 :     }
507 :     return 1
508 :     }
509 :     public change_boost(id,newboost){ //Change Boost flags
510 :     if(!(cvar_enabled(id,p_boost)&&isalive(id))&&notpaused(id))return PLUGIN_HANDLED
511 :     new msg[151],rmflag,cflags=timer[id][TMR_CFLAGS]
512 :     if(cflags&CF_SOLID){
513 :     if(task_exists(150+id))remove_task(150+id)
514 :     rmflag=CF_SOLID
515 :     msg="Solid Boost Disabled.^n"
516 :     }
517 :     else if(cflags&CF_SUPER_JUMP){
518 :     rmflag=CF_SUPER_JUMP
519 :     msg="Super Jump Disabled.^n"
520 :     }
521 :     else if(cflags&CF_DOUBLE_JUMP){
522 :     rmflag=CF_DOUBLE_JUMP
523 :     msg="Double Jump Disabled.^n"
524 :     }
525 :     if(rmflag>0)timer[id][TMR_CFLAGS]-=rmflag
526 :     if(!(rmflag&newboost)&&check_timeout(id,(cflags&CF_START?getusertime(id):get_systime()),time_stamps[id][TS_BOOST],5)){
527 :     if(newboost==CF_SOLID){
528 :     format(msg,150,"%sSolid Boost Enabled.",msg)
529 :     new ida[1]
530 :     ida[0]=id
531 :     set_task(15.0,"solid_boost_timer",150+id,ida,1)
532 :     if(timer[id][TMR_CFLAGS]&CF_START)timer[id][TMR_BOOSTS]++
533 :     }
534 :     if(newboost==CF_SUPER_JUMP)format(msg,150,"%sSuper Jump Enabled.",msg)
535 :     if(newboost==CF_DOUBLE_JUMP)format(msg,150,"%sDouble Jump Enabled.",msg)
536 :     timer[id][TMR_CFLAGS]+=newboost
537 :     }
538 :     if(strlen(msg))clmsg(id,msg)
539 :     return PLUGIN_HANDLED
540 :     }
541 :     public solid_boost_timer(ida[]){ //Task to auto disable solid boost after timeout
542 :     //if(timer[id][TMR_CFLAGS]&CF_SOLID)solid_boost(id) //Shouldn't need the if statement
543 :     change_boost(ida[0],CF_SOLID)
544 :     return PLUGIN_HANDLED
545 :     }
546 :     //Semi-clip, and entity touch detection for non-solid clients
547 :     //* Maybe move this to client prethink
548 :     public server_frame(){
549 :     if(get_pcvar_num(p_climb)){
550 :     new players[32],num,i,j,Float:c1[3],Float:c2[3]
551 :     new Float:c1z[3],Float:c2z[3]
552 :     new id_i,id_j,cflags_i,cflags_j
553 :     get_players(players,num,"ac")
554 :     if(trignum){
555 :     for(i=0;i<num;i++){
556 :     id_i=players[i]
557 :     if(!playersolid(id_i)){
558 :     for(j=0;j<trignum;j++){
559 :     id_j=trig[j]
560 :     entity_get_vector(id_j,EV_VEC_absmin,c2)
561 :     entity_get_vector(id_j,EV_VEC_absmax,c2z)
562 :     entity_get_vector(id_i,EV_VEC_origin,c1)
563 :     if(c2[0]<=c1[0]&&c2z[0]>=c1[0]&&c2[1]<=c1[1]&&c2z[1]>=c1[1]&&c2[2]<=c1[2]&&c2z[2]>=c1[2]){
564 :     fake_touch(id_j,id_i)
565 :     j=trignum
566 :     }
567 :     }
568 :     }
569 :     }
570 :     }
571 :     if(brknum){
572 :     for(i=0;i<num;i++){
573 :     id_i=players[i]
574 :     if(!playersolid(id_i)){
575 :     for(j=0;j<brknum;j++){
576 :     id_j=brk[j]
577 :     entity_get_vector(id_j,EV_VEC_absmin,c2)
578 :     entity_get_vector(id_j,EV_VEC_absmax,c2z)
579 :     entity_get_vector(id_i,EV_VEC_origin,c1)
580 :     c1[0]-=26
581 :     c1z[0]=c1[0]+32
582 :     c1[1]-=16
583 :     c1z[1]=c1[1]+32
584 :     c1[2]-=40
585 :     c1z[2]=c1[2]+50
586 :     if(((c2[0]<c1[0]<c2z[0])||(c2[0]<c1z[0]<c2z[0])||(c1[0]<c2[0]<c1z[0])||(c1[0]<c2z[0]<c1z[0]))
587 :     &&((c2[1]<c1[1]<c2z[1])||(c2[1]<c1z[1]<c2z[1])||(c1[1]<c2[1]<c1z[1])||(c1[1]<c2z[1]<c1z[1]))
588 :     &&((c2[2]<c1[2]<c2z[2])||(c2[2]<c1z[2]<c2z[2])||(c1[2]<c2[2]<c1z[2])||(c1[2]<c2z[2]<c1z[2]))
589 :     ){
590 :     fake_touch(id_j,id_i)
591 :     j=brknum
592 :     }
593 :     }
594 :     }
595 :     }
596 :     }
597 :     c1z[0]=0.0
598 :     c1z[1]=0.0
599 :     c2z[0]=0.0
600 :     c2z[1]=0.0
601 :     //new Float:c1d[3],Float:c2d[3],xyadd,zadd
602 :     for(i=0;i<num;i++){
603 :     id_i=players[i]
604 :     cflags_i=timer[id_i][TMR_CFLAGS]
605 :     if(!(cflags_i&CF_PAUSE)){
606 :     //solid(players[i])
607 :     entity_get_vector(id_i,EV_VEC_origin,c1)
608 :     //entity_get_vector(players[i],EV_VEC_velocity,c1d)
609 :     c1z[2]=c1[2]
610 :     c1[2]=0.0
611 :     for(j=0;j<num;j++){
612 :     id_j=players[j]
613 :     cflags_j=timer[id_j][TMR_CFLAGS]
614 :     if(!(cflags_j&CF_SOLID)&&i!=j){
615 :     entity_get_vector(id_j,EV_VEC_origin,c2)
616 :     //entity_get_vector(players[j],EV_VEC_velocity,c2d)
617 :     c2z[2]=c2[2]
618 :     c2[2]=0.0
619 :     if(vector_distance(c1,c2)<90&&vector_distance(c1z,c2z)<110){
620 :     if(!(cflags_i&CF_SOLID&&cflags_j&CF_SOLID)){//&&vector_distance(c1,c2)>25&&vector_distance(c1z,c2z)>30)){
621 :     unsolid(id_i)
622 :     unsolid(id_j)
623 :     j=num
624 :     }
625 :     }
626 :     }
627 :     if(j+1==num)solid(id_i)
628 :     }
629 :     }
630 :     }
631 :     }
632 :     return PLUGIN_CONTINUE
633 :     }
634 :     public client_PreThink(id){
635 :     if(!(get_pcvar_num(p_climb)&&get_pcvar_num(p_boost)&&isalive(id)))return PLUGIN_CONTINUE
636 :     new cflags=timer[id][TMR_CFLAGS],bool:onground=false
637 :     if(get_entity_flags(id)&FL_ONGROUND)onground=true
638 :     if(get_user_button(id)&IN_JUMP){
639 :     if(cflags&CF_SUPER_JUMP&&onground){
640 :     entity_get_vector(id,EV_VEC_velocity,post_think_vel[id])
641 :     if(post_think_vel[id][0]!=0.0||post_think_vel[id][1]!=0.0){
642 :     velocity_by_aim(id,600,post_think_vel[id])
643 :     if(post_think_vel[id][2]<250.0)post_think_vel[id][2]=250.0
644 :     if(post_think_vel[id][2]>350.0)post_think_vel[id][2]=350.0
645 :     }
646 :     else post_think_vel[id]=Float:{0.0,0.0,0.0}
647 :     }
648 :     else if(cflags&CF_DOUBLE_JUMP){
649 :     if(!onground&&!(get_user_oldbutton(id)&IN_JUMP)){
650 :     entity_get_vector(id,EV_VEC_velocity,post_think_vel[id])
651 :     if(is_finished(id)||post_think_vel[id][2]>-500)post_think_vel[id][2]=250.0
652 :     else post_think_vel[id]=Float:{0.0,0.0,0.0}
653 :     }
654 :     }
655 :     }
656 :     return PLUGIN_CONTINUE
657 :     }
658 :     public client_PostThink(id){
659 :     if(!(get_pcvar_num(p_climb)&&get_pcvar_num(p_boost)&&isalive(id)))return PLUGIN_CONTINUE
660 :     if(_:get_distance(_:post_think_vel[id],{0,0,0})){
661 :     entity_set_vector(id,EV_VEC_velocity,post_think_vel[id])
662 :     post_think_vel[id]=Float:{0.0,0.0,0.0}
663 :     if(timer[id][TMR_CFLAGS]&CF_START){
664 :     timer[id][TMR_BOOSTS]++ //Increment client boost count
665 :     time_stamps[id][TS_BOOST]=getusertime(id) //Timeout based on timer so they can't pause to avoid timeout
666 :     change_boost(id,CF_NULL)
667 :     }
668 :     else if(!is_finished(id)){
669 :     time_stamps[id][TS_BOOST]=get_systime()
670 :     change_boost(id,CF_NULL)
671 :     }
672 :     }
673 :     return PLUGIN_CONTINUE
674 :     }
675 :     public is_finished(id){
676 :     new cflags=timer[id][TMR_CFLAGS]
677 :     if(cflags&CF_STOP&&(get_user_flags(id)&ADMIN_RESERVATION||timer[id][TMR_SESFIN]>0))
678 :     return 1
679 :     return 0
680 :     }
681 :     public traceline(Float:v1[3], Float:v2[3], noMonsters, entity){
682 :     if(get_pcvar_num(p_climb)){
683 :     new id=entity
684 :     new entity2=get_tr(TR_pHit)
685 :     if(id>0&&entity2>0){
686 :     if(is_user_alive(id)){
687 :     new class[32]
688 :     entity_get_string(entity2,EV_SZ_classname,class,32)
689 :     new Float:orig1[3],Float:orig2[3]
690 :     entity_get_vector(id,EV_VEC_origin,orig1)
691 :     get_brush_entity_origin(entity2,orig2)
692 :     //if(get_user_button(id)&IN_USE&&get_user_aiming(id,a,b)<70&&equal(class,"func_button")){
693 :     if(get_user_button(id)&IN_USE&&vector_distance(orig1,orig2)<95&&equal(class,"func_button")){
694 :     new targ[32]
695 :     entity_get_string(entity2,EV_SZ_target,targ,32)
696 :     //Timer Start
697 :     //if((!(timer[id][TMR_CFLAGS]&CF_START)||getusertime(id)>4)&&/*(timer[id][TMR_CFLAGS]&CF_STOP||timer[id][TMR_CFLAGS]==TMR_CFLAGS_FNSH)&&(*/equal(targ,"counter_start")||equal(targ,"clockstartbutton")||equal(targ,"firsttimerelay")/*)*/){
698 :     if((!(timer[id][TMR_CFLAGS]&CF_START)||check_timeout(id,get_systime(),time_stamps[id][TS_SPAWN],5))&&(equal(targ,"counter_start")||equal(targ,"clockstartbutton")||equal(targ,"firsttimerelay"))){
699 :     new Float:orig[3],Float:view[3]
700 :     //Erase checkpoints
701 :     for(new i=0;i<8;i++)origins[id][i]=0.0
702 :     //Set all associated variables
703 :     timer[id][TMR_STARTD]=get_systime()
704 :     change_status(id,CF_START)
705 :     timer[id][TMR_CPSCNT]=0
706 :     timer[id][TMR_GCSCNT]=0
707 :     timer[id][TMR_BOOSTS]=0
708 :     //Respawn client to clear items.
709 :     entity_get_vector(id,EV_VEC_origin,orig)
710 :     entity_get_vector(id,EV_VEC_angles,view)
711 :     cs_user_spawn(id)
712 :     entity_set_vector(id,EV_VEC_origin,orig)
713 :     entity_set_vector(id,EV_VEC_angles,view)
714 :     delay_duck(id)
715 :     cs_set_user_money(id,get_pcvar_num(p_startmoney))
716 :     //Play random start sound and text messages
717 :     if(get_pcvar_num(p_sounds))switch(random_num(0,2)){
718 :     case 0:client_cmd(id,"spk barney/beertopside")
719 :     case 1:client_cmd(id,"spk scientist/c3a2_sci_portopen")
720 :     case 2:client_cmd(id,"spk barney/c1a2_ba_climb")
721 :     }
722 :     //Disable Boosts
723 :     change_boost(id,CF_NULL)
724 :     time_stamps[id][TS_BOOST]=0
725 :     clmsg(id,"Timer started. Go Go Go!!!")
726 :     client_print(id,print_chat,"Timer started. Go Go Go!!!")
727 :     //Update frags to reorder scoreboard
728 :     sortcssb()
729 :     //If stats save enabled warn unregistered clients to register
730 :     if(climb_save)regwarn(id)
731 :     //Execute commands from start/finish config
732 :     sfexec(id,2)
733 :     time_stamps[id][TS_SPAWN]=get_systime()
734 :     }
735 :     //Timer Stop
736 :     else if(equal(targ,"counter_off")||equal(targ,"clockstopbutton")||equal(targ,"clockstop")){
737 :     if(timer[id][TMR_CFLAGS]&CF_START){
738 :     //Set client variables
739 :     timer[id][TMR_FINISH]=get_systime()
740 :     change_status(id,CF_STOP)
741 :     timer[id][TMR_SESFIN]++
742 :     timer[id][TMR_MAPFIN]++
743 :     //Update frags to reorder scoreboard
744 :     sortcssb()
745 :     //Announce to client
746 :     if(get_pcvar_num(p_sounds))client_cmd(0,"spk woop")
747 :     clmsg(id,"Congratulations 1337 climber.")
748 :     client_print(id,print_chat,"Congratulations 1337 climber.")
749 :     new name[32],msg[21]
750 :     formatex(msg,sizeof(msg)-1,"%s^t%s",getuserstatus(id),parsetime(getusertime(id)))
751 :     //clmsg(id,msg)
752 :     //client_print(id,print_chat,msg)
753 :     //Announce to all
754 :     get_user_name(id,name,32)
755 :     client_print(0,print_chat,"%s^t%s^t(%d CPS/ %d GCS/ %d Boosts)^tCompleted (%d, %d)",name,msg,timer[id][TMR_CPSCNT],timer[id][TMR_GCSCNT],timer[id][TMR_BOOSTS],timer[id][TMR_SESFIN],timer[id][TMR_MAPFIN])
756 :     //If new record
757 :     if(getusertime(id)<timer[id][TMR_BSTTME]||timer[id][TMR_BSTTME]==0){
758 :     timer[id][TMR_BSTTME]=getusertime(id)
759 :     timer[id][TMR_BSTCPS]=timer[id][TMR_CPSCNT]
760 :     timer[id][TMR_BSTGCS]=timer[id][TMR_GCSCNT]
761 :     }
762 :     //Execute commands from start/finish config
763 :     sfexec(id,2)
764 :     //If stats enabled, warn unregistered clients to register, or save for registered clients
765 :     if(climb_save)
766 :     if(!regwarn(id))
767 :     db_save(id)
768 :     }
769 :     else if(timer[id][TMR_CFLAGS]&CF_STOP&&timer[id][TMR_SESFIN]==0){
770 :     //change_status(id,CF_FINISH)
771 :     timer[id][TMR_SESFIN]++
772 :     new msg[100]="Congratulations, you finished! But you didn't start the timer. :("
773 :     clmsg(id,msg)
774 :     client_print(id,print_chat,msg)
775 :     //Execute commands from start/finish config
776 :     sfexec(id,2)
777 :     //If stats save enabled warn unregistered clients to register
778 :     if(climb_save)regwarn(id)
779 :     }
780 :     }
781 :     }
782 :     }
783 :     }
784 :     }
785 :     return PLUGIN_CONTINUE
786 :     }
787 :     //Execute commands from start/finish config
788 :     public sfexec(id,clevent){
789 :     new clstat[3],cflags=timer[id][TMR_CFLAGS]
790 :     /*switch(timer[id][TMR_CFLAGS]){
791 :     case TMR_CFLAGS_STOP: clstat="ns"
792 :     case TMR_CFLAGS_STRT: clstat="st"
793 :     case TMR_CFLAGS_FNSH: clstat="fn"
794 :     }*/
795 :     if(is_finished(id))clstat="fn"
796 :     else if(cflags&CF_STOP)clstat="ns"
797 :     else if(cflags&CF_START)clstat="st"
798 :     //else if(timer[id][TMR_CFLAGS]&CF_FINISH)clstat="fn"
799 :     //if(equal(clstat,"ns")&&(get_user_flags(id)&ADMIN_RESERVATION||timer[id][TMR_SESFIN]>0))clstat="fn"
800 :    
801 :     for(new i=0;i<sfcount;i++){
802 :     new cmdstat[3],cmdevent[2],cmdtype[3],cmd[60],idtype[5]
803 :     parse(sfactions[i],cmdstat,2,cmdevent,1,cmdtype,2,cmd,sizeof(cmd)-1,idtype,4)
804 :     if((equali(cmdstat,clstat)||equali(cmdstat,"ay"))&&str_to_num(cmdevent)&clevent){
805 :     if(equali(cmdtype,"sc")){
806 :     if(equali(idtype,"uid"))format(cmd,sizeof(cmd)-1,cmd,get_user_userid(id))
807 :     else{
808 :     new name[24]
809 :     get_user_name(id,name,sizeof(name)-1)
810 :     format(name,sizeof(name),"^"%s^"",name)
811 :     format(cmd,sizeof(cmd)-1,cmd,name)
812 :     client_print(id,print_chat,cmd)
813 :     }
814 :     server_cmd(cmd)
815 :     }
816 :     else{
817 :     client_cmd(id,cmd)
818 :     }
819 :     }
820 :     }
821 :     return 1
822 :     }
823 :     //Pad text for console score listing
824 :     public pad(pad){
825 :     new j=4,str[50]=""
826 :     for(new i=strlen(str);i<pad;i++){
827 :     if(j==5){
828 :     copy(str[i],1,"^t")
829 :     j=0
830 :     }
831 :     else copy(str[i],1," ")
832 :     j++
833 :     }
834 :     return str
835 :     }
836 :     //Update frags to reorder scoreboard
837 :     public sortcssb(){
838 :     new players[32],num
839 :     get_players_ordered(players,num)
840 :     for(new i=0;i<num;i++){
841 :     set_user_frags(players[i],0)
842 :     cs_set_user_deaths(players[i],i+1)
843 :     }
844 :     return 1
845 :     }
846 :     //Returns array of client id's sorted by climb time
847 :     public get_players_ordered(players[32],&num){
848 :     get_players(players,num,"c")
849 :     //Insertion Sort clients by finished time
850 :     for(new i=1;i<num;i++){
851 :     new j=i,tmp
852 :     if(timer[players[i]][TMR_BSTTME]>0){
853 :     tmp=players[i]
854 :     while(j>0&&(timer[players[j-1]][TMR_BSTTME]==0?18000:timer[players[j-1]][TMR_BSTTME])>timer[tmp][TMR_BSTTME]){
855 :     players[j]=players[j-1]
856 :     j--
857 :     }
858 :     players[j]=tmp
859 :     }
860 :     }
861 :     //2nd Insertion Sort clients by climbing time
862 :     for(new i=1;i<num;i++){
863 :     new j=i,tmp
864 :     if(getusertime(players[i])>0){
865 :     tmp=players[i]
866 :     while(j>0&&(getusertime(players[j-1])==0?18000:getusertime(players[j-1]))>getusertime(tmp)&&timer[players[j-1]][TMR_BSTTME]==timer[tmp][TMR_BSTTME]){
867 :     players[j]=players[j-1]
868 :     j--
869 :     }
870 :     players[j]=tmp
871 :     }
872 :     }
873 :     return 1
874 :     }
875 :     //Make pathname for scoreboard html files
876 :     public pathname(filename[]){
877 :     new path[100]
878 :     get_pcvar_string(p_stats_path,path,79)
879 :     format(path,99,"%s%s",path,filename)
880 :     return path
881 :     }
882 :     public get_limit(){
883 :     if(get_pcvar_num(p_webmod))
884 :     return 0
885 :     new url[100]
886 :     get_pcvar_string(p_stats_url,url,99)
887 :     if(strlen(url))
888 :     return 0
889 :     return 1
890 :     }
891 :     public get_url(id,file[]){
892 :     new url[100]
893 :     get_pcvar_string(p_stats_url,url,99)
894 :     if(get_pcvar_num(p_webmod)){
895 :     new ip[10],iip[33],eip[33],port[10]
896 :     get_user_ip(id,ip,9)
897 :     get_pcvar_string(p_ip_internal,iip,32)
898 :     get_pcvar_string(p_ip_external,eip,32)
899 :     get_pcvar_string(p_port,port,9)
900 :     if(equal(ip,"192.168.",8))format(url,99,"http://%s:%s/%s",iip,port,file)
901 :     else format(url,99,"http://%s:%s/%s",eip,port,file)
902 :     }
903 :     else if(strlen(url)){
904 :     format(url,99,"%sclimb_scores.html",url)
905 :     }
906 :     return url
907 :     }
908 :     //Show scoreboard
909 :     public climbscores(id){
910 :     if(get_pcvar_num(p_climb)){
911 :     new fpn[100],bool:limit=true,cust_msg[129]
912 :     get_pcvar_string(p_stats_msg,cust_msg,128)
913 :     if(!get_limit())limit=false
914 :     fpn=pathname("climb_scores.html")
915 :     if(get_systime()-score_ts>2){
916 :     new fh=fopen(fpn,"w")
917 :     fprintf(fh,"<html><head>%s<link rel=stylesheet href=http://ian.cammarata.us/climb/sb.css></head><body><table><tr>",limit?"":"<meta http-equiv=pragma content=no-cache>")
918 :     fprintf(fh,"<th height=1%%>Reg</th><th>#</th><th width=28%%>Name</th><th width=15%%>Status</th><th width=8%%>Time</th><th width=6%%>CP#</th><th width=6%%>GC#</th>")
919 :     fprintf(fh,"<th width=8%%>Best</th><th width=6%%>CP#</th><th width=6%%>GC#</th><th width=10%%>Completed</th></tr><tr><td class=st colspan=11></td></tr>")
920 :     //99+144+134=377
921 :     new line[251],name[33],players[32],num,tid,writen_len
922 :     get_players_ordered(players,num)
923 :     for(new i=1;i<=num;i++){
924 :     tid=players[i-1]
925 :     if(!is_user_hltv(tid)&&is_user_connected(tid)){
926 :     get_user_name(tid,name,32)
927 :     htmlspecialchars(name)
928 :     formatex(line,250,"<tr%s><td height=1%>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td></tr>",i%2?"":" class='o'",timer[tid][TMR_DBUSER]>0?"y":"n",i,name,getuserstatus(tid),parsetime(getusertime(tid)),timer[tid][TMR_CPSCNT],timer[tid][TMR_GCSCNT],parsetime(timer[tid][TMR_BSTTME]),timer[tid][TMR_BSTGCS],timer[tid][TMR_BSTCPS],timer[tid][TMR_MAPFIN])
929 :     writen_len+=strlen(line)
930 :     if(limit&&writen_len>(1003-strlen(cust_msg)))break
931 :     fprintf(fh,line)
932 :     }
933 :     }
934 :     //1530-150-377=1003
935 :     fprintf(fh,"<tr><td></td></tr><tr><td class=sb colspan=11></td></tr><tr><th colspan=4 height=1%>")
936 :     fprintf(fh,"climb v%s by: Ian Cammarata</th><th colspan=7>%s</th></tr></table></body></html>",VERSION,cust_msg)
937 :     fclose(fh)
938 :     score_ts=get_systime()
939 :     }
940 :    
941 :     if(!limit)fpn=get_url(id,"climb_scores.html")
942 :     show_motd(id,fpn,"Current Scores")
943 :     }
944 :     return PLUGIN_HANDLED
945 :     }
946 :     //Show High Scores
947 :     public highscores(id){
948 :     new hsurl[150],mapname[33]
949 :     get_pcvar_string(p_stats_hsurl,hsurl,149)
950 :     get_mapname(mapname,32)
951 :     if(strlen(hsurl)){
952 :     formatex(hsurl,149,hsurl,mapname)
953 :     show_motd(id,hsurl,"High Scores")
954 :     return PLUGIN_HANDLED
955 :     }
956 :     if(get_systime()-hscore_ts>10){
957 :     new query[250],data[1]
958 :     data[0]=id
959 :     formatex(query,249,"select p.alias, s.fin_time, s.cps, s.gcs, s.fin_cnt from %sscores s, %splayers p where s.map_name='%s' and p.user_id=s.user_id order by s.fin_time, s.gcs, s.cps limit 20;",db_prefix,db_prefix,mapname)
960 :     SQL_ThreadQuery(db_tuple,"hs_handler",query,data,1)
961 :     hscore_ts=get_systime()
962 :     }
963 :     else{
964 :     new fpn[100],bool:limit=true
965 :     if(!get_limit())limit=false
966 :     fpn=pathname("climb_highscores.html")
967 :     if(!limit)fpn=get_url(id,"climb_highscores.html")
968 :     show_motd(id,fpn,"High Scores")
969 :     }
970 :    
971 :     return PLUGIN_HANDLED
972 :     }
973 :     public hs_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){
974 :     if(failstate == TQUERY_CONNECT_FAILED)
975 :     return server_print("Climb: Couldn't connect to database.")
976 :     else if(failstate == TQUERY_QUERY_FAILED)
977 :     return server_print("Climb: Query failed: %s",error)
978 :    
979 :     if(errnum)
980 :     return server_print("Climb: Query Error: %s",error)
981 :    
982 :     new id=data[0],msg[50],num=SQL_NumResults(query)
983 :     if(!num){
984 :     msg="^x04[Climb] No stats available for the current map."
985 :     return saytext(id,id,msg)
986 :     }
987 :    
988 :     new fpn[100],bool:limit=true,cust_msg[129]
989 :     get_pcvar_string(p_stats_msg,cust_msg,128)
990 :     if(!get_limit())limit=false
991 :     fpn=pathname("climb_highscores.html")
992 :     new fh=fopen(fpn,"w")
993 :     fprintf(fh,"<html><head>%s<link rel=stylesheet href=http://ian.cammarata.us/climb/sb.css></head><body><table><tr>",limit?"":"<meta http-equiv=pragma content=no-cache>")
994 :     fprintf(fh,"<th height=1%%>#</th><th width=45%%>Name</th><th width=20%%>Time</th><th width=10%%>CP#</th>")
995 :     fprintf(fh,"<th width=10%%>GC#</th><th width=10%%>Completed</th></tr><tr><td class=st colspan=6></td></tr>")
996 :     //99+88+92=279
997 :     new name[33],line[151],writen_len
998 :     for(new i=1;i<=num;i++){
999 :     SQL_ReadResult(query,0,name,32)
1000 :     htmlspecialchars(name)
1001 :     formatex(line,150,"<tr%s><td height=1%>%d</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td></tr>",i%2?"":" class='o'",i,name,parsetime(SQL_ReadResult(query,1)),SQL_ReadResult(query,2),SQL_ReadResult(query,3),SQL_ReadResult(query,4))
1002 :     writen_len+=strlen(line)
1003 :     if(limit&&writen_len>(1101-strlen(cust_msg)))break
1004 :     fprintf(fh,line)
1005 :     SQL_NextRow(query)
1006 :     }
1007 :     //1530-150-279=1101
1008 :     fprintf(fh,"<tr><td></td></tr><tr><td class=sb colspan=6></td></tr><tr><th colspan=2 height=1%>")
1009 :     fprintf(fh,"climb v %s by: Ian Cammarata</th><th colspan=4>%s</th></tr></table></body></html>",VERSION,cust_msg)
1010 :     fclose(fh)
1011 :    
1012 :     if(!limit)fpn=get_url(id,"climb_highscores.html")
1013 :     show_motd(id,fpn,"High Scores")
1014 :    
1015 :     return PLUGIN_HANDLED
1016 :     }
1017 :     //Convert seconds to time string with zero padded seconds field
1018 :     public parsetime(sec){
1019 :     new timestr[9],mins
1020 :     mins=sec/60
1021 :     sec=sec%60
1022 :     formatex(timestr,8,"%d:%s%d",mins,sec<10?"0":"",sec)
1023 :     return timestr
1024 :     }
1025 :     //Calculate client climb time in seconds
1026 :     public getusertime(id){
1027 :     new ptime,cflags=timer[id][TMR_CFLAGS]
1028 :     //ptime=timer[id][TMR_FINISH]-timer[id][TMR_STARTD]
1029 :     //if(cflags&CF_STOP&&timer[id][TMR_SESFIN]>0)ptime=ptime<10000?ptime:0
1030 :     if(cflags&CF_STOP&&timer[id][TMR_SESFIN]>0)ptime=timer[id][TMR_FINISH]-timer[id][TMR_STARTD]
1031 :     else if(cflags&CF_STOP)ptime=0
1032 :     else if(cflags&CF_START)ptime=get_systime()-timer[id][TMR_STARTD]
1033 :     else if(cflags&CF_PAUSE)ptime=timer[id][TMR_STARTD]
1034 :     return ptime
1035 :     }
1036 :     //Set clock on HUD to current climb time
1037 :     public hudtime(){
1038 :     if(get_pcvar_num(p_climb)){
1039 :     new player,players[32],num
1040 :     get_players(players,num,"ac")
1041 :     for(new i=0;i<num;i++){
1042 :     player=players[i]
1043 :     message_begin(1,get_user_msgid("RoundTime"),{0,0,0},player)
1044 :     write_short(getusertime(player)+1)
1045 :     message_end()
1046 :     if(timer[player][TMR_CFLAGS]&CF_PAUSE)clmsg(player,"PAUSED")
1047 :     }
1048 :     }
1049 :     return 1
1050 :     }
1051 :     //Return string describing user status
1052 :     public getuserstatus(id){
1053 :     new msg[12]
1054 :     if(timer[id][TMR_CFLAGS]&CF_STOP&&timer[id][TMR_SESFIN]>0)msg="Finished"
1055 :     /*else switch(timer[id][TMR_CFLAGS]){
1056 :     case TMR_CFLAGS_STOP: msg="Not Started"
1057 :     case TMR_CFLAGS_STRT: msg="Climbing"
1058 :     case TMR_CFLAGS_PAUS: msg="Paused"
1059 :     }*/
1060 :     else if(timer[id][TMR_CFLAGS]&CF_STOP)msg="Not Started"
1061 :     else if(timer[id][TMR_CFLAGS]&CF_START)msg="Climbing"
1062 :     else if(timer[id][TMR_CFLAGS]&CF_PAUSE)msg="Paused"
1063 :     return msg
1064 :     }
1065 :     //Show Hud Message
1066 :     public clmsg(id, msg[]){
1067 :     set_hudmessage(get_pcvar_num(p_msg_r),get_pcvar_num(p_msg_g),get_pcvar_num(p_msg_b),get_pcvar_float(p_msg_x),get_pcvar_float(p_msg_y),0,0.0,5.0,0.5,0.5,4)
1068 :     show_hudmessage(id,msg)
1069 :     return PLUGIN_HANDLED
1070 :     }
1071 :     //Make client solid
1072 :     public solid(id){
1073 :     set_user_rendering(id,kRenderFxNone,0,0,0,kRenderNormal,255)
1074 :     entity_set_int(id,EV_INT_solid,SOLID_BBOX)
1075 :     return PLUGIN_CONTINUE
1076 :     }
1077 :     //Make client unsolid
1078 :     public unsolid(id){
1079 :     if(get_pcvar_num(p_render))set_user_rendering(id,kRenderFxPulseSlow,0,0,0,kRenderTransTexture,50)
1080 :     else set_user_rendering(id,kRenderFxHologram,0,0,0,kRenderTransAdd,0)
1081 :     entity_set_int(id,EV_INT_solid,SOLID_NOT)
1082 :     return PLUGIN_CONTINUE
1083 :     }
1084 :     //Check client solid
1085 :     public playersolid(id){
1086 :     if(entity_get_int(id,EV_INT_solid)==SOLID_BBOX)return 1
1087 :     return 0
1088 :     }
1089 :     //Use in IF statements to automatically print error if false
1090 :     public isalive(id){
1091 :     if(is_user_alive(id))return 1
1092 :     clmsg(id,"You must be alive to execute this command.")
1093 :     return 0
1094 :     }
1095 :     //Use in IF statements to automatically print error if false
1096 :     public notpaused(id){
1097 :     if(!(timer[id][TMR_CFLAGS]&CF_PAUSE))return 1
1098 :     clmsg(id,"You can't execute this command while paused.")
1099 :     return 0
1100 :     }
1101 :     //Used in IF statements a lot
1102 :     public isct(id){
1103 :     if(get_user_team(id)==2)return 1
1104 :     return 0
1105 :     }
1106 :     //Called when client takes damage
1107 :     public damage(id){
1108 :     new ida[1]
1109 :     ida[0]=id
1110 :     set_task(0.1,"damage_handle",_,ida,1)
1111 :     }
1112 :     //Damage hander, delayed to provide HUD consistency
1113 :     public damage_handle(ida[1]){
1114 :     new id=ida[0]
1115 :     if(get_pcvar_num(p_climb)&&is_user_alive(id)){
1116 :     new chp=get_user_health(id)
1117 :     if(chp!=hp){
1118 :     new wpn,atk=get_user_attacker(id,wpn)
1119 :     //Heal hp immediately
1120 :     if((atk==0||(id==atk&&wpn==0))&&!task_exists(50+id))set_user_health(id,hp)
1121 :     //Heal delayed
1122 :     else{
1123 :     if(task_exists(50+id))remove_task(50+id)
1124 :     set_task(5.0,"heal",50+id,ida,1)
1125 :     //Fix hp display at 0
1126 :     if(chp==256)set_user_health(id,257)
1127 :     }
1128 :     }
1129 :     else if(task_exists(50+id))remove_task(50+id)
1130 :     }
1131 :     return PLUGIN_HANDLED
1132 :     }
1133 :     //Heal client to predetermined HP required by map
1134 :     public heal(ida[]){
1135 :     if(is_user_alive(ida[0]))set_user_health(ida[0],hp)
1136 :     return PLUGIN_HANDLED
1137 :     }
1138 :     public pfn_keyvalue(ent){
1139 :     static bool:first_run=true
1140 :     new temp_ent
1141 :     if(first_run){
1142 :     for(new i=0;i<32;i++){
1143 :     temp_ent=create_entity("info_player_start")
1144 :     if(temp_ent>0){
1145 :     dyn_spawn_count++
1146 :     dyn_spawn_ids[dyn_spawn_count]=temp_ent
1147 :     entity_set_int(temp_ent,EV_INT_iuser1,1)
1148 :     //DispatchKeyValue(temp_ent,"origin","0 0 0")
1149 :     //DispatchKeyValue(temp_ent,"angles","0 0 0")
1150 :     }
1151 :     }
1152 :     first_run=false
1153 :     }
1154 :     /*static bool:got_first=false,bool:done=false,first_id,first_orig[21],first_angle[21]
1155 :     new class[26],key[26],val[26]
1156 :     copy_keyvalue(class,25,key,25,val,25)
1157 :    
1158 :     if(equal(class,"info_player_start")&&is_valid_ent(ent)){
1159 :     if(!done){
1160 :     if(!got_first){
1161 :     console_print(0,"DEBUG: Got First")
1162 :     first_id=ent
1163 :     got_first=true
1164 :     }
1165 :     if(got_first&&!done&&ent==first_id){
1166 :     if(equal(key,"origin"))copy(first_orig,20,val)
1167 :     else if(equal(key,"angles"))copy(first_angle,20,val)
1168 :     if(strlen(first_orig)&&strlen(first_angle)){
1169 :     done=true
1170 :     console_print(0,"DEBUG: orig:%s angle:%s",first_orig,first_angle)
1171 :     new i,sp
1172 :     for(i=0;i<31;i++){
1173 :     sp=create_entity("info_player_start")
1174 :     if(ent>0){
1175 :     entity_set_int(sp,EV_INT_iuser1,1)
1176 :     DispatchKeyValue(sp,"origin",first_orig)
1177 :     DispatchKeyValue(sp,"angles",first_angle)
1178 :     }
1179 :     }
1180 :     }
1181 :     }
1182 :     }
1183 :     if(done&&entity_get_int(ent,EV_INT_iuser1)!=1)remove_entity(ent)
1184 :     }*/
1185 :     return PLUGIN_CONTINUE
1186 :     }
1187 :     public plugin_cfg(){
1188 :     //fix timer built into map
1189 :     set_cvar_num("sv_restartround",1)
1190 :     set_cvar_num("sv_gravity",800)
1191 :     new ent,count=0,tmpstr[32],Float:tmpflt
1192 :     get_mapname(tmpstr,32)
1193 :     //map specific fixes : real gravity in nasa maps instead of trigger_push brush.
1194 :     if(equali(tmpstr,"kz_man_nasa")||equali(tmpstr,"kz_man_eznasa")){
1195 :     remove_entity_name("trigger_push")
1196 :     set_cvar_num("sv_gravity",500)
1197 :     }
1198 :     //Non-Solid check: *trigger_teleport,trigger_once,trigger_gravity,trigger_push
1199 :     //trigger_teleport
1200 :     ent=find_ent_by_class(-1,"trigger_teleport")
1201 :     while(ent>0){
1202 :     trig[trignum]=ent
1203 :     trignum++
1204 :     ent=find_ent_by_class(ent,"trigger_teleport")
1205 :     }
1206 :     //trigger_gravity
1207 :     ent=find_ent_by_class(-1,"trigger_gravity")
1208 :     while(ent>0){
1209 :     trig[trignum]=ent
1210 :     trignum++
1211 :     ent=find_ent_by_class(ent,"trigger_gravity")
1212 :     }
1213 :     //trigger_once
1214 :     /* ent=find_ent_by_class(-1,"trigger_once")
1215 :     while(ent>0){
1216 :     trig[trignum]=ent
1217 :     trignum++
1218 :     ent=find_ent_by_class(ent,"trigger_once")
1219 :     }
1220 :     //trigger_push
1221 :     ent=find_ent_by_class(-1,"trigger_push")
1222 :     while(ent>0){
1223 :     trig[trignum]=ent
1224 :     trignum++
1225 :     ent=find_ent_by_class(ent,"trigger_push")
1226 :     }*/
1227 :     //server_print("***** %d trigger entities found *****",trignum)
1228 :     //Remove neg dmg: *trigger_hurt,*func_door
1229 :     //func_door neg dmg removal
1230 :     ent=find_ent_by_class(-1,"func_door")
1231 :     while(ent>0){
1232 :     tmpflt=entity_get_float(ent,EV_FL_dmg)
1233 :     if(tmpflt<0){
1234 :     count++
1235 :     hp=floatround(tmpflt)
1236 :     remove_entity(ent)
1237 :     ent=-1
1238 :     }
1239 :     ent=find_ent_by_class(ent,"func_door")
1240 :     }
1241 :     server_print("***** %d neg dmg func_door entities removed *****",count)
1242 :     //trigger_hurt neg dmg removal
1243 :     count=0
1244 :     ent=find_ent_by_class(-1,"trigger_hurt")
1245 :     while(ent>0){
1246 :     tmpflt=entity_get_float(ent,EV_FL_dmg)
1247 :     if(tmpflt<0){
1248 :     count++
1249 :     hp=floatround(tmpflt)
1250 :     remove_entity(ent)
1251 :     ent=-1
1252 :     }
1253 :     ent=find_ent_by_class(ent,"trigger_hurt")
1254 :     }
1255 :     server_print("***** %d neg dmg trigger_hurt entities removed *****",count)
1256 :     hp=abs(hp)
1257 :     hp=clamp(hp,100,511)
1258 :     //Healing door trigger button removal
1259 :     count=0
1260 :     ent=find_ent_by_class(-1,"func_button")
1261 :     while(ent>0){
1262 :     entity_get_string(ent,EV_SZ_target,tmpstr,32)
1263 :     if(containi(tmpstr,"heal")>-1||containi(tmpstr,"goddoor")>-1){
1264 :     count++
1265 :     remove_entity(ent)
1266 :     ent=-1
1267 :     }
1268 :     ent=find_ent_by_class(ent,"func_button")
1269 :     }
1270 :     server_print("***** %d healing door buttons entities removed *****",count)
1271 :     //func_breakables
1272 :     ent=find_ent_by_class(-1,"func_breakable")
1273 :     while(ent>0){
1274 :     if(entity_get_int(ent,EV_INT_spawnflags)==2){
1275 :     brk[brknum]=ent
1276 :     brknum++
1277 :     }
1278 :     ent=find_ent_by_class(ent,"func_breakable")
1279 :     }
1280 :     server_print("***** %d func_breakable entities found *****",brknum)
1281 :     //Remove unneeded entities if it's a climbing map.
1282 :     count=0
1283 :     new bool:has_start_button=false,Float:sb_orig[3]
1284 :     ent=find_ent_by_class(-1,"func_button")
1285 :     while(ent>0){
1286 :     entity_get_string(ent,EV_SZ_target,tmpstr,32)
1287 :     if(equal(tmpstr,"counter_start")||equal(tmpstr,"clockstartbutton")||equal(tmpstr,"firsttimerelay")){
1288 :     has_start_button=true
1289 :     get_brush_entity_origin(ent,sb_orig)
1290 :     break
1291 :     }
1292 :     ent=find_ent_by_class(ent,"func_button")
1293 :     }
1294 :     if(has_start_button){
1295 :     remove_entity_name("player_weaponstrip")
1296 :     remove_entity_name("armoury_entity")
1297 :     remove_entity_name("info_player_deathmatch")
1298 :     get_mapname(tmpstr,32)
1299 :     //Health chargers needed for some maps as climbing platforms, don't remove
1300 :     //if(!(equali(tmpstr,"kz_real_skyscraper")||equali(tmpstr,"kz_northpole_b01")))remove_entities("func_healthcharger")
1301 :     count++
1302 :     //Remove map built in start button sounds
1303 :     ent=find_ent_by_class(-1,"ambient_generic")
1304 :     while(ent>0){
1305 :     entity_get_string(ent,EV_SZ_targetname,tmpstr,32)
1306 :     if(equal(tmpstr,"counter_start")||equal(tmpstr,"clockstartbutton")||equal(tmpstr,"firsttimerelay")){
1307 :     remove_entity(ent)
1308 :     }
1309 :     ent=find_ent_by_class(ent,"ambient_generic")
1310 :     }
1311 :     //Count original map spawns and remove extra dyn created spawns
1312 :     new map_spawns[32][2],map_spawns_count,Float:orig[3]
1313 :     ent=find_ent_by_class(-1,"info_player_start")
1314 :     while(ent>0&&map_spawns_count<32){
1315 :     if(entity_get_int(ent,EV_INT_iuser1)!=1){
1316 :     entity_get_vector(ent,EV_VEC_origin,orig)
1317 :     map_spawns[map_spawns_count][0]=floatround(vector_distance(orig,sb_orig))
1318 :     map_spawns[map_spawns_count][1]=ent
1319 :     map_spawns_count++
1320 :     while(dyn_spawn_count>=0){
1321 :     entity_get_string(dyn_spawn_ids[dyn_spawn_count],EV_SZ_classname,tmpstr,31)
1322 :     if(equal(tmpstr,"info_player_start")&&entity_get_int(dyn_spawn_ids[dyn_spawn_count],EV_INT_iuser1)==1){
1323 :     remove_entity(dyn_spawn_ids[dyn_spawn_count])
1324 :     dyn_spawn_count--
1325 :     break
1326 :     }
1327 :     else dyn_spawn_count--
1328 :     }
1329 :     }
1330 :     ent=find_ent_by_class(ent,"info_player_start")
1331 :     }
1332 :     //Save origin of spawn closest to start and arrange all spawn points to positions of the next 4 closest
1333 :     //SortCustom2D(map_spawns,map_spawns_count,"spawn_distance_sort");
1334 :     SortStrings(map_spawns,map_spawns_count)
1335 :     entity_get_vector(map_spawns[0][1],EV_VEC_origin,spawn_tp_orig)
1336 :     //remove_entity(map_spawns[0][1])
1337 :     entity_set_vector(map_spawns[0][1],EV_VEC_origin,Float:{0,0,0})
1338 :     for(new i=5;i<map_spawns_count;i++)//normal i=5
1339 :     entity_set_vector(map_spawns[i][1],EV_VEC_origin,Float:{0,0,0})
1340 :     /*new Float:orig2[3],i
1341 :     entity_get_vector(map_spawns[1][1],EV_VEC_origin,orig)
1342 :     entity_get_vector(map_spawns[2][1],EV_VEC_origin,orig2)
1343 :     for(i=3;i<map_spawns_count;i++){
1344 :     if((i/2)==(i%2))entity_set_vector(map_spawns[i][1],EV_VEC_origin,orig)
1345 :     else entity_set_vector(map_spawns[i][1],EV_VEC_origin,orig2)
1346 :     }*/
1347 :     }
1348 :     else{
1349 :     while(dyn_spawn_count>=0){
1350 :     ent=dyn_spawn_ids[dyn_spawn_count]
1351 :     entity_get_string(ent,EV_SZ_classname,tmpstr,31)
1352 :     //entity_get_string(dyn_spawn_ids[i],EV_SZ_classname,tmpstr,31)
1353 :     if(equal(tmpstr,"info_player_start")&&entity_get_int(ent,EV_INT_iuser1)==1)remove_entity(ent)
1354 :     dyn_spawn_count--
1355 :     }
1356 :     }
1357 :     return PLUGIN_CONTINUE
1358 :     }
1359 :     /*public spawn_distance_sort(elem1[],elem2[]){
1360 :     if(elem1[1]<elem2[1])return -1
1361 :     if(elem1[1]>elem2[1])return 1
1362 :     return 0
1363 :     }*/
1364 :     //Future use, to block hook, or detect hook cheaters a.k.a. hookers
1365 :     public phook(id){
1366 :     hooked[id]=1
1367 :     return PLUGIN_CONTINUE
1368 :     }
1369 :     public mhook(id){
1370 :     hooked[id]=0
1371 :     return PLUGIN_CONTINUE
1372 :     }
1373 :     //Make a public viewable help page for this on my web host.
1374 :     public climb_help(id){
1375 :     if(get_pcvar_num(p_climb)){
1376 :     show_motd(id,"http://ian.cammarata.us/climb/help/2a2/","Climb Plugin Help")
1377 :     }
1378 :     return PLUGIN_HANDLED
1379 :     }
1380 :     public boost_help(id){
1381 :     if(get_pcvar_num(p_climb)){
1382 :     show_motd(id,"http://ian.cammarata.us/climb/help/2a2/boost.html","Climb Plugin Help")
1383 :     }
1384 :     return PLUGIN_HANDLED
1385 :     }
1386 :     //Force client to CT
1387 :     public menuteam(id){
1388 :     if(get_pcvar_num(p_climb))client_cmd(id,"slot2")
1389 :     return PLUGIN_CONTINUE
1390 :     }
1391 :     //Force client to choose random model
1392 :     public menuclass(id){
1393 :     if(get_pcvar_num(p_climb)){
1394 :     client_cmd(id,"slot5")
1395 :     }
1396 :     return PLUGIN_CONTINUE
1397 :     }
1398 :     //Used to teleport clients, prevents client collisions and getting stuck
1399 :     public teleport(id,Float:orig[3]){
1400 :     new Float:c2[3],player,players[32],num
1401 :     get_players(players,num,"ac")
1402 :     unsolid(id)
1403 :     for(new i=0;i<num;i++){
1404 :     player=players[i]
1405 :     if(id!=player){
1406 :     entity_get_vector(player,EV_VEC_origin,c2)
1407 :     if(vector_distance(orig,c2)<74)unsolid(player)
1408 :     }
1409 :     }
1410 :     entity_set_vector(id,EV_VEC_velocity,Float:{0.0, 0.0, 0.0})
1411 :     entity_set_vector(id,EV_VEC_origin,orig)
1412 :     delay_duck(id)
1413 :     return 1
1414 :     }
1415 :     //Used by teleport and traceline-timer start, prevents getting stuck
1416 :     public delay_duck(id){
1417 :     new ida[1]
1418 :     ida[0]=id
1419 :     set_task(0.01,"force_duck",_,ida,1)
1420 :     set_entity_flags(ida[0],FL_DUCKING,1)
1421 :     }
1422 :     //Task for delay_duck
1423 :     public force_duck(ida[1]){
1424 :     set_entity_flags(ida[0],FL_DUCKING,1)
1425 :     }
1426 :     //Use in IF statements to automatically print error if false
1427 :     public cvar_enabled(id,p_cvar){
1428 :     if(get_pcvar_num(p_cvar)==0){
1429 :     clmsg(id,"This command is disabled.")
1430 :     client_print(id,print_chat,"This command has been disabled by the server administrator.")
1431 :     return 0
1432 :     }
1433 :     return 1
1434 :     }
1435 :     //Admin command, teleport to client
1436 :     public goto_player(id,level,cid){
1437 :     if(cmd_access(id,level,cid,2)&&get_pcvar_num(p_climb)){
1438 :     new tid,arg[24]
1439 :     read_argv(1,arg,sizeof(arg)-1)
1440 :     tid=cmd_target(tid,arg,4)
1441 :     if(tid){
1442 :     new Float:orig[3]
1443 :     entity_get_vector(tid,EV_VEC_origin,orig)
1444 :     teleport(id,orig)
1445 :     }
1446 :     }
1447 :     return PLUGIN_HANDLED
1448 :     }
1449 :     //Move yourself to spectator
1450 :     public spectate(id){
1451 :     if(get_pcvar_num(p_climb)&&(get_user_flags(id)&ADMIN_RESERVATION?1:(cvar_enabled(id,p_allow_spectators)))){
1452 :     cs_set_user_team(id,3)
1453 :     set_msg_block(get_user_msgid("DeathMsg"),1)
1454 :     user_kill(id,1)
1455 :     }
1456 :     return PLUGIN_HANDLED
1457 :     }
1458 :     //Block client kill command
1459 :     public client_kill(id){
1460 :     if(get_pcvar_num(p_climb)==1)return PLUGIN_HANDLED
1461 :     return PLUGIN_CONTINUE
1462 :     }
1463 :     //Used to block some commands
1464 :     public block_cmd(id){
1465 :     if(get_pcvar_num(p_climb))return PLUGIN_HANDLED
1466 :     return PLUGIN_CONTINUE
1467 :     }
1468 :     public block_cmd2(id){
1469 :     return PLUGIN_HANDLED
1470 :     }
1471 :     //Block client trying to switch teams
1472 :     public block_jointeam(id){
1473 :     if(get_pcvar_num(p_climb)&&isct(id))return PLUGIN_HANDLED
1474 :     return PLUGIN_CONTINUE
1475 :     }
1476 :     //Forward to catch all formats for commands
1477 :     public client_command(id){
1478 :     if(!get_pcvar_num(p_climb))
1479 :     return PLUGIN_CONTINUE
1480 :     new cmd[21]
1481 :     read_argv(0,cmd,20)
1482 :     //If say command replace command with say text, abort if more than one word
1483 :     if(equal(cmd,"say")||equal(cmd,"say_team")){
1484 :     read_argv(1,cmd,20)
1485 :     trim(cmd)
1486 :     if(contain(cmd," ")>-1)return PLUGIN_CONTINUE
1487 :     }
1488 :     //Remove slashes
1489 :     if(equal(cmd,"/",1)||equal(cmd,"\",1)||equal(cmd,".",1)||equal(cmd,"!",1))copy(cmd,20,cmd[1])
1490 :     //Make a checkpoint
1491 :     if(equali(cmd,"checkpoint")||equali(cmd,"check")||equali(cmd,"cp"))check(id)
1492 :     //Go to checkpoint
1493 :     else if(equali(cmd,"gocheck")||equali(cmd,"gc")||equali(cmd,"tp")||equali(cmd,"tele"))gocheck(id)
1494 :     //Boost help page
1495 :     else if(equali(cmd,"boost"))boost_help(id)
1496 :     //Solid Boost
1497 :     else if(equali(cmd,"solid")||equali(cmd,"semiclip"))change_boost(id,CF_SOLID)
1498 :     //Jump Boost
1499 :     else if(equali(cmd,"superjump")||equali(cmd,"sjump")||equali(cmd,"sj")||equali(cmd,"longjump")||equali(cmd,"ljump")||equali(cmd,"lj"))change_boost(id,CF_SUPER_JUMP)
1500 :     //Double Jump Boost
1501 :     else if(equali(cmd,"doublejump")||equali(cmd,"djump")||equali(cmd,"dj"))change_boost(id,CF_DOUBLE_JUMP)
1502 :     //Stuck
1503 :     else if(equali(cmd,"stuck")||equali(cmd,"unstuck"))stuck(id)
1504 :     //Pause
1505 :     else if(equali(cmd,"pause")||equali(cmd,"unpause"))change_status(id,CF_PAUSE)
1506 :     //Restart
1507 :     else if(equali(cmd,"restart")||equali(cmd,"reset"))reset(id)
1508 :     //Stop
1509 :     else if(equali(cmd,"stop"))stop(id)
1510 :     //Time/Scores
1511 :     else if(equali(cmd,"scoreboard")||equali(cmd,"score")||equali(cmd,"scores"))climbscores(id)
1512 :     //Top Scores
1513 :     else if(equali(cmd,"top10")||equali(cmd,"top15")||equali(cmd,"top")||equali(cmd,"highscores")||equali(cmd,"best")||equali(cmd,"rank"))highscores(id)
1514 :     //Respawn
1515 :     else if(equali(cmd,"respawn")||equali(cmd,"spawn"))frespawn(id)
1516 :     //Spectate
1517 :     else if(equali(cmd,"spectate")||equali(cmd,"spec"))spectate(id)
1518 :     //Climb Help
1519 :     else if(equali(cmd,"help")||equali(cmd,"climbhelp")||equali(cmd,"kzhelp"))climb_help(id)
1520 :     //If none of above conditions met, don't block the command
1521 :     else return PLUGIN_CONTINUE
1522 :     return PLUGIN_HANDLED
1523 :     }
1524 :     public donothing(){
1525 :     return PLUGIN_CONTINUE
1526 :     }
1527 :     public regwarn(id){
1528 :     if(timer[id][TMR_DBUSER]<1){
1529 :     saytext(id,id,"^x04You must register/login for your stats to save. Say /help for more info.")
1530 :     return 1
1531 :     }
1532 :     return 0
1533 :     }
1534 :     public db_init(){
1535 :     //update from old db version
1536 :     //alter table climb_scores add boosts int
1537 :     //alter table climb_scores add wpns int
1538 :     //alter table climb_scores add score int
1539 :     //update climb_scores set boosts=-1
1540 :     //update climb_scores set wpns=-1
1541 :     static host[32],user[32],pass[32],name[32],type[12]
1542 :    
1543 :     get_cvar_string("climb_db_host",host,31)
1544 :     get_cvar_string("climb_db_user",user,31)
1545 :     get_cvar_string("climb_db_pass",pass,31)
1546 :     get_cvar_string("climb_db_name",name,31)
1547 :     get_cvar_string("climb_db_type",type,11)
1548 :     get_cvar_string("climb_db_prefix",db_prefix,31)
1549 :    
1550 :     //SQL_SetAffinity(type)
1551 :     db_tuple=SQL_MakeDbTuple(host,user,pass,name)
1552 :    
1553 :     new query[600]
1554 :     formatex(query,599,"\
1555 :     create table %splayers (\
1556 :     user_id integer primary key autoincrement,\
1557 :     steam_id char(25) unique,\
1558 :     password char(6),\
1559 :     user_name varchar(20) unique,\
1560 :     alias varchar(32) unique,\
1561 :     email varchar(50) unique,\
1562 :     cflags integer);\
1563 :     ",db_prefix)
1564 :     SQL_ThreadQuery(db_tuple,"db_generic_handler",query)
1565 :     formatex(query,599,"\
1566 :     create table %sscores (\
1567 :     score_id integer primary key autoincrement,\
1568 :     score integer,\
1569 :     server_ip char(15),\
1570 :     user_id integer,\
1571 :     map_name varchar(32),\
1572 :     fin_time integer,\
1573 :     cps integer,\
1574 :     gcs integer,\
1575 :     fin_cnt integer,\
1576 :     boosts integer,\
1577 :     wpns integer,\
1578 :     server_time_stamp integer);\
1579 :     create unique index scores_usermap_idx on %sscores (user_id, map_name);\
1580 :     create index scores_score on %sscores (score);\
1581 :     ",db_prefix,db_prefix,db_prefix)
1582 :     SQL_ThreadQuery(db_tuple,"db_generic_handler",query)
1583 :     formatex(query,599,"\
1584 :     create table %ssessions (\
1585 :     steam_id char(25) primary key,\
1586 :     user_id integer unique);\
1587 :     ",db_prefix)
1588 :     SQL_ThreadQuery(db_tuple,"db_generic_handler",query)
1589 :     return PLUGIN_HANDLED
1590 :     }
1591 :     public db_generic_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){
1592 :     if(failstate == TQUERY_CONNECT_FAILED)
1593 :     return server_print("Climb: Couldn't connect to database.")
1594 :     else if(failstate == TQUERY_QUERY_FAILED)
1595 :     return server_print("Climb: Query failed: %s",error)
1596 :    
1597 :     if(errnum)
1598 :     return server_print("Climb: Query Error: %s",error)
1599 :     return PLUGIN_HANDLED
1600 :     }
1601 :     public logout(id){
1602 :     for(new i=0;i<8;i++)origins[id][i]=0.0
1603 :     for(new i=0;i<11;i++)timer[id][i]=0
1604 :     }
1605 :     public login(id){
1606 :     if(get_pcvar_num(p_climb)){
1607 :     if(climb_save){
1608 :     if(timer[id][TMR_DBUSER]>0){//Already logged in
1609 :     client_print(id,print_console,"[Climb] Login Error: You are already logged in.")
1610 :     return PLUGIN_HANDLED
1611 :     }
1612 :     new query[99],data[28]
1613 :     data[0]=id
1614 :     if(read_argc()>1){//Client is logging in with a user/pass
1615 :     new user[21],pass[21]
1616 :     read_argv(1,user,20)
1617 :     read_argv(2,pass,20)
1618 :     rotwtf(pass,6)
1619 :     data[1]=1
1620 :     formatex(query,98,"select user_id from %splayers where user_id='%s' and password='%s';",db_prefix,user,pass)
1621 :     formatex(data[2],25,user)
1622 :     SQL_ThreadQuery(db_tuple,"login_handler",query,data,28)
1623 :     }
1624 :     else{//Client is logging in with SteamID
1625 :     new sid[26]
1626 :     get_user_authid(id,sid,25)
1627 :     data[1]=2
1628 :     formatex(query,98,"select user_id, password from %splayers where steam_id='%s';",db_prefix,sid)
1629 :     formatex(data[2],25,sid)
1630 :     SQL_ThreadQuery(db_tuple,"login_handler",query,data,28)
1631 :     }
1632 :     }
1633 :     else client_print(id,print_console,"[Climb] Login Error: Can't Login; Stats not enabled.")
1634 :     }
1635 :     return PLUGIN_HANDLED
1636 :     }
1637 :     public login_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){
1638 :     new id=data[0]
1639 :     if(failstate == TQUERY_CONNECT_FAILED)
1640 :     return server_print("Climb: Couldn't connect to database.")
1641 :     else if(failstate == TQUERY_QUERY_FAILED)
1642 :     return server_print("Climb: Query failed: %s",error)
1643 :    
1644 :     if(errnum)
1645 :     return server_print("Climb: Query Error: %s",error)
1646 :    
1647 :     if(SQL_NumResults(query)<1)
1648 :     return client_print(id,print_console,"[Climb] Login Error: Not a valid account.")
1649 :    
1650 :     if(data[1]==2){
1651 :     new pass[7]
1652 :     SQL_ReadResult(query,1,pass,6)
1653 :     if(equali(pass,"shared")){
1654 :     client_print(id,print_console,"[Climb] Login Error: You are using a shared SteamID. Please login with a username and password.")
1655 :     return PLUGIN_HANDLED
1656 :     }
1657 :     }
1658 :     timer[id][TMR_DBUSER]=SQL_ReadResult(query,0)
1659 :     new msg[100]
1660 :     formatex(msg,99,"[Climb] Login: Success - Account: %s",data[2])
1661 :     client_print(id,print_console,msg)
1662 :     format(msg,99,"^x04%s",msg)
1663 :     saytext(id,id,msg)
1664 :     db_load(id)
1665 :     return PLUGIN_HANDLED
1666 :     }
1667 :     public db_load(id){
1668 :     new query[150],mapname[33],data[1]
1669 :     data[0]=id
1670 :     get_mapname(mapname,32)
1671 :     formatex(query,149,"select fin_time, cps, gcs, fin_cnt from %sscores where user_id=%d and map_name='%s';",db_prefix,timer[id][TMR_DBUSER],mapname)
1672 :     SQL_ThreadQuery(db_tuple,"db_load_handler",query,data,1)
1673 :     return PLUGIN_HANDLED
1674 :     }
1675 :     public db_load_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){
1676 :     if(failstate == TQUERY_CONNECT_FAILED)
1677 :     return server_print("Climb: Couldn't connect to database.")
1678 :     else if(failstate == TQUERY_QUERY_FAILED)
1679 :     return server_print("Climb: Query failed: %s",error)
1680 :    
1681 :     if(errnum)
1682 :     return server_print("Climb: Query Error: %s",error)
1683 :    
1684 :     new msg[100],id=data[0]
1685 :     if(!SQL_NumResults(query))
1686 :     msg="^x04No stats available for this account on the current map."
1687 :     else{
1688 :     new mapname[33],timestr[9]
1689 :     get_mapname(mapname,32)
1690 :     timer[id][TMR_BSTTME]=SQL_ReadResult(query,0)
1691 :     timer[id][TMR_BSTCPS]=SQL_ReadResult(query,1)
1692 :     timer[id][TMR_BSTGCS]=SQL_ReadResult(query,2)
1693 :     timer[id][TMR_MAPFIN]=SQL_ReadResult(query,3)
1694 :     timestr=parsetime(timer[id][TMR_BSTTME])
1695 :     formatex(msg,99,"^x04Stats loaded for %s - %s^t(%d CPS/ %d GCS)^tCompleted %d",mapname,timestr,timer[id][TMR_BSTCPS],timer[id][TMR_BSTGCS],timer[id][TMR_MAPFIN])
1696 :     }
1697 :     saytext(id,id,msg)
1698 :     return PLUGIN_HANDLED
1699 :     }
1700 :     public db_save(id){
1701 :     new query[150],name[33]
1702 :     get_mapname(name,32)
1703 :     if(timer[id][TMR_MAPFIN]==1)
1704 :     formatex(query,149,"insert into %sscores (user_id, map_name, fin_time, cps, gcs, fin_cnt)\
1705 :     values (%d, '%s', %d, %d, %d, %d);\
1706 :     ",db_prefix,timer[id][TMR_DBUSER],name,timer[id][TMR_BSTTME],timer[id][TMR_BSTCPS],timer[id][TMR_BSTGCS],timer[id][TMR_MAPFIN])
1707 :     else
1708 :     formatex(query,149,"update %sscores set fin_time=%d, cps=%d, gcs=%d, fin_cnt=%d where user_id=%d and map_name='%s';",db_prefix,timer[id][TMR_BSTTME],timer[id][TMR_BSTCPS],timer[id][TMR_BSTGCS],timer[id][TMR_MAPFIN],timer[id][TMR_DBUSER],name)
1709 :     SQL_ThreadQuery(db_tuple,"db_save_handler",query)
1710 :     get_user_name(id,name,32)
1711 :     formatex(query,149,"update %splayers set alias='%s' where user_id=%d;",db_prefix,name,timer[id][TMR_DBUSER])
1712 :     SQL_ThreadQuery(db_tuple,"db_save_handler",query)
1713 :     return PLUGIN_HANDLED
1714 :     }
1715 :     public db_save_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){
1716 :     if(failstate == TQUERY_CONNECT_FAILED)
1717 :     return server_print("Climb: Couldn't connect to database.")
1718 :     else if(failstate == TQUERY_QUERY_FAILED)
1719 :     return server_print("Climb: Query failed: %s",error)
1720 :    
1721 :     if(errnum)
1722 :     return server_print("Climb: Query Error: %s",error)
1723 :    
1724 :     return PLUGIN_HANDLED
1725 :     }
1726 :     public reg(id){
1727 :     if(get_pcvar_num(p_climb)){
1728 :     if(climb_save){
1729 :     new query[100],sid[26],name[33],data[43]
1730 :     data[0]=id
1731 :     data[1]=0
1732 :     get_user_authid(id,sid,25)
1733 :     get_user_name(id,name,32)
1734 :     //Register user/pass
1735 :     if(read_argc()>1){
1736 :     if(read_argc()!=3){
1737 :     client_print(id,print_console,"[Climb] Registration Error: Invalid number of arguments")
1738 :     return PLUGIN_HANDLED
1739 :     }
1740 :     new user[21],pass[50]
1741 :     //Read password and check length
1742 :     read_argv(2,pass,20)
1743 :     if(strlen(pass)<10){
1744 :     client_print(id,print_console,"[Climb] Registration Error: Password must be at least 10 characters.")
1745 :     return PLUGIN_HANDLED
1746 :     }
1747 :     //Read user
1748 :     read_argv(1,user,20)
1749 :     //Store user/pass in data array to pass to handler for autologin
1750 :     formatex(data[2],20,user)
1751 :     formatex(data[22],20,pass)
1752 :     //Create password hash
1753 :     rotwtf(pass,6)
1754 :     //Register shared SteamID
1755 :     formatex(query,99,"insert into %splayers (steam_id,password) values ('%s','shared')",db_prefix,sid)
1756 :     SQL_ThreadQuery(db_tuple,"reg_handler",query,data,43)
1757 :     //Register user/pass
1758 :     data[1]=1
1759 :     formatex(query,99,"insert into %splayers (user_name,password,alias) values ('%s','%s','%s')",db_prefix,user,pass,name)
1760 :     SQL_ThreadQuery(db_tuple,"reg_handler",query,data,43)
1761 :     }
1762 :     //Else register SteamID
1763 :     else{
1764 :     data[1]=2
1765 :     formatex(query,99,"insert into %splayers (steam_id,alias) values ('%s','%s')",db_prefix,sid,name)
1766 :     SQL_ThreadQuery(db_tuple,"reg_handler",query,data,43)
1767 :     }
1768 :     }
1769 :     else client_print(id,print_console,"[Climb] Registration Error: Can't Register; Stats not enabled.")
1770 :     }
1771 :     return PLUGIN_HANDLED
1772 :     }
1773 :     public reg_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){
1774 :     new id=data[0],flag=data[1],user[21],pass[21]
1775 :     format(user,20,data[2])
1776 :     format(pass,20,data[22])
1777 :     if(failstate == TQUERY_CONNECT_FAILED)
1778 :     return server_print("[Climb] Couldn't connect to database.")
1779 :     else if(failstate == TQUERY_QUERY_FAILED)
1780 :     return server_print("[Climb] Query failed: %s",error)
1781 :    
1782 :     if(errnum){
1783 :     client_print(id,print_console,"[Climb] Registration Error: Database error, please notify the server admin.")
1784 :     return server_print("[Climb] Query Error: %s",error)
1785 :     }
1786 :    
1787 :    
1788 :     if(flag==0)client_print(id,print_console,"[Climb] Recorded shared SteamID.")
1789 :     else{
1790 :     client_print(id,print_console,"[Climb] Registration Successful.")
1791 :     new cmd[50]
1792 :     formatex(cmd,49,"login %s %s",user,pass)
1793 :     client_cmd(id,cmd)
1794 :     }
1795 :     return PLUGIN_HANDLED
1796 :     }
1797 :     public rotwtf(string[],out_len){
1798 :     new len=strlen(string),str[99],cnt=0,tok=len-1
1799 :     copy(str,out_len,string)
1800 :     for(new index=0;index<11;index++){
1801 :     if('a'<=string[index]<='z')
1802 :     str[index]=(str[index]-'a'+string[tok]+index)
1803 :     else if('A'<=str[index]<='Z')
1804 :     str[index]=(str[index]-'A'+string[tok]+index)
1805 :     else if('0'<=str[index]<='9')
1806 :     str[index]=(str[index]-'0'+string[tok]+index)
1807 :     switch(cnt){
1808 :     case 0:str[index]=str[index]%26+'a'
1809 :     case 1:str[index]=str[index]%26+'A'
1810 :     case 2:str[index]=str[index]%10+'0'
1811 :     }
1812 :     tok--
1813 :     if(tok<0)tok=len-1
1814 :     cnt++
1815 :     if(cnt==3)cnt=0
1816 :     }
1817 :     copy(string,out_len,str)
1818 :     return PLUGIN_HANDLED
1819 :     }
1820 :     public plugin_init(){
1821 :     register_plugin("Climb",VERSION,"Ian Cammarata")
1822 :     register_cvar("climb_version",VERSION,FCVAR_SERVER)
1823 :    
1824 :     p_climb= register_cvar("climb","1",FCVAR_SERVER)
1825 :     p_boost= register_cvar("climb_boost","1")
1826 :     p_cpprice=register_cvar("climb_cpprice","0")
1827 :    
1828 :     register_cvar("climb_save","1")
1829 :    
1830 :     register_cvar("climb_db_type","sqlite")
1831 :     register_cvar("climb_db_host","127.0.0.1")
1832 :     register_cvar("climb_db_user","")
1833 :     register_cvar("climb_db_pass","")
1834 :     register_cvar("climb_db_name","climb")
1835 :     register_cvar("climb_db_prefix","climb_")
1836 :    
1837 :     p_msg_r=register_cvar("climb_msg_r","0")
1838 :     p_msg_g=register_cvar("climb_msg_g","150")
1839 :     p_msg_b=register_cvar("climb_msg_b","250")
1840 :     p_msg_x=register_cvar("climb_msg_x","0.05")
1841 :     p_msg_y=register_cvar("climb_msg_y","0.5")
1842 :    
1843 :     p_sounds=register_cvar("climb_sounds","1")
1844 :     p_render=register_cvar("climb_unsolid_type","0")
1845 :    
1846 :     p_ip_internal=register_cvar("ip_internal","localhost")
1847 :     p_ip_external=register_cvar("ip_external","localhost")
1848 :     p_port=get_cvar_pointer("port")
1849 :    
1850 :     p_webmod=register_cvar("climb_webmod","0")
1851 :     p_stats_path= register_cvar("climb_stats_path","")
1852 :     p_stats_url= register_cvar("climb_stats_url","")
1853 :     p_stats_hsurl= register_cvar("climb_stats_hsurl","") //Use %s in place of map name
1854 :     p_stats_msg= register_cvar("climb_stats_msg","")
1855 :    
1856 :     p_allow_spectators=get_cvar_pointer("allow_spectators")
1857 :     p_startmoney= register_cvar("climb_startmoney","1337")
1858 :     //General Client Commands
1859 :     //These commands get blocked always.
1860 :     register_clcmd("fullupdate","block_cmd2")
1861 :     //These commands get blocked when climb is enabled.
1862 :     register_clcmd("chooseteam","block_cmd")
1863 :     register_clcmd("buy","block_cmd")
1864 :     register_clcmd("buyammo1","block_cmd")
1865 :     register_clcmd("buyammo2","block_cmd")
1866 :     register_clcmd("buyequip","block_cmd")
1867 :     register_clcmd("jointeam","block_jointeam")
1868 :     //Commands to detect cheats.
1869 :     register_clcmd("+hook","phook")
1870 :     register_clcmd("+rope","phook")
1871 :     register_clcmd("-hook","mhook")
1872 :     register_clcmd("-rope","mhook")
1873 :     //Commands referencing function 'donothing' are picked up by the more flexible code in the client_command forward.
1874 :     register_clcmd("climbhelp","donothing",0,"- Veiw climb help.")
1875 :     register_clcmd("cp","donothing",_,"- Make a checkpoint")
1876 :     register_clcmd("gc","donothing",_,"- Teleport to last checkpoint")
1877 :     register_clcmd("stuck","donothing",_,"- Teleport to previous checkpoint")
1878 :     register_clcmd("restart","donothing",_,"- Stop and respawn.")
1879 :     register_clcmd("stop","donothing",_,"- End current climbing run.")
1880 :     register_clcmd("pause","donothing",_,"- Pause yourself.")
1881 :     register_clcmd("scoreboard","donothing",_,"- View score board.")
1882 :     register_clcmd("respawn","donothing",_,"- Force respawn")
1883 :     register_clcmd("boost","donothing",_,"- Boost.")
1884 :     register_clcmd("spec","donothing",_,"- Spectate mode.")
1885 :     //Commands related to stats account system.
1886 :     register_clcmd("register","reg",_,"- (Console Only) Register for stats tracking.")
1887 :     register_clcmd("login","login",_,"- (Console Only) Login to stats account.")
1888 :     //Admin Commands
1889 :     register_clcmd("amx_goto","goto_player",ADMIN_SLAY)
1890 :     //For scoreboard backend
1891 :     //register_srvcmd("amx_climb_sbrefresh","htmlscoreboard")
1892 :     //Events
1893 :     register_event("DeathMsg","death_msg","a")
1894 :     register_event("ResetHUD","spawned","b")
1895 :     //register_event("Damage","damage","b")
1896 :     register_event("Health","damage","b")
1897 :     register_event("ShowMenu","menuclass","b","4&CT_Select","4&Terrorist_Select")
1898 :     register_event("ShowMenu","menuteam","b","4&Team_Select_Spect","4&Team_Select","4&IG_Team_Select")
1899 :     //Init DB
1900 :     if(get_cvar_num("climb_save"))climb_save=true
1901 :     if(climb_save)db_init()
1902 :     //Init anti flood time stamps
1903 :     score_ts=get_systime()
1904 :     hscore_ts=get_systime()
1905 :     //Task to update time on clients HUD; Task set for half second to minimize flickering of the timer.
1906 :     set_task(0.5,"hudtime",_,_,_,"b")
1907 :     //Register FakeMeta Traceline forward.
1908 :     register_forward(FM_TraceLine, "traceline", 1)
1909 :     //Load Start/Finish Commands
1910 :     new ini[50]
1911 :     get_configsdir(ini,49)
1912 :     format(ini,49,"%s/climb.ini",ini)
1913 :     if(file_exists(ini)){
1914 :     new line=0,text[50],len
1915 :     while(read_file(ini,line++,text,sizeof(text)-1,len)){
1916 :     if(!equal(text,";",1)&&!equal(text,"#",1)&&!equal(text,"//",2)){
1917 :     if(sfcount<SF_MAX){
1918 :     sfactions[sfcount]=text
1919 :     sfcount++
1920 :     }
1921 :     }
1922 :     }
1923 :     }
1924 :     return PLUGIN_CONTINUE
1925 :     }
1926 :     public plugin_end()
1927 :     if(climb_save)
1928 :     SQL_FreeHandle(db_tuple)

Contact
ViewVC Help
Powered by ViewVC 1.0.4