Parent Directory | Revision Log
Revision 22 - (view) (download)
1 : | ian | 1 | /* |
2 : | Climb v2.0a4 | ||
3 : | Copyright (C) 2006-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 | ||
19 : | Sep 21 18:27 | ||
20 : | |||
21 : | |||
22 : | To do: | ||
23 : | Save user/pass login data for sessions (don't require login ever map change) | ||
24 : | Account management for accounts with user/pass login. email, change password, password recovery | ||
25 : | Unsolid as function of position and velocity | ||
26 : | Recode custom flashlight without temp entities | ||
27 : | |||
28 : | |||
29 : | Description: | ||
30 : | This plugin is designed for use in climbing maps like those available from www.kreedz.com. | ||
31 : | |||
32 : | |||
33 : | Commands: | ||
34 : | say /checkpoint : Save your position. | ||
35 : | say /gocheck : Teleport you to your last saved position. | ||
36 : | say /ungocheck : Undo a gocheck in case you accidentally use one after you make a tough jump. | ||
37 : | say /stuck : Teleport you to your previous checkpoint in case you get stuck in a wall. | ||
38 : | amx_goto : Teleport to another player. (Can't be used while timer is running) | ||
39 : | |||
40 : | A full help page can be found at http://ian.cammarata.us/projects/climb/help/2a3/en/commands | ||
41 : | |||
42 : | |||
43 : | Cvars: | ||
44 : | climb <1|0> : Enables|Disables all plugin functionality. The plugin now enables and disables itself, you should only use this cvar to turn the plugin on in maps which don't have a start button. | ||
45 : | climb_boost <1|0> : Enables|Disables boosting. | ||
46 : | climb_cpprice <0|...> : Set to dollar amount for cost of checkpoints. | ||
47 : | climb_startmoney <1337|0-16000> : Money amount set when players start timer. | ||
48 : | |||
49 : | climb_render <0|1> : Changes unsolid rendering style, 0=classic, other=new more see through rendering. | ||
50 : | climb_sounds <1|0> : Enables|Disables sounds build in to the Climb plugin. | ||
51 : | climb_start_respawn <0|1> : When enabled, eliminates unnecessary respawning. (Defaults to off) | ||
52 : | climb_water_nodraw: <0|1> : When enabled makes func_water entities invisible to help with players FPS issues. (Defaults to off) | ||
53 : | |||
54 : | climb_webmod <0|1> : Disables|Enables web mod interoperability. | ||
55 : | climb_stats_path <NULL|...> : Path to save generated stats pages. (If using WebMod, enter path to WebMod's www folder.) | ||
56 : | climb_stats_url <NULL|...> : URL to send clients to for stats pages. Only use if you have a web server running on the same machine as the game server. IF WEBMOD=1 THIS IS IGNORED. | ||
57 : | climb_stats_hsurl <NULL|...> : "%s" will be replaced with map name. Set to send client to URL if you have a page that automatically generates high scores via direct DB access. IF WEBMOD=1 THIS IS IGNORED. | ||
58 : | climb_stats_msg <NULL|...> : Message to display on scoreboard. Use HTML | ||
59 : | |||
60 : | ip_internal <localhost|...> : Set to internal network IP or hostname. (If server behind NAT) | ||
61 : | ip_external <localhost|...> : Set to external network IP or hostname. | ||
62 : | |||
63 : | climb_msg_r <0|0-255> : Display message red value. | ||
64 : | climb_msg_g <150|0-255> : Display message green value. | ||
65 : | climb_msg_b <250|0-255> : Display message blue value. | ||
66 : | climb_msg_x <0.05|0-1> : Display message x position. | ||
67 : | climb_msg_y <0.5|0-1> : Display message y position. | ||
68 : | |||
69 : | climb_light_r <255|0-255> : Sets the red value for the custom flashlight's color. | ||
70 : | climb_light_g <255|0-255> : Sets the green value for the custom flashlight's color. | ||
71 : | climb_light_b <255|0-255> : Sets the blue value for the custom flashlight's color. | ||
72 : | |||
73 : | *The following cvars are only read at plugin load, changes will not take effect until the map is changed. | ||
74 : | climb_save <1|0> : Enables|Disables saving of stats to a database. | ||
75 : | |||
76 : | climb_db_type <sqlite|mysql> : Database type. | ||
77 : | climb_db_host <127.0.0.1> : Database host name/ip. | ||
78 : | climb_db_user <NULL|...> : Database user name. | ||
79 : | climb_db_pass <NULL|...> : Database password. | ||
80 : | climb_db_name <climb|...> : Database name. | ||
81 : | climb_db_prefix <climb_|...> : Table name prefix. | ||
82 : | |||
83 : | |||
84 : | Requirements: | ||
85 : | AMXX 1.76 or higher | ||
86 : | Engine module | ||
87 : | Fakemeta module | ||
88 : | DB Module (MySQL or SQLite/Only needed if using CLIMB_SAVE 1.) | ||
89 : | |||
90 : | |||
91 : | Notes: | ||
92 : | Make sure you place the climb.txt file in addons\amxmodx\data\lang | ||
93 : | |||
94 : | I highly recommend using All Chat along with this plugin: | ||
95 : | http://forums.alliedmods.net/showthread.php?t=56825 | ||
96 : | |||
97 : | DF Hook Frontend plugin is included with this plugin, but still requires the Hookmod from AdminOP: | ||
98 : | http://www.adminop.net/modules.php?name=Downloads&d_op=viewdownloaddetails&lid=73&ttitle=Hook_Mod_Windows | ||
99 : | |||
100 : | To be able to get a full player listing on the scoreboard, you'll need to install WebMod and set the appropriate cvars for this plugin. | ||
101 : | WebMod site: http://djeyl.net/w.php | ||
102 : | |||
103 : | |||
104 : | Credits: | ||
105 : | Borrowed some code from Space Headed's bot_api.sma | ||
106 : | Borrowed some code from KCE's attack blocking tutorial (http://forums.alliedmods.net/showthread.php?t=41265) | ||
107 : | Thanks to Lola for letting me use her awesome server for testing purposes. | ||
108 : | http://1337bunnies.com | ||
109 : | 66.55.131.63:27015 | ||
110 : | Thanks to r33d and Woofie for testing and suggestions. | ||
111 : | |||
112 : | |||
113 : | Supported Languages: | ||
114 : | Not Applicable... yet. | ||
115 : | |||
116 : | |||
117 : | Change Log: | ||
118 : | Key (+ added | - removed | c changed | f fixed) | ||
119 : | |||
120 : | v2.0a4 (SEPT ??, 2007) | ||
121 : | +: New db admin commands: climb_dbwho, climb_dbmap, climb_dbplayer, climb_dbdelete. | ||
122 : | +: High scores now saves boosts, cps/gcs, and weapon used. | ||
123 : | +: New high scores sorting method. | ||
124 : | +: Breakable objects with health less than 9999 are now removed at map load. | ||
125 : | +: Duplicate names in database are now appended with "(#)" like the game scoreboard. | ||
126 : | +: Client commands 'cp+' and 'cp-' to cycle through checkpoints. | ||
127 : | +: Cvars mp_autoteambalance and mp_limitteams are set to 0 when a start button is found, and reverted when the map changes. | ||
128 : | +: Support for a2 maps start/finish buttons. | ||
129 : | +: Commands measure and measure2. | ||
130 : | +: Multiplayer friendly bhops. | ||
131 : | +: Command 'weapons', gives client one of each speed weapon. | ||
132 : | +: Ranking by weapon speed. ex: If you beat a map with AWP, you'll be ranked above other weapon scores. | ||
133 : | +: Command countdown to have time countdown from your best time instead of counting up. | ||
134 : | +: Instantly switch to spectator without death animation. | ||
135 : | -: Plugin ad on client connect. | ||
136 : | -: WebMod support since it is a huge security vulnerability. | ||
137 : | -: Cvars: climb_webmod, climb_stats_path, climb_stats_url, ip_internal, ip_external | ||
138 : | c: Tweaked semiclip to hopefully eliminate lag problems reported by some people. | ||
139 : | c: Cvar climb_water_nodraw changes take effect without reloading map. | ||
140 : | c: Database now stores multiple records per map per player. | ||
141 : | c: Cvar climb_db_pass is now protected. | ||
142 : | c: Optimized html layout of scoreboards to fit more data without using WebMod. | ||
143 : | c: Command '/stuck' is now an alias for 'cp-' and doesn't deduct from cp count. | ||
144 : | c: Start and restart commands now tp client to the start button (Spawn and respawn still tp to spawn point). | ||
145 : | c: Clients now spawn at start button. | ||
146 : | c: USP and M4 forced to be always silent. | ||
147 : | c: Guns reload with only 2 bullets, admins get unlimited clip for silenced guns. | ||
148 : | c: Timeout on knife slash. (The sound makes my ears bleed) | ||
149 : | c: Set 0.4 second timeout on cp, gc, and ungc commands. | ||
150 : | c: Set 2 second timeout on usp and scout commands. | ||
151 : | c: Re-enabled default flashlight, at least untill I recode the custom one. Custom NVG still in place. | ||
152 : | c: Respawn command now stops your timer, to prevent cheating in some maps. | ||
153 : | f: Bug where maps with built in auto-heal and healing doors didn't give 511 hp. (ex: kz_man_streetclimb) | ||
154 : | f: Showing high scores from previous map if client executes cmd a second time within the timeout period and current map has no scores in the DB. | ||
155 : | f: An exploit that involved a paused player with their view attached to something else. | ||
156 : | f: Bug where respawn command would spawn clients at maps origin if plugin was enabled without running init functions. | ||
157 : | f: Bug where multiple players could connect and get logged in with the same db user id. | ||
158 : | |||
159 : | v2.0a3 (JUNE 21, 2007) | ||
160 : | +: New alias for restart, /start. | ||
161 : | +: HP set to 512 when finished as god mode replacement. God mode prevents people from seeign each others names. | ||
162 : | +: Replicate hud messages and timer to spectators. | ||
163 : | +: Replacement flashlight/nightvision. Change color with cvars climb_light_r, ..._g, ..._b | ||
164 : | +: Cvar climb_start_respawn: eliminates unnecessary respawning, admin can enable if needed | ||
165 : | +: Cvar climb_water_nodraw: Makes func_water entities invisible to help with players FPS issues(off by default). | ||
166 : | +: Fake client added to CT team to prevent round end. Automatically leaves when the server is almost full, and rejoins as it empties. | ||
167 : | +: Two new commands, /scout and /usp, to get a scout or usp if you need one, or more ammo. | ||
168 : | +: New command /ungocheck or /ungc. Takes you to where you were before you last used gocheck. | ||
169 : | +: Can use chooseteam button or kill command to switch between spectating and playing. | ||
170 : | +: Plugin automatically disables on map change. Automatically enables if it finds a start button in new map. Setting the cvar climb to 1 in a map config will force the plugin to run. | ||
171 : | c: Spectators stay listed as CT on CS scoreboard so their rank will always show. | ||
172 : | c: Command amx_goto can be used by any player once they've completed the map. | ||
173 : | c: Players don't spawn with scout or c4 anymore. | ||
174 : | c: Newer unsolid render is default. | ||
175 : | c: New unsolid code provides perfect touch detection and eliminates problems that occurred in some maps. | ||
176 : | c: Decreased the wait time on some of the command timeouts. | ||
177 : | c: Replicated button use code from HL SDK. Start and finish button use detection is now perfect. | ||
178 : | c: In maps with built in healing climb auto heal is disabled(some maps like this have falling areas where you're not supposed to heal). | ||
179 : | f: Lag caused by respawning is pretty much eliminated by new weapon cleanup code and not giving as many weapons on spawn. | ||
180 : | f: MySQL query format problem for auto increment fields. | ||
181 : | f: SQLite query problem. Replaced single quotes around strings with double quotes. | ||
182 : | f: HLTV proxies caused two adjacent rows in scoreboard to be same color. | ||
183 : | f: Spectator lag bug. | ||
184 : | f: Bug where players had 511 HP on every map. | ||
185 : | |||
186 : | v2.0a2 (FEB 16, 2007) | ||
187 : | +: 2 addition boost types. Super jump and double jump. (No partner needed for boosting anymore) | ||
188 : | +: Boosts are counted. (Not logged in DB yet.) | ||
189 : | +: Stats saving in database. MySQL or SQLite. (MySQL not tested yet. Only works with single db module enabled) | ||
190 : | +: Players now get rewarded for finishing even without starting the timer. | ||
191 : | +: Cvars for message color and position. (climb_msg_r, ..._g, ..._b, ..._x, ..._y) | ||
192 : | +: Cvar climb_startmoney - Value to set money to when players start timer. | ||
193 : | +: Cvar climb_stats_msg - Message to display on the HTML scoreboards. | ||
194 : | +: Cvar climb_unsolid_type - Change rendering style for unsolid players. | ||
195 : | +: Cvar climb_sounds - Disabled Climb plugin sounds. | ||
196 : | +: Several cvars for database settings. | ||
197 : | +: All players spawn at spawn point closest to the start button. (Eliminates cheat in maps with a spawn point at the finish button.) | ||
198 : | +: Additional spawns added during map load to fix maps without enough spawns. | ||
199 : | +: Timeouts for respawning and boosting. | ||
200 : | +: Command "help". Displays HTML help pages. | ||
201 : | -: AMX compatibility. (AMX is officially dead) | ||
202 : | c: Cvars now prefixed with climb_ instead of amx_. | ||
203 : | c: Minor code optimizations. | ||
204 : | c: Command "Boost" now takes players to the boost help page instead of activating solid boost. | ||
205 : | c: All internal cvar handling is now done with pointers. (With the acception of cvars used only during init functions.) | ||
206 : | c: Solid boost only lasts 15 seconds at a time now since its usage is being tracked. | ||
207 : | c: Major internal rewrite (Probably added a few bugs. More major rewrites coming in next release.) | ||
208 : | |||
209 : | v1.9.19 (AUG 02, 2006) | ||
210 : | +: New public cvar 'climb_version' to aid in searching for server with this plugin. | ||
211 : | +: Show checkpoints, gochecks, and finish stats (Stats will be more extensive in next version) with finish announcement. | ||
212 : | -: Global chat. Use AllChat plugin instead. | ||
213 : | -: Cvar: amx_climb_globchat | ||
214 : | c: The /spec command now obeys the cvar "allow_spectators", clients with reserved slot always allowed. | ||
215 : | c: Shows number of checks and gocheck on client finish announcement. | ||
216 : | f: Bug caused by using stop command while paused. | ||
217 : | c: 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... | ||
218 : | |||
219 : | v1.9.18 (MAY 15, 2006) | ||
220 : | c: Recoded the way health is handled. Should work for any map now. | ||
221 : | |||
222 : | v1.9.17 (APR 07, 2006) | ||
223 : | c: Plugin is now compatible with both AMX and AMXX. | ||
224 : | c: The /spectate command can now be used by anyone. Admin no longer required. | ||
225 : | |||
226 : | v1.9.16a | ||
227 : | f: Added health fix for kz_cfl_yamakasi. | ||
228 : | c: New CSS theme for html scoreboard. | ||
229 : | |||
230 : | v1.9.16 | ||
231 : | +: Counts usage of CP and GC commands(only displayed on html scoreboard). | ||
232 : | f: Added health fix for kz_lighthouse and kz_phoogi. | ||
233 : | |||
234 : | v1.9.15 | ||
235 : | +: Colorized global chat. ADMIN_RESERVATION has name in green instead of team color. | ||
236 : | +: /stop command. Resets timer to zero, end climbing session. | ||
237 : | c: Reset function. /stop + /respawn. Client is now reset automatically when pressing the start button if they are not already started. | ||
238 : | f: YOU CAN'T GET STUCK ANYMORE!!! (Well almost. Doing gocheck a second time gets you unstuck.) | ||
239 : | f: Global chat is now logged correctly and shows up in HLSW. | ||
240 : | |||
241 : | v1.9.14 | ||
242 : | +: Hook is taken away when client starts timer, given back if they reset. | ||
243 : | +: Max health fixes for several new maps. | ||
244 : | +: Sort clients on CS scoreboard by climb rank. | ||
245 : | +: Cvar amx_climb_boost - enable\disable boosting. | ||
246 : | +: Cvar amx_climb_cpprice - charge money for checkpoints. | ||
247 : | +: Custom configurable commands based on events. (climb.ini) | ||
248 : | +: Global chat. cvar: amx_climb_globchat <1|0> | ||
249 : | +: Client climb time is now shown using the round time HUD sprites. | ||
250 : | -: Command /mytime, not needed because of HUD sprite timer. | ||
251 : | -: Auto time display every 30 seconds, not needed because of HUD sprite timer. | ||
252 : | c: Added another start button sound. | ||
253 : | c: Super healing doors no longer removed. (Needed for shortcuts in some maps.) | ||
254 : | f: Admins can't be alive as spectator even with 3rd party respawn plugin. | ||
255 : | f: Keep godmode after respawning if finished map and not reset. | ||
256 : | f: Admins VIP display on CS scoreboard is now updated whenever clients connect. | ||
257 : | f: Health charger minimaps in kz_real_skyscraper & kz_northpole_b01. | ||
258 : | f: Not teleporting to exact cp position if another client is on your cp. | ||
259 : | f: Respawning outside of maps sometimes immediately after leaving spectator. | ||
260 : | */ | ||
261 : | #include <amxmodx> | ||
262 : | #include <fun> | ||
263 : | #include <amxmisc> | ||
264 : | #include <engine> | ||
265 : | #include <fakemeta> | ||
266 : | #include <sqlx> | ||
267 : | #include <string2> | ||
268 : | #include <cstrike> | ||
269 : | #include <cstrike2> | ||
270 : | |||
271 : | ian | 22 | new const VERSION[ ] = "a3.7.1 Nov 18 06:22 MST" |
272 : | new const TRKCVAR[ ] = "climb_version" | ||
273 : | new const DONOTHING[ ] = "donothing" | ||
274 : | new const NULLSTR[ ] = "" | ||
275 : | ian | 1 | |
276 : | #define IN_ATTACK_EITHER ( IN_ATTACK + IN_ATTACK2 ) | ||
277 : | |||
278 : | #define SF_MAX 50 //Maximum number of start/finish commands in climb.ini | ||
279 : | |||
280 : | #define CPGC_TIMEOUT 0.4 //In seconds, decimal allowed | ||
281 : | #define SPAWN_TIMEOUT 2 //In seconds, whole number only / used for start button also | ||
282 : | #define WPN_TIMEOUT 2 //In seconds, whole number only | ||
283 : | #define BOOST_TIMEOUT 5 //In seconds, whole number only | ||
284 : | #define KNIFE_TIMEOUT 2 //In seconds, whole number only | ||
285 : | |||
286 : | #define NAMELEN 15 | ||
287 : | |||
288 : | #define DBADMIN ADMIN_RCON | ||
289 : | #define VIP ADMIN_RESERVATION | ||
290 : | |||
291 : | new MAXPLAYERS | ||
292 : | |||
293 : | //DB data | ||
294 : | new Handle:DB_TUPLE, DB_PREFIX[11], bool:CLIMB_SAVE, DB_SERVER_ID[16] | ||
295 : | new db_last_del_id | ||
296 : | |||
297 : | //Client flags arrays | ||
298 : | #define ORIGINS_SIZE 48 | ||
299 : | ian | 19 | new Float:origins[33][ORIGINS_SIZE] |
300 : | ian | 1 | #define ORIG_UNGC 40 |
301 : | #define ORIG_PAUS 44 | ||
302 : | //#define ORIG_X 0 | ||
303 : | //#define ORIG_Y 1 | ||
304 : | //#define ORIG_Z 2 | ||
305 : | #define ORIG_GRAV 3 | ||
306 : | |||
307 : | ian | 19 | new time_stamps[33][5]//time_stamps[id][x] |
308 : | ian | 1 | #define TS_SPAWN 0 |
309 : | #define TS_BOOST 1 | ||
310 : | #define TS_WPN 2 | ||
311 : | #define TS_CPGC 3 //This one holds a flag, not a timestamp so it can be < 1 second | ||
312 : | #define TS_KNIFE 4 | ||
313 : | |||
314 : | #define TIMER_SIZE 16 | ||
315 : | ian | 19 | new timer[33][TIMER_SIZE]//timer[id][x]: |
316 : | ian | 1 | #define TMR_CFLAGS 0 //Status |
317 : | #define TMR_STARTD 1 //Start Time | ||
318 : | #define TMR_FINISH 2 //Finish Time | ||
319 : | #define TMR_CNTCPS 3 //CP Count | ||
320 : | #define TMR_CNTGCS 4 //GC Count | ||
321 : | #define TMR_CNTBST 5 //Boosts | ||
322 : | #define TMR_BSTTME 6 //Best Time | ||
323 : | #define TMR_BSTCPS 7 //Best CP | ||
324 : | #define TMR_BSTGCS 8 //Best GC | ||
325 : | #define TMR_BSTBST 9 //Number of boosts used | ||
326 : | #define TMR_SESFIN 10 //Finished this session | ||
327 : | #define TMR_MAPFIN 11 //Total times finished this map | ||
328 : | #define TMR_DBUSER 12 //Database player ID; 0=not registered; -1=not registered & shared steam id | ||
329 : | #define TMR_CPPOS 13 //Current CP offset, for cycling back and forward through cps | ||
330 : | #define TMR_CNTWPN 14 //Current weapon rank modifier | ||
331 : | #define TMR_BSTWPN 15 //Best score weapon rank modifier | ||
332 : | |||
333 : | //Temp save vars | ||
334 : | new savepos = 0, steamid[32][32], Float:originssave[32][ORIGINS_SIZE], timersave[32][TIMER_SIZE] | ||
335 : | |||
336 : | //Other stuff | ||
337 : | ian | 19 | new hooked[33], hp = 100 |
338 : | ian | 1 | new sfactions[SF_MAX][50], sfcount = 0 |
339 : | new ts_score, ts_hscore, bool:has_hscores = false //scoreboard timeouts | ||
340 : | ian | 19 | new spec_ids[33][33] |
341 : | ian | 1 | new beam_sprite |
342 : | |||
343 : | new ST_BTNS[9], FN_BTNS[9], ST_BTN_CNT = 0, FN_BTN_CNT = 0 | ||
344 : | new dyn_spawn_ids[32], dyn_spawn_count, Float:spawn_tp_orig[3], Float:start_tp_orig[3] | ||
345 : | |||
346 : | ian | 19 | new bool:sclip[33],Float:post_think_vel[33][3],sc_fcount |
347 : | ian | 1 | |
348 : | new LIMIT_TEAMS_OLD, TEAM_BALANCE_OLD | ||
349 : | |||
350 : | //Bhop fix vars | ||
351 : | #define MAX_DOORS 500 | ||
352 : | new door_count = 0, func_doors[MAX_DOORS][3], Float:door_tp_pos[MAX_DOORS][3] | ||
353 : | ian | 19 | new bhop_failid[33], bool:bhop_fail[33] |
354 : | ian | 1 | //func_doors[x]{ id, speed, angles } |
355 : | |||
356 : | //Cvar Pointers | ||
357 : | new p_climb, p_auto, p_boost, p_cpprice, p_startmoney | ||
358 : | new p_msg_r, p_msg_g, p_msg_b, p_msg_x, p_msg_y | ||
359 : | new p_sounds, p_render | ||
360 : | new p_stats_hsurl, p_stats_msg | ||
361 : | new p_light_r, p_light_g, p_light_b | ||
362 : | new p_start_respawn, p_water_nodraw | ||
363 : | new p_allow_spectators, p_teambalance, p_limitteams | ||
364 : | |||
365 : | //Model size | ||
366 : | //standing 32x32x72 | ||
367 : | //crouched 32x32x36 | ||
368 : | |||
369 : | //Tasks: | ||
370 : | //#define TSK_AUTOHEAL 50 //50+ : Auto Heal | ||
371 : | #define TSK_AUTORSPN 100 //100+: Auto Respawn | ||
372 : | //#define TSK_BOOSTTMR 150 //150+: Solid Boost Timer | ||
373 : | #define TSK_FLIGHT 200 | ||
374 : | #define TSK_BHOP 250 | ||
375 : | #define TSK_CLEAR_FAIL 300 | ||
376 : | #define TSK_MEASURE2 350 | ||
377 : | |||
378 : | ian | 19 | //Status timer[id][TMR_CFLAGS]&=x |
379 : | ian | 1 | #define CF_NULL 0 //Passed to change_boost() to remove all boost flags |
380 : | #define CF_STOP (1<<0) //STATUS FLAG: Not Started | ||
381 : | #define CF_START (1<<1) //STATUS FLAG: Climbing | ||
382 : | #define CF_PAUSE (1<<2) //STATUS FLAG: Paused | ||
383 : | #define CF_STATUSFLAGS ( CF_STOP + CF_START + CF_PAUSE ) | ||
384 : | #define CF_SOLID (1<<3) //BOOST FLAG | ||
385 : | #define CF_SUPER_JUMP (1<<4) //BOOST FLAG | ||
386 : | #define CF_DOUBLE_JUMP (1<<5) //BOOST FLAG | ||
387 : | #define CF_LIGHT_ON (1<<6) | ||
388 : | //#define CF_NO_VIP (1<<7) | ||
389 : | #define CF_JUST_REGD (1<<8) | ||
390 : | #define CF_MEASURE (1<<9) | ||
391 : | #define CF_MEASURE2 (1<<10) | ||
392 : | #define CF_COUNTDOWN (1<<11) | ||
393 : | #define CF_SUNGLASSES (1<<12) | ||
394 : | |||
395 : | new SVC_STATUSICON, SVC_TEAMINFO, SVC_ROUNDTIME, SVC_FLASHLIGHT, SVC_SCREENFADE | ||
396 : | |||
397 : | new SCORES_PATH[100], HSCORES_PATH[100] | ||
398 : | |||
399 : | //////////////////////////////////////////////////////////////////////////////// | ||
400 : | // Start: Init forwards | ||
401 : | //////////////////////////////////////////////////////////////////////////////// | ||
402 : | public plugin_init( ) | ||
403 : | ian | 22 | { |
404 : | ian | 1 | register_plugin( "Climb", VERSION, "Ian Cammarata" ) |
405 : | ian | 22 | register_cvar( TRKCVAR, VERSION, FCVAR_SERVER ) |
406 : | set_cvar_string( TRKCVAR, VERSION ) | ||
407 : | ian | 1 | |
408 : | p_climb = register_cvar( "climb", "0", FCVAR_SERVER ) | ||
409 : | p_auto = register_cvar( "climb_auto", "1" ) | ||
410 : | p_boost = register_cvar( "climb_boost", "1" ) | ||
411 : | p_cpprice = register_cvar( "climb_cpprice", "0" ) | ||
412 : | p_startmoney = register_cvar( "climb_startmoney", "1337" ) | ||
413 : | |||
414 : | register_cvar( "climb_save", "1" ) | ||
415 : | register_cvar( "climb_db_type", "sqlite" ) | ||
416 : | register_cvar( "climb_db_host", "127.0.0.1" ) | ||
417 : | ian | 22 | register_cvar( "climb_db_user", NULLSTR ) |
418 : | register_cvar( "climb_db_pass", NULLSTR, FCVAR_PROTECTED ) | ||
419 : | ian | 1 | register_cvar( "climb_db_name", "climb" ) |
420 : | register_cvar( "climb_db_prefix", "climb_" ) | ||
421 : | ian | 22 | register_cvar( "climb_db_serverid", NULLSTR ) |
422 : | ian | 1 | register_cvar( "climb_db_exists", "0" ) |
423 : | |||
424 : | p_msg_r = register_cvar( "climb_msg_r", "0" ) | ||
425 : | p_msg_g = register_cvar( "climb_msg_g", "150" ) | ||
426 : | p_msg_b = register_cvar( "climb_msg_b", "250" ) | ||
427 : | p_msg_x = register_cvar( "climb_msg_x", "0.05" ) | ||
428 : | p_msg_y = register_cvar( "climb_msg_y", "0.5" ) | ||
429 : | |||
430 : | p_light_r = register_cvar( "climb_light_r", "255" ) | ||
431 : | p_light_g = register_cvar( "climb_light_g", "255" ) | ||
432 : | p_light_b = register_cvar( "climb_light_b", "255" ) | ||
433 : | |||
434 : | p_sounds = register_cvar( "climb_sounds", "1" ) | ||
435 : | p_render = register_cvar( "climb_unsolid_type", "0" ) | ||
436 : | p_start_respawn = register_cvar( "climb_start_respawn", "0" ) | ||
437 : | p_water_nodraw = register_cvar( "climb_water_nodraw", "0" ) | ||
438 : | |||
439 : | ian | 22 | p_stats_hsurl = register_cvar( "climb_stats_hsurl", NULLSTR ) //Use %s in place of map name |
440 : | p_stats_msg = register_cvar( "climb_stats_msg", NULLSTR ) | ||
441 : | ian | 1 | |
442 : | p_allow_spectators = get_cvar_pointer( "allow_spectators" ) | ||
443 : | p_teambalance = get_cvar_pointer( "mp_autoteambalance" ) | ||
444 : | p_limitteams = get_cvar_pointer( "mp_limitteams" ) | ||
445 : | |||
446 : | ian | 22 | MAXPLAYERS = get_maxplayers( ) |
447 : | |||
448 : | ian | 1 | TEAM_BALANCE_OLD = get_pcvar_num( p_teambalance ) |
449 : | LIMIT_TEAMS_OLD = get_pcvar_num( p_limitteams ) | ||
450 : | |||
451 : | //Message Pseudo-Constants | ||
452 : | SVC_STATUSICON = get_user_msgid( "StatusIcon" ) | ||
453 : | SVC_TEAMINFO = get_user_msgid( "TeamInfo" ) | ||
454 : | SVC_ROUNDTIME = get_user_msgid( "RoundTime" ) | ||
455 : | SVC_FLASHLIGHT = get_user_msgid( "Flashlight" ) | ||
456 : | SVC_SCREENFADE = get_user_msgid( "ScreenFade" ) | ||
457 : | |||
458 : | //These commands get blocked always. | ||
459 : | register_clcmd( "fullupdate", "block_cmd2" ) | ||
460 : | |||
461 : | //These commands get blocked when climb is enabled. | ||
462 : | register_clcmd( "chooseteam", "spectate" ) | ||
463 : | register_clcmd( "buy", "block_cmd" ) | ||
464 : | register_clcmd( "buyammo1", "block_cmd" ) | ||
465 : | register_clcmd( "buyammo2", "block_cmd" ) | ||
466 : | register_clcmd( "buyequip", "block_cmd" ) | ||
467 : | |||
468 : | register_clcmd( "jointeam", "block_jointeam" ) | ||
469 : | |||
470 : | //Commands to detect cheats. | ||
471 : | register_clcmd( "+hook", "phook" ) | ||
472 : | register_clcmd( "+rope", "phook" ) | ||
473 : | register_clcmd( "-hook", "mhook" ) | ||
474 : | register_clcmd( "-rope", "mhook" ) | ||
475 : | |||
476 : | //Commands referencing function 'donothing' are picked up by the more flexible code in the client_command forward. | ||
477 : | register_clcmd( "say help", "help_msg" ) | ||
478 : | register_clcmd( "say /help", "help_msg" ) | ||
479 : | ian | 22 | register_clcmd( "climbhelp", DONOTHING, 0, "- Veiw climb help." ) |
480 : | register_clcmd( "cp", DONOTHING, _, "- Make a checkpoint" ) | ||
481 : | register_clcmd( "gc", DONOTHING, _, "- Teleport to last checkpoint" ) | ||
482 : | register_clcmd( "stuck", DONOTHING, _, "- Teleport to previous checkpoint" ) | ||
483 : | register_clcmd( "restart", DONOTHING, _, "- Stop and respawn." ) | ||
484 : | register_clcmd( "stop", DONOTHING, _, "- End current climbing run." ) | ||
485 : | register_clcmd( "pause", DONOTHING, _, "- Pause yourself." ) | ||
486 : | register_clcmd( "scoreboard", DONOTHING, _, "- View score board." ) | ||
487 : | register_clcmd( "respawn", DONOTHING, _, "- Force respawn" ) | ||
488 : | register_clcmd( "boost", DONOTHING, _, "- Boost." ) | ||
489 : | register_clcmd( "spec", DONOTHING, _, "- Spectate mode." ) | ||
490 : | register_clcmd( "ungc", DONOTHING, _, "- Undo last gocheck." ) | ||
491 : | ian | 1 | |
492 : | //Commands related to stats account system. | ||
493 : | //register_clcmd( "register", "reg", _, "- (Console Only) Register for stats tracking." ) | ||
494 : | register_clcmd( "login", "db_login", _, "- (Console Only) Login to stats account." ) | ||
495 : | |||
496 : | register_concmd( "climb_dbwho", "climb_dbwho", DBADMIN, "- List DB ID of current clients." ) | ||
497 : | register_concmd( "climb_dbmap", "climb_dbmap", DBADMIN, "<Map Name> - List high scores for current map." ) | ||
498 : | register_concmd( "climb_dbuser", "climb_dbuser", DBADMIN, "[DB User ID] - List high scores for given DB User ID." ) | ||
499 : | register_concmd( "climb_dbdelete", "climb_dbdelete", DBADMIN, "[DB Score ID] - Delete score for given DB Score ID." ) | ||
500 : | |||
501 : | //temp commands | ||
502 : | register_concmd("climb_dbrecalc","climb_dbrecalc",DBADMIN) | ||
503 : | |||
504 : | //Admin Commands | ||
505 : | register_clcmd("amx_goto","goto_player") | ||
506 : | |||
507 : | //Climb Flashlight | ||
508 : | //register_impulse(100,"tog_flight") | ||
509 : | register_clcmd("nightvision","tog_flight") | ||
510 : | |||
511 : | //Events | ||
512 : | register_event("DeathMsg","DeathMsg","a") | ||
513 : | register_event("ResetHUD","ResetHUD","b") | ||
514 : | ian | 22 | register_event("Health","Health","b") |
515 : | ian | 1 | register_event("ShowMenu","menuclass","b","4&CT_Select","4&Terrorist_Select") |
516 : | register_event("ShowMenu","menuteam","b","4&Team_Select_Spect","4&Team_Select","4&IG_Team_Select") | ||
517 : | |||
518 : | //Init DB | ||
519 : | if( get_cvar_num( "climb_save" ) ) CLIMB_SAVE = true | ||
520 : | if( CLIMB_SAVE ) db_init( ) | ||
521 : | |||
522 : | //Init anti flood time stamps | ||
523 : | ts_score = get_systime( ) | ||
524 : | ts_hscore = get_systime( ) | ||
525 : | set_task( 0.5, "hudtime", _, _, _, "b" ) //Task to update time on clients HUD; Task set for half second to minimize flickering of the timer. | ||
526 : | set_task( 1.0, "spec_update", _, _, _, "b" ) //Task to update spectator array | ||
527 : | set_task( 5.0, "run_tasks", _, _, _, "b" ) | ||
528 : | |||
529 : | register_message( get_user_msgid( "CurWeapon" ), "CurWeapon" ) | ||
530 : | |||
531 : | register_forward( FM_UpdateClientData, "PostUpdateClientData", 1 ) | ||
532 : | |||
533 : | //register_dictionary("climb.txt") | ||
534 : | |||
535 : | //Make var folder if not exists | ||
536 : | new path[61] | ||
537 : | get_localinfo( "amxx_datadir", path, 60 ) | ||
538 : | format( path, 60, "%s/var", path ) | ||
539 : | if( !dir_exists( path ) ) mkdir( path ) | ||
540 : | formatex( SCORES_PATH, 99, "%s/climb_scores.html", path ) | ||
541 : | formatex( HSCORES_PATH, 99, "%s/climb_highscores.html", path ) | ||
542 : | |||
543 : | //Load Start/Finish Commands | ||
544 : | new ini[50] | ||
545 : | get_configsdir( ini, 49 ) | ||
546 : | format( ini, 49, "%s/climb.ini", ini ) | ||
547 : | if( file_exists( ini ) ) | ||
548 : | { | ||
549 : | new line = 0, text[50], len | ||
550 : | while( read_file( ini, line++, text, sizeof(text)-1 , len ) ) | ||
551 : | { | ||
552 : | if( !equal( text, ";", 1 ) && !equal( text, "#", 1 ) && !equal( text, "//", 2 ) ) | ||
553 : | { | ||
554 : | if( sfcount < SF_MAX ) | ||
555 : | { | ||
556 : | sfactions[sfcount] = text | ||
557 : | sfcount++ | ||
558 : | } | ||
559 : | } | ||
560 : | } | ||
561 : | } | ||
562 : | return PLUGIN_CONTINUE | ||
563 : | } | ||
564 : | |||
565 : | public pfn_keyvalue( ent ) | ||
566 : | { | ||
567 : | //Create more ct spawns so everyone can join team | ||
568 : | if( dyn_spawn_count < 1 ) | ||
569 : | { | ||
570 : | new id | ||
571 : | for( dyn_spawn_count = 0; dyn_spawn_count < 30; dyn_spawn_count++ ) | ||
572 : | { | ||
573 : | id = create_entity( "info_player_start" ) | ||
574 : | if( id > 0 ) | ||
575 : | { | ||
576 : | dyn_spawn_ids[dyn_spawn_count] = id | ||
577 : | entity_set_int( id, EV_INT_iuser1, 1 ) | ||
578 : | } | ||
579 : | } | ||
580 : | } | ||
581 : | |||
582 : | static last_ent | ||
583 : | new class[31], key[31], val[31] | ||
584 : | copy_keyvalue( class, 30, key, 30, val, 30 ) | ||
585 : | |||
586 : | if( ent != last_ent && func_doors[door_count][0] && door_count < MAX_DOORS ) | ||
587 : | door_count++ | ||
588 : | |||
589 : | if( equal( class, "func_door" ) ) | ||
590 : | { | ||
591 : | //func_doors[x]{ id, speed, angles } | ||
592 : | |||
593 : | if( ent != last_ent ) func_doors[door_count][0] = ent | ||
594 : | |||
595 : | if( equal( key, "speed" ) ) | ||
596 : | func_doors[door_count][1] = str_to_num(val) | ||
597 : | if( equal( key, "dmg" ) ) | ||
598 : | func_doors[door_count][0] = 0 | ||
599 : | if( equal( key, "angles" ) ) | ||
600 : | { | ||
601 : | new angles[5] | ||
602 : | parse( val, angles, 4 ) | ||
603 : | func_doors[door_count][2] = str_to_num( angles ) | ||
604 : | } | ||
605 : | last_ent = ent | ||
606 : | } | ||
607 : | |||
608 : | return PLUGIN_CONTINUE | ||
609 : | } | ||
610 : | |||
611 : | public plugin_cfg( ) | ||
612 : | { | ||
613 : | new ent, ent2, tmpstr[33], Float:tmpflt | ||
614 : | |||
615 : | if( func_doors[door_count][0] && door_count < MAX_DOORS ) | ||
616 : | door_count++ | ||
617 : | |||
618 : | //Find tp spots for doors, in case they're used for bhop | ||
619 : | //func_doors[x]{ id, speed, angles } | ||
620 : | for( new i = 0; i < door_count; i++ ) | ||
621 : | { | ||
622 : | ent = func_doors[i][0] | ||
623 : | if( !is_valid_ent( ent ) ) func_doors[i][0] = 0 | ||
624 : | else | ||
625 : | { | ||
626 : | new Float:dmins[3], Float:dmaxs[3] | ||
627 : | entity_get_vector( ent, EV_VEC_mins, dmins ) | ||
628 : | entity_get_vector( ent, EV_VEC_maxs, dmaxs ) | ||
629 : | |||
630 : | new dwid = floatround( dmaxs[0] - dmins[0] ) | ||
631 : | new dlen = floatround( dmaxs[1] - dmins[1] ) | ||
632 : | |||
633 : | //If the door moves up, or is thin, remove it's id from the array | ||
634 : | if( func_doors[i][2] < 0 || dwid < 24 || dlen < 24 ) | ||
635 : | func_doors[i][0] = 0 | ||
636 : | //Otherwise find a safe tp spot in case it's a bhop door | ||
637 : | else | ||
638 : | { | ||
639 : | //If it has a targetname, change the id in array to targeter | ||
640 : | entity_get_string( ent, EV_SZ_targetname, tmpstr, 32 ) | ||
641 : | if( strlen( tmpstr ) ) | ||
642 : | { | ||
643 : | ent2 = find_ent_by_target( -1, tmpstr ) | ||
644 : | if( ent2 ) | ||
645 : | { | ||
646 : | func_doors[i][0] = ent2 | ||
647 : | |||
648 : | //If targeter is a button, remove it's id from the array | ||
649 : | entity_get_string( ent2, EV_SZ_classname, tmpstr, 32 ) | ||
650 : | if( equal( tmpstr, "func_button" ) ) | ||
651 : | func_doors[i][0] = 0 | ||
652 : | } | ||
653 : | } | ||
654 : | |||
655 : | new Float:tmpvec[3], Float:tmpvec2[3] | ||
656 : | |||
657 : | new Float:dr_tc[3] | ||
658 : | dr_tc[0] = ( dmaxs[0] + dmins[0] ) / 2 | ||
659 : | dr_tc[1] = ( dmaxs[1] + dmins[1] ) / 2 | ||
660 : | dr_tc[2] = dmaxs[2] | ||
661 : | |||
662 : | tmpvec[0] = ( dmaxs[0] + dmins[0] ) / 2 | ||
663 : | tmpvec[1] = dmaxs[1] + 20 | ||
664 : | tmpvec[2] = dmaxs[2] + 20 | ||
665 : | trace_line( ent, dr_tc, tmpvec, tmpvec2 ) | ||
666 : | if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] ) | ||
667 : | door_tp_pos[i] = tmpvec | ||
668 : | else | ||
669 : | { | ||
670 : | tmpvec[1] = dmins[1] - 20 | ||
671 : | trace_line( ent, dr_tc, tmpvec, tmpvec2 ) | ||
672 : | if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] ) | ||
673 : | door_tp_pos[i] = tmpvec | ||
674 : | else | ||
675 : | { | ||
676 : | tmpvec[0] = dmaxs[0] + 20 | ||
677 : | tmpvec[1] = ( dmaxs[1] + dmins[1] ) / 2 | ||
678 : | trace_line( ent, dr_tc, tmpvec, tmpvec2 ) | ||
679 : | if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] ) | ||
680 : | door_tp_pos[i] = tmpvec | ||
681 : | else | ||
682 : | { | ||
683 : | tmpvec[0] = dmins[0] - 20 | ||
684 : | door_tp_pos[i] = tmpvec | ||
685 : | } | ||
686 : | } | ||
687 : | } | ||
688 : | } | ||
689 : | } | ||
690 : | } | ||
691 : | |||
692 : | //Store ent id's for start/fin buttons, some maps change target value after timer starts | ||
693 : | ent = find_ent_by_class( -1, "func_button" ) | ||
694 : | while( ent > 0 ) | ||
695 : | { | ||
696 : | entity_get_string( ent, EV_SZ_target, tmpstr, 32 ) | ||
697 : | |||
698 : | if( equal( tmpstr, "counter_start" ) || equal( tmpstr, "clockstartbutton" ) | ||
699 : | || equal( tmpstr, "firsttimerelay" ) || equal( tmpstr, "gogogo" ) ) | ||
700 : | { | ||
701 : | ST_BTNS[ST_BTN_CNT] = ent | ||
702 : | ST_BTN_CNT++ | ||
703 : | } | ||
704 : | else if( equal( tmpstr, "counter_off" ) || equal( tmpstr, "clockstopbutton" ) | ||
705 : | || equal( tmpstr, "clockstop" ) || equal( tmpstr, "stop_counter" ) ) | ||
706 : | { | ||
707 : | FN_BTNS[FN_BTN_CNT] = ent | ||
708 : | FN_BTN_CNT++ | ||
709 : | } | ||
710 : | |||
711 : | ent = find_ent_by_class( ent, "func_button" ) | ||
712 : | } | ||
713 : | |||
714 : | if( ST_BTN_CNT /*|| get_pcvar_num( p_climb )*/ ) | ||
715 : | { | ||
716 : | get_brush_entity_origin( ST_BTNS[0], start_tp_orig ) | ||
717 : | |||
718 : | set_pcvar_num( p_teambalance, 0 ) | ||
719 : | set_pcvar_num( p_limitteams, 0 ) | ||
720 : | |||
721 : | set_cvar_num( "sv_restartround", 1 )//reset timer built into map | ||
722 : | set_cvar_num( "sv_gravity", 800 ) | ||
723 : | set_pcvar_num( p_climb, 1 ) | ||
724 : | |||
725 : | remove_entity_name("player_weaponstrip") | ||
726 : | remove_entity_name("armoury_entity") | ||
727 : | remove_entity_name("info_player_deathmatch") | ||
728 : | remove_entity_name("game_player_equip")//Remove map built in spawn weapons | ||
729 : | |||
730 : | //Remove func_breakables with < 9999 hp | ||
731 : | ent = find_ent_by_class( -1, "func_breakable" ) | ||
732 : | while( ent > 0 ) | ||
733 : | { | ||
734 : | tmpflt = entity_get_float( ent, EV_FL_health ) | ||
735 : | if( tmpflt < 9999 ) remove_entity( ent ) | ||
736 : | ent = find_ent_by_class( ent, "func_breakable" ) | ||
737 : | } | ||
738 : | |||
739 : | //Remove neg dmg func_door that aren't targeted by a button | ||
740 : | ent=find_ent_by_class(-1,"func_door") | ||
741 : | while(ent>0) | ||
742 : | { | ||
743 : | tmpflt=entity_get_float(ent,EV_FL_dmg) | ||
744 : | if(tmpflt<0) | ||
745 : | { | ||
746 : | hp=floatround(tmpflt)//record hp for auto heal | ||
747 : | entity_get_string( ent, EV_SZ_targetname, tmpstr, 32 ) | ||
748 : | if(strlen(tmpstr)) | ||
749 : | { | ||
750 : | ent2=find_ent_by_target(-1,tmpstr) | ||
751 : | //entity_get_string(ent2,EV_SZ_classname,tmpstr,32) | ||
752 : | //if(!equal("func_button",tmpstr)){ | ||
753 : | remove_entity(ent2) | ||
754 : | } | ||
755 : | remove_entity(ent) | ||
756 : | //} | ||
757 : | //if(!strlen(tmpstr))remove_entity(ent) | ||
758 : | //ent=-1 | ||
759 : | } | ||
760 : | ent=find_ent_by_class(ent,"func_door") | ||
761 : | } | ||
762 : | |||
763 : | if( hp < 0 ) hp = 511 | ||
764 : | //Disable climb auto heal if there is a neg dmg trigger hurt | ||
765 : | else | ||
766 : | { | ||
767 : | ent=find_ent_by_class(-1,"trigger_hurt") | ||
768 : | while(ent>0){ | ||
769 : | tmpflt=entity_get_float(ent,EV_FL_dmg) | ||
770 : | if(tmpflt<0){ | ||
771 : | hp=0 | ||
772 : | break | ||
773 : | } | ||
774 : | ent=find_ent_by_class(ent,"trigger_hurt") | ||
775 : | } | ||
776 : | } | ||
777 : | |||
778 : | //If Cvar set, set func_water ents to no draw, helps many peoples FPS | ||
779 : | if( get_pcvar_num( p_water_nodraw ) ) | ||
780 : | { | ||
781 : | ent = find_ent_by_class( -1, "func_water" ) | ||
782 : | while( ent > 0 ) | ||
783 : | { | ||
784 : | set_entity_visibility( ent, 0 ) | ||
785 : | ent=find_ent_by_class( ent, "func_water" ) | ||
786 : | } | ||
787 : | } | ||
788 : | |||
789 : | //Remove map built in start button sounds | ||
790 : | ent = find_ent_by_class( -1, "ambient_generic" ) | ||
791 : | while( ent > 0 ) | ||
792 : | { | ||
793 : | entity_get_string( ent, EV_SZ_targetname, tmpstr, 32 ) | ||
794 : | if( equal( tmpstr, "counter_start" ) || equal( tmpstr, "clockstartbutton" ) | ||
795 : | || equal( tmpstr, "firsttimerelay" ) || equal( tmpstr, "gogogo" ) ) | ||
796 : | remove_entity( ent ) | ||
797 : | ent = find_ent_by_class( ent, "ambient_generic" ) | ||
798 : | } | ||
799 : | |||
800 : | //Count original map spawns and remove extra dyn created spawns | ||
801 : | new map_spawns[32][2], map_spawns_count, Float:orig[3] | ||
802 : | ent = find_ent_by_class( -1, "info_player_start" ) | ||
803 : | while( ent > 0 && map_spawns_count < 32 ) | ||
804 : | { | ||
805 : | if( entity_get_int( ent, EV_INT_iuser1 ) != 1 ) | ||
806 : | { | ||
807 : | entity_get_vector( ent, EV_VEC_origin, orig ) | ||
808 : | map_spawns[map_spawns_count][0] = floatround( vector_distance( orig, start_tp_orig ) ) | ||
809 : | map_spawns[map_spawns_count][1] = ent | ||
810 : | map_spawns_count++ | ||
811 : | while( dyn_spawn_count >= 0 ) | ||
812 : | { | ||
813 : | entity_get_string( dyn_spawn_ids[dyn_spawn_count], EV_SZ_classname, tmpstr, 32 ) | ||
814 : | if( equal( tmpstr, "info_player_start" ) && | ||
815 : | entity_get_int( dyn_spawn_ids[dyn_spawn_count], EV_INT_iuser1 ) == 1 ) | ||
816 : | { | ||
817 : | remove_entity( dyn_spawn_ids[dyn_spawn_count] ) | ||
818 : | dyn_spawn_count-- | ||
819 : | break | ||
820 : | } | ||
821 : | else dyn_spawn_count-- | ||
822 : | } | ||
823 : | } | ||
824 : | ent = find_ent_by_class( ent, "info_player_start" ) | ||
825 : | } | ||
826 : | |||
827 : | //Save origin of spawn closest to start | ||
828 : | SortStrings( map_spawns, map_spawns_count ) | ||
829 : | entity_get_vector( map_spawns[0][1], EV_VEC_origin, spawn_tp_orig ) | ||
830 : | |||
831 : | new Float:tmpvec[3], Float:tmpvec2[3] | ||
832 : | tmpvec = start_tp_orig | ||
833 : | |||
834 : | start_tp_orig[2] += 24 | ||
835 : | |||
836 : | start_tp_orig[0] += 40 | ||
837 : | trace_line( ST_BTNS[0], tmpvec, start_tp_orig, tmpvec2 ) | ||
838 : | if( !trace_hull( start_tp_orig, HULL_HUMAN ) && tmpvec2[2] == start_tp_orig[2] ) | ||
839 : | return PLUGIN_CONTINUE | ||
840 : | |||
841 : | start_tp_orig[0] -= 80 | ||
842 : | trace_line( ST_BTNS[0], tmpvec, start_tp_orig, tmpvec2 ) | ||
843 : | if( !trace_hull( start_tp_orig, HULL_HUMAN ) && tmpvec2[2] == start_tp_orig[2] ) | ||
844 : | return PLUGIN_CONTINUE | ||
845 : | |||
846 : | start_tp_orig[0] += 40 | ||
847 : | start_tp_orig[1] += 40 | ||
848 : | trace_line( ST_BTNS[0], tmpvec, start_tp_orig, tmpvec2 ) | ||
849 : | if( !trace_hull( start_tp_orig, HULL_HUMAN ) && tmpvec2[2] == start_tp_orig[2] ) | ||
850 : | return PLUGIN_CONTINUE | ||
851 : | |||
852 : | start_tp_orig[1] -= 80 | ||
853 : | trace_line( ST_BTNS[0], tmpvec, start_tp_orig, tmpvec2 ) | ||
854 : | if( !trace_hull( start_tp_orig, HULL_HUMAN ) && tmpvec2[2] == start_tp_orig[2] ) | ||
855 : | return PLUGIN_CONTINUE | ||
856 : | |||
857 : | start_tp_orig = spawn_tp_orig | ||
858 : | } | ||
859 : | else | ||
860 : | {//if not kz map remove dyn created spawns | ||
861 : | while( dyn_spawn_count >= 0 ) | ||
862 : | { | ||
863 : | ent = dyn_spawn_ids[dyn_spawn_count] | ||
864 : | entity_get_string( ent, EV_SZ_classname, tmpstr, 32 ) | ||
865 : | //entity_get_string(dyn_spawn_ids[i],EV_SZ_classname,tmpstr,32) | ||
866 : | if( equal( tmpstr, "info_player_start" ) && entity_get_int( ent, EV_INT_iuser1 ) == 1 ) | ||
867 : | remove_entity(ent) | ||
868 : | dyn_spawn_count-- | ||
869 : | } | ||
870 : | } | ||
871 : | return PLUGIN_CONTINUE | ||
872 : | } | ||
873 : | |||
874 : | public plugin_precache( ) | ||
875 : | { | ||
876 : | beam_sprite = precache_model( "sprites/laserbeam.spr" ) | ||
877 : | return PLUGIN_CONTINUE | ||
878 : | } | ||
879 : | |||
880 : | stock Float:float_clamp( Float:curval, Float:minval, Float:maxval ) | ||
881 : | { | ||
882 : | if( curval < minval )return minval | ||
883 : | if( curval > maxval )return maxval | ||
884 : | return curval | ||
885 : | } | ||
886 : | |||
887 : | //////////////////////////////////////////////////////////////////////////////// | ||
888 : | // End: Init forwards | ||
889 : | //////////////////////////////////////////////////////////////////////////////// | ||
890 : | public client_putinserver( id ) | ||
891 : | { | ||
892 : | if( get_pcvar_num( p_climb ) && !is_user_bot( id ) && !is_user_hltv( id ) ) | ||
893 : | { | ||
894 : | ian | 19 | timer[id][TMR_DBUSER] = 0 |
895 : | ian | 1 | |
896 : | //search steamid to position reference for match | ||
897 : | new searchid[32] | ||
898 : | get_user_authid( id, searchid, 31 ) | ||
899 : | for(new i = 0; i < 32; i++ ) | ||
900 : | if( equal( searchid, steamid[i] ) ) | ||
901 : | {//load origins & timer array if match found | ||
902 : | ian | 19 | origins[id] = originssave[i] |
903 : | timer[id] = timersave[i] | ||
904 : | ian | 1 | return PLUGIN_CONTINUE |
905 : | } | ||
906 : | |||
907 : | ian | 19 | timer[id][TMR_CFLAGS] += CF_STOP |
908 : | ian | 1 | |
909 : | new ida[1] | ||
910 : | ida[0]=id | ||
911 : | |||
912 : | ian | 19 | if( CLIMB_SAVE && timer[id][TMR_DBUSER] < 1 ) |
913 : | ian | 1 | set_task( 5.0, "auto_login", 0, ida, 1 ) |
914 : | } | ||
915 : | return PLUGIN_CONTINUE | ||
916 : | } | ||
917 : | |||
918 : | public client_disconnect( id ) | ||
919 : | { | ||
920 : | if( get_pcvar_num(p_climb) ) | ||
921 : | { | ||
922 : | savepos++ | ||
923 : | if( savepos == 31 ) savepos = 0 | ||
924 : | |||
925 : | new saveid[32] | ||
926 : | get_user_authid( id, saveid, 32 ) | ||
927 : | |||
928 : | //erase previous save if exists | ||
929 : | for( new i=0; i<32; i++ ) | ||
930 : | ian | 22 | if( equal( saveid, steamid[i] ) ) steamid[i] = NULLSTR |
931 : | ian | 1 | |
932 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_START ) change_status( id, CF_PAUSE ) //Pause if running |
933 : | ian | 1 | steamid[savepos] = saveid //save steamid to position reference |
934 : | ian | 19 | originssave[savepos] = origins[id] //save origins |
935 : | timersave[savepos] = timer[id] //save timer array | ||
936 : | ian | 1 | |
937 : | //clear data for new client in that slot | ||
938 : | ian | 19 | for( new i = 0; i < 48; i++ ) origins[id][i] = 0.0 |
939 : | for( new i = 0; i < 14; i++ ) timer[id][i] = 0 | ||
940 : | ian | 1 | hooked[id] = 0 |
941 : | sortcssb( ) //Update frags to reorder scoreboard | ||
942 : | } | ||
943 : | return PLUGIN_CONTINUE | ||
944 : | } | ||
945 : | //////////////////////////////////////////////////////////////////////////////// | ||
946 : | // Start: CP/GC functions | ||
947 : | //////////////////////////////////////////////////////////////////////////////// | ||
948 : | public set_cpgc_timeout( id ) | ||
949 : | { | ||
950 : | //Set timeout flag and set_task to clear it | ||
951 : | new ida[1] | ||
952 : | ida[0] = id | ||
953 : | ian | 19 | time_stamps[id][TS_CPGC] = 1 |
954 : | ian | 1 | set_task( CPGC_TIMEOUT, "clear_cpgc_timeout", _, ida, 1 ) |
955 : | } | ||
956 : | |||
957 : | public clear_cpgc_timeout( ida[1] ) | ||
958 : | ian | 19 | return time_stamps[ida[0]][TS_CPGC]=0 |
959 : | ian | 1 | |
960 : | //Save a checkpoint | ||
961 : | public check( id ) | ||
962 : | { | ||
963 : | if( get_pcvar_num( p_climb ) && isalive( id ) && notpaused( id ) ) | ||
964 : | { | ||
965 : | new cpprice = get_pcvar_num( p_cpprice ) | ||
966 : | if( cpprice > 0 ) | ||
967 : | { | ||
968 : | new cash = cs_get_user_money(id) | ||
969 : | if( cpprice > cash ) | ||
970 : | { | ||
971 : | clmsg(id,"You don't have enough cash for more checkpoints.") | ||
972 : | client_print(id,print_chat,"You don't have enough cash for more checkpoints.") | ||
973 : | return PLUGIN_HANDLED | ||
974 : | } | ||
975 : | cs_set_user_money( id, cash - cpprice ) | ||
976 : | } | ||
977 : | if( !hooked[id] )//If they're not hooked... | ||
978 : | { | ||
979 : | new Float:vel[3] | ||
980 : | entity_get_vector( id, EV_VEC_velocity, vel ) | ||
981 : | if( vel[2] >= 0 )//and they're not falling... | ||
982 : | { | ||
983 : | new Float:coords[3] | ||
984 : | entity_get_vector( id, EV_VEC_origin, coords ) | ||
985 : | if( coords[0] || coords[1] || coords[2] )//and they're not at world origin, then save checkpoint | ||
986 : | { | ||
987 : | ian | 19 | if( timer[id][TMR_CPPOS] > 0 ) timer[id][TMR_CPPOS]-- |
988 : | new cppos = timer[id][TMR_CPPOS] * 4 | ||
989 : | ian | 1 | |
990 : | //If cp position is 0 then bump all cps back before saving. | ||
991 : | ian | 19 | if( !cppos ) for(new i=39; i>3 ;i-- ) origins[id][i] = origins[id][i-4] |
992 : | ian | 1 | |
993 : | ian | 19 | for( new i=0; i<3; i++ ) origins[id][cppos + i] = coords[i] |
994 : | origins[id][3]=entity_get_float(id, EV_FL_gravity) | ||
995 : | ian | 1 | |
996 : | new msg[100]="Checkpoint saved." | ||
997 : | ian | 19 | if(timer[id][TMR_CFLAGS]&CF_START){ |
998 : | timer[id][TMR_CNTCPS]++ | ||
999 : | formatex(msg,99,"Checkpoint saved. (%d CPS/ %d GCS/ %d Boosts)",timer[id][TMR_CNTCPS],timer[id][TMR_CNTGCS],timer[id][TMR_CNTBST]) | ||
1000 : | ian | 1 | } |
1001 : | clmsg(id,msg) | ||
1002 : | |||
1003 : | set_cpgc_timeout( id ) | ||
1004 : | } | ||
1005 : | else clmsg(id,"Can not save checkpoint at current location.") | ||
1006 : | } | ||
1007 : | else clmsg(id,"You can't make checkpoints while falling.") | ||
1008 : | } | ||
1009 : | else clmsg(id,"You can't make checkpoints while using hook.") | ||
1010 : | } | ||
1011 : | return PLUGIN_HANDLED | ||
1012 : | } | ||
1013 : | |||
1014 : | //Go to most recent checkpoint | ||
1015 : | public gocheck( id ) | ||
1016 : | { | ||
1017 : | ian | 19 | if( get_pcvar_num( p_climb ) && isalive( id ) && notpaused( id ) && !time_stamps[id][TS_CPGC] ) |
1018 : | ian | 1 | { |
1019 : | ian | 19 | if( origins[id][0] || origins[id][1] || origins[id][2] ) |
1020 : | ian | 1 | { |
1021 : | new Float:coords[3] | ||
1022 : | |||
1023 : | //Store ungocheck data | ||
1024 : | entity_get_vector( id, EV_VEC_origin, coords ) | ||
1025 : | ian | 19 | for( new i=0; i<3; i++ ) origins[id][ORIG_UNGC + i] = coords[i] |
1026 : | origins[id][ORIG_UNGC + 3] = entity_get_float( id, EV_FL_gravity ) | ||
1027 : | ian | 1 | |
1028 : | //Do gocheck | ||
1029 : | ian | 19 | new cppos = timer[id][TMR_CPPOS] * 4 |
1030 : | for( new i=0; i<3; i++ ) coords[i] = origins[id][cppos + i] | ||
1031 : | entity_set_float( id, EV_FL_gravity, origins[id][3] ) | ||
1032 : | ian | 1 | teleport( id, coords ) |
1033 : | |||
1034 : | new msg[100]="Checkpoint restored." | ||
1035 : | ian | 19 | if(timer[id][TMR_CFLAGS]&CF_START){ |
1036 : | timer[id][TMR_CNTGCS]++ | ||
1037 : | formatex(msg,99,"Checkpoint restored. (%d CPS/ %d GCS/ %d Boosts)",timer[id][TMR_CNTCPS],timer[id][TMR_CNTGCS],timer[id][TMR_CNTBST]) | ||
1038 : | ian | 1 | } |
1039 : | clmsg(id,msg) | ||
1040 : | |||
1041 : | set_cpgc_timeout( id ) | ||
1042 : | } | ||
1043 : | else{ | ||
1044 : | clmsg(id,"You must make a checkpoint first.") | ||
1045 : | return 0 | ||
1046 : | } | ||
1047 : | } | ||
1048 : | return 1 | ||
1049 : | } | ||
1050 : | |||
1051 : | //Undo a gocheck | ||
1052 : | public ungocheck( id ) | ||
1053 : | { | ||
1054 : | ian | 19 | if( get_pcvar_num(p_climb) && isalive(id) && notpaused(id) && !time_stamps[id][TS_CPGC] ) |
1055 : | ian | 1 | { |
1056 : | ian | 19 | if( origins[id][ORIG_UNGC] || origins[id][ORIG_UNGC + 1] || origins[id][ORIG_UNGC + 2]) |
1057 : | ian | 1 | { |
1058 : | new Float:coords[3] | ||
1059 : | ian | 19 | for( new i=0; i<3; i++ )coords[i] = origins[id][ORIG_UNGC + i] |
1060 : | ian | 1 | teleport( id, coords ) |
1061 : | ian | 19 | entity_set_float( id, EV_FL_gravity, origins[id][ORIG_UNGC + 3] ) |
1062 : | if( timer[id][TMR_CFLAGS] & CF_START ) timer[id][TMR_CNTGCS]++ | ||
1063 : | ian | 1 | clmsg( id, "You have been ungochecked." ) |
1064 : | |||
1065 : | set_cpgc_timeout( id ) | ||
1066 : | } | ||
1067 : | else clmsg(id,"Cannot ungocheck.") | ||
1068 : | } | ||
1069 : | } | ||
1070 : | |||
1071 : | //Cycle back through CPs | ||
1072 : | public cp_back( id ) | ||
1073 : | { | ||
1074 : | ian | 19 | if( get_pcvar_num( p_climb ) && isalive( id ) && notpaused( id ) && !time_stamps[id][TS_CPGC] ) |
1075 : | ian | 1 | { |
1076 : | ian | 19 | if( timer[id][TMR_CPPOS] < 9 ) timer[id][TMR_CPPOS]++ |
1077 : | new cppos = timer[id][TMR_CPPOS] * 4 | ||
1078 : | if( origins[id][cppos] || origins[id][cppos + 1] || origins[id][cppos + 2] ) | ||
1079 : | ian | 1 | { |
1080 : | new Float:coords[3] | ||
1081 : | ian | 19 | //for( new i=0; i<36; i++ ) origins[id][i] = origins[id][i+4] |
1082 : | for( new i=0; i<3; i++ ) coords[i] = origins[id][cppos + i] | ||
1083 : | entity_set_float( id, EV_FL_gravity, origins[id][cppos + ORIG_GRAV] ) | ||
1084 : | ian | 1 | teleport( id, coords ) |
1085 : | |||
1086 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_START ) timer[id][TMR_CNTGCS]++ |
1087 : | ian | 1 | |
1088 : | /*new msg[100]="Previous checkpoint restored." | ||
1089 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_START ) |
1090 : | ian | 1 | { |
1091 : | ian | 19 | timer[id][TMR_CNTCPS]-- |
1092 : | ian | 1 | formatex( msg, 99, "Previous checkpoint restored. (%d CPS/ %d GCS/ %d Boosts)",\ |
1093 : | ian | 19 | timer[id][TMR_CNTCPS], timer[id][TMR_CNTGCS], timer[id][TMR_CNTBST] ) |
1094 : | ian | 1 | } |
1095 : | clmsg( id, msg )*/ | ||
1096 : | |||
1097 : | /*new cpprice = get_pcvar_num( p_cpprice ) | ||
1098 : | if( cpprice > 0 ) | ||
1099 : | { | ||
1100 : | new cash = cs_get_user_money( id ) | ||
1101 : | cs_set_user_money( id, cash + cpprice ) | ||
1102 : | }*/ | ||
1103 : | |||
1104 : | set_cpgc_timeout( id ) | ||
1105 : | } | ||
1106 : | else | ||
1107 : | { | ||
1108 : | clmsg(id,"You have no previous checkpoints remaining.") | ||
1109 : | ian | 19 | timer[id][TMR_CPPOS]-- |
1110 : | ian | 1 | } |
1111 : | } | ||
1112 : | return PLUGIN_HANDLED | ||
1113 : | } | ||
1114 : | |||
1115 : | //Cycle forward through CPs | ||
1116 : | public cp_forward( id ) | ||
1117 : | { | ||
1118 : | ian | 19 | if( get_pcvar_num( p_climb ) && isalive( id ) && notpaused( id ) && !time_stamps[id][TS_CPGC] && timer[id][TMR_CPPOS] > 0 ) |
1119 : | ian | 1 | { |
1120 : | ian | 19 | timer[id][TMR_CPPOS]-- |
1121 : | new cppos = timer[id][TMR_CPPOS] * 4 | ||
1122 : | ian | 1 | |
1123 : | new Float:coords[3] | ||
1124 : | ian | 19 | for( new i=0; i<3; i++ ) coords[i] = origins[id][cppos + i] |
1125 : | entity_set_float( id, EV_FL_gravity, origins[id][cppos + ORIG_GRAV] ) | ||
1126 : | ian | 1 | teleport( id, coords ) |
1127 : | |||
1128 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_START ) timer[id][TMR_CNTGCS]++ |
1129 : | ian | 1 | |
1130 : | set_cpgc_timeout( id ) | ||
1131 : | } | ||
1132 : | return PLUGIN_HANDLED | ||
1133 : | } | ||
1134 : | //////////////////////////////////////////////////////////////////////////////// | ||
1135 : | // End: CP/GC functions | ||
1136 : | //////////////////////////////////////////////////////////////////////////////// | ||
1137 : | public change_status( id, newstat ) | ||
1138 : | { | ||
1139 : | ian | 19 | new cflags_old = timer[id][TMR_CFLAGS] |
1140 : | ian | 1 | new cflags_new = cflags_old & ~CF_STATUSFLAGS |
1141 : | |||
1142 : | if( newstat & CF_PAUSE ) | ||
1143 : | { | ||
1144 : | if( cflags_old & CF_PAUSE ) //unpause | ||
1145 : | { | ||
1146 : | cflags_new += CF_START | ||
1147 : | ian | 19 | timer[id][TMR_STARTD] = get_systime() - timer[id][TMR_STARTD] |
1148 : | ian | 1 | set_entity_flags( id, FL_FROZEN, 0 ) |
1149 : | unsolid( id ) | ||
1150 : | ian | 19 | entity_set_float( id, EV_FL_gravity, origins[id][ORIG_PAUS + ORIG_GRAV] ) |
1151 : | ian | 1 | clmsg( id, "UNPAUSED" ) |
1152 : | sfexec( id, 2 ) | ||
1153 : | } | ||
1154 : | else if( cflags_old & CF_START ) //pause | ||
1155 : | { | ||
1156 : | ian | 19 | timer[id][TMR_STARTD] = get_systime() - timer[id][TMR_STARTD] |
1157 : | ian | 1 | cl_pause( id ) |
1158 : | cflags_new += CF_PAUSE | ||
1159 : | } | ||
1160 : | else | ||
1161 : | { | ||
1162 : | clmsg( id, "You must start the timer before you can pause." ) | ||
1163 : | cflags_new = cflags_old | ||
1164 : | } | ||
1165 : | } | ||
1166 : | else cflags_new += newstat | ||
1167 : | ian | 19 | timer[id][TMR_CFLAGS] = cflags_new |
1168 : | ian | 1 | return PLUGIN_HANDLED |
1169 : | } | ||
1170 : | |||
1171 : | public cl_pause( id ) | ||
1172 : | { | ||
1173 : | if( is_climber_alive( id ) ) | ||
1174 : | { | ||
1175 : | unsolid( id ) | ||
1176 : | set_rendering( id, kRenderFxGlowShell, 0, 0, 255, kRenderTransColor, 1 ) | ||
1177 : | set_entity_flags( id, FL_FROZEN, 1 ) | ||
1178 : | clmsg( id, "PAUSED - say '/unpause' to resume." ) | ||
1179 : | } | ||
1180 : | return PLUGIN_HANDLED | ||
1181 : | } | ||
1182 : | |||
1183 : | public stop( id ) | ||
1184 : | { | ||
1185 : | ian | 19 | if( get_pcvar_num( p_climb ) && timer[id][TMR_CFLAGS] & CF_START ) |
1186 : | ian | 1 | { |
1187 : | change_status( id, CF_STOP ) | ||
1188 : | heal(id) | ||
1189 : | //Erase start/finish time stamps, prevents crazy number on scoreboard | ||
1190 : | ian | 19 | timer[id][TMR_STARTD]=0 |
1191 : | timer[id][TMR_FINISH]=0 | ||
1192 : | ian | 1 | |
1193 : | sfexec(id,4) //Execute commands from start/finish config | ||
1194 : | } | ||
1195 : | return PLUGIN_HANDLED | ||
1196 : | } | ||
1197 : | |||
1198 : | //Start borrowed code : from KCE's attack blocking tutorial (http://forums.alliedmods.net/showthread.php?t=41265) | ||
1199 : | public PostUpdateClientData( id, sendweapons, cd_handle ) | ||
1200 : | { | ||
1201 : | if( get_pcvar_num( p_climb ) && is_climber_alive( id ) ) | ||
1202 : | { | ||
1203 : | new wpn, clip, ammo | ||
1204 : | wpn = get_user_weapon( id, clip, ammo ) | ||
1205 : | if( wpn == CSW_KNIFE ) | ||
1206 : | { | ||
1207 : | ian | 19 | new remain = check_timeout( 0, time_stamps[id][TS_KNIFE], KNIFE_TIMEOUT, _, 1 ) |
1208 : | ian | 1 | if( remain ) |
1209 : | { | ||
1210 : | set_cd(cd_handle, CD_flNextAttack, halflife_time() + remain ) | ||
1211 : | return FMRES_HANDLED | ||
1212 : | } | ||
1213 : | } | ||
1214 : | } | ||
1215 : | return FMRES_IGNORED | ||
1216 : | } | ||
1217 : | //End borrowed code | ||
1218 : | |||
1219 : | public CurWeapon( msg_id, msg_dest, id ) | ||
1220 : | { | ||
1221 : | new wpn = get_msg_arg_int( 2 ) | ||
1222 : | if( !get_pcvar_num( p_climb ) || !( 0 < wpn <= 30 ) ) | ||
1223 : | return PLUGIN_CONTINUE | ||
1224 : | |||
1225 : | ian | 19 | static client_oldwpn[33] |
1226 : | if( wpn != client_oldwpn[id] ) | ||
1227 : | ian | 1 | rank_mod_update( id ) |
1228 : | |||
1229 : | ian | 19 | client_oldwpn[id] = wpn |
1230 : | ian | 1 | |
1231 : | ian | 22 | if( wpn == CSW_C4 || |
1232 : | wpn == CSW_HEGRENADE || | ||
1233 : | wpn == CSW_FLASHBANG || | ||
1234 : | wpn == CSW_SMOKEGRENADE || | ||
1235 : | wpn == CSW_KNIFE | ||
1236 : | ) return PLUGIN_CONTINUE | ||
1237 : | |||
1238 : | ian | 1 | //If it's a gun, update pack and clip ammo & silencer |
1239 : | ian | 22 | new wpn_id = get_user_weapon( id ) |
1240 : | if( !wpn_id ) return PLUGIN_CONTINUE | ||
1241 : | |||
1242 : | new clip = get_msg_arg_int( 3 ) | ||
1243 : | new maxammo = 2 | ||
1244 : | |||
1245 : | //Force silencer w/o animation | ||
1246 : | if( wpn == CSW_USP || wpn == CSW_M4A1 || wpn == CSW_TMP ) | ||
1247 : | ian | 1 | { |
1248 : | ian | 22 | if( wpn != CSW_TMP ) cs_set_weapon_silen( wpn_id, 1, 0 ) |
1249 : | maxammo = 10 | ||
1250 : | ian | 1 | |
1251 : | ian | 22 | //Unlimited ammo for VIPs |
1252 : | if( get_user_flags(id) & VIP ) | ||
1253 : | ian | 1 | { |
1254 : | ian | 22 | cs_set_weapon_ammo( wpn_id, 12 ) |
1255 : | if( clip != 12 )return PLUGIN_HANDLED | ||
1256 : | set_msg_arg_int( 3, ARG_BYTE, 12 ) | ||
1257 : | return PLUGIN_CONTINUE | ||
1258 : | ian | 1 | } |
1259 : | } | ||
1260 : | |||
1261 : | ian | 22 | //Set clip and backpack ammo |
1262 : | cs_set_user_bpammo( id, wpn, maxammo - clip ) | ||
1263 : | if( clip > maxammo ) | ||
1264 : | { | ||
1265 : | set_msg_arg_int( 3, ARG_BYTE, maxammo ) | ||
1266 : | cs_set_weapon_ammo( wpn_id, maxammo ) | ||
1267 : | } | ||
1268 : | |||
1269 : | ian | 1 | return PLUGIN_CONTINUE |
1270 : | } | ||
1271 : | |||
1272 : | public rank_mod_update( id ) | ||
1273 : | ian | 22 | { |
1274 : | ian | 1 | new rank, maxspeed = pev( id, pev_maxspeed ) |
1275 : | switch( maxspeed ) | ||
1276 : | { | ||
1277 : | case 210: | ||
1278 : | rank = 0 | ||
1279 : | case 220: | ||
1280 : | rank = 1 | ||
1281 : | case 230: | ||
1282 : | rank = 2 | ||
1283 : | case 235: | ||
1284 : | rank = 3 | ||
1285 : | case 240: | ||
1286 : | rank = 4 | ||
1287 : | case 245: | ||
1288 : | rank = 5 | ||
1289 : | case 250: | ||
1290 : | rank = 6 | ||
1291 : | case 260: | ||
1292 : | rank = 7 | ||
1293 : | } | ||
1294 : | |||
1295 : | ian | 19 | if( rank > timer[id][TMR_CNTWPN] ) |
1296 : | timer[id][TMR_CNTWPN] = rank | ||
1297 : | ian | 1 | |
1298 : | new msg[100] | ||
1299 : | format( msg, 99, "Weapon Max Speed: %d^nRank Modifier: %d", maxspeed, rank ) | ||
1300 : | clmsg( id, msg ) | ||
1301 : | } | ||
1302 : | |||
1303 : | public get_weapon_name( wpn_rank, ret_name[], len ) | ||
1304 : | { | ||
1305 : | new name[21] | ||
1306 : | switch( wpn_rank ) | ||
1307 : | { | ||
1308 : | case 0: | ||
1309 : | name = "AWP" | ||
1310 : | case 1: | ||
1311 : | name = "Para" | ||
1312 : | case 2: | ||
1313 : | name = "M4A1" | ||
1314 : | case 3: | ||
1315 : | name = "SG552" | ||
1316 : | case 4: | ||
1317 : | name = "Famas" | ||
1318 : | case 5: | ||
1319 : | name = "P90" | ||
1320 : | case 6: | ||
1321 : | name = "USP" | ||
1322 : | case 7: | ||
1323 : | name = "Scout" | ||
1324 : | } | ||
1325 : | formatex( ret_name, len, name ) | ||
1326 : | } | ||
1327 : | |||
1328 : | public DeathMsg( ) | ||
1329 : | {//Respawn client when they die unless switching to spec | ||
1330 : | if( get_pcvar_num( p_climb ) ) | ||
1331 : | { | ||
1332 : | new id = read_data(2) | ||
1333 : | set_entity_flags( id, FL_FROZEN, 0 )//Unfreeze in case of switch to spectator. | ||
1334 : | new ida[1] | ||
1335 : | ida[0]=id | ||
1336 : | if(task_exists(100+id))remove_task(100+id) | ||
1337 : | if(isct(id)){ | ||
1338 : | set_task(0.2,"respawn_task",100+id,ida,1) | ||
1339 : | } | ||
1340 : | } | ||
1341 : | return PLUGIN_HANDLED | ||
1342 : | } | ||
1343 : | |||
1344 : | public respawn_task(ida[]){//used by death_msg function | ||
1345 : | new id=ida[0] | ||
1346 : | if( !get_user_team( id ) || is_climber_alive( id ) || !isct( id ) ) | ||
1347 : | return PLUGIN_HANDLED | ||
1348 : | //cs_user_spawn(id) | ||
1349 : | climb_user_spawn( id, 0 ) | ||
1350 : | return PLUGIN_HANDLED | ||
1351 : | } | ||
1352 : | |||
1353 : | public frespawn( id ) | ||
1354 : | { | ||
1355 : | stop(id) | ||
1356 : | if( is_climber_alive( id ) ) teleport( id, spawn_tp_orig ) | ||
1357 : | ian | 19 | else if( !check_timeout( id, time_stamps[id][TS_SPAWN], SPAWN_TIMEOUT ) ) |
1358 : | ian | 1 | { |
1359 : | //if( get_user_team ( id ) == 3 ) cs_set_user_team( id, 2 ) | ||
1360 : | //cs_user_spawn( id ) | ||
1361 : | climb_user_spawn( id ) | ||
1362 : | } | ||
1363 : | return PLUGIN_HANDLED | ||
1364 : | } | ||
1365 : | |||
1366 : | public tp_start_btn( id ) | ||
1367 : | { | ||
1368 : | if ( !is_climber_alive( id ) ) | ||
1369 : | { | ||
1370 : | //if( get_user_team ( id ) == 3 ) cs_set_user_team( id, 2 ) | ||
1371 : | //cs_user_spawn( id ) | ||
1372 : | climb_user_spawn( id ) | ||
1373 : | } | ||
1374 : | if( teleport( id, start_tp_orig ) ) return | ||
1375 : | clmsg( id, "This map doesn't have a start button." ) | ||
1376 : | } | ||
1377 : | |||
1378 : | stock climb_user_spawn( id, give_wpns = 1 ) | ||
1379 : | { | ||
1380 : | cs_user_spawn( id ) | ||
1381 : | |||
1382 : | set_pev( id, pev_movetype, MOVETYPE_WALK ) | ||
1383 : | set_pev( id, pev_solid, SOLID_BBOX ) | ||
1384 : | set_pev( id, pev_effects, 0 ) | ||
1385 : | set_pev( id, pev_deadflag, DEAD_NO ) | ||
1386 : | set_pev( id, pev_takedamage, DAMAGE_AIM ) | ||
1387 : | set_pev( id, pev_health, 100 ) | ||
1388 : | |||
1389 : | cs_set_user_team( id, 2 ) | ||
1390 : | |||
1391 : | if( give_wpns ) | ||
1392 : | { | ||
1393 : | give_item( id, "weapon_knife" ) | ||
1394 : | give_item( id, "weapon_usp" ) | ||
1395 : | } | ||
1396 : | } | ||
1397 : | |||
1398 : | public ResetHUD( id ) | ||
1399 : | {//Spawned | ||
1400 : | if( get_pcvar_num( p_climb ) ) | ||
1401 : | { | ||
1402 : | if( !is_user_bot( id ) && !is_user_hltv( id ) ) | ||
1403 : | { | ||
1404 : | flight_icons( id )//redraw flashlight hud icons | ||
1405 : | set_msg_block( SVC_STATUSICON, 2 )//Block buy menu | ||
1406 : | |||
1407 : | if( is_climber_alive( id ) ) | ||
1408 : | { | ||
1409 : | //set_pev( id, pev_movetype, MOVETYPE_WALK ) | ||
1410 : | //cs_set_user_team( id, 2 ) | ||
1411 : | |||
1412 : | heal( id ) | ||
1413 : | sfexec( id, 1 )//Execute commands from start/finish config | ||
1414 : | if( get_user_flags( id ) & VIP ) cs_set_user_scoreattrib( id, 4 )//Show admin as VIP on Scoreboard. | ||
1415 : | |||
1416 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_PAUSE ) |
1417 : | ian | 1 | {//If they are paused tp to pause spot and freeze them again. |
1418 : | new Float:coords[3] | ||
1419 : | for( new i=0; i<3; i++ ) coords[i] = origins[ id - 1 ][ ORIG_PAUS + i ] | ||
1420 : | teleport( id, coords ) | ||
1421 : | cl_pause( id ) | ||
1422 : | } | ||
1423 : | |||
1424 : | //Teleport to cp, start, or primary spawn position | ||
1425 : | else if( origins[ id - 1 ][ 0 ] || origins[ id - 1][ 1 ] || origins[ id - 1 ][ 2 ]) gocheck( id ) | ||
1426 : | else if( !teleport( id, start_tp_orig ) ) teleport( id, spawn_tp_orig ) | ||
1427 : | } | ||
1428 : | } | ||
1429 : | sortcssb( ) | ||
1430 : | } | ||
1431 : | else set_msg_block( SVC_STATUSICON, 0 ) | ||
1432 : | } | ||
1433 : | |||
1434 : | public run_tasks( ) | ||
1435 : | { | ||
1436 : | updatebot( ) | ||
1437 : | check_cvars( ) | ||
1438 : | } | ||
1439 : | |||
1440 : | public updatebot( ) | ||
1441 : | { | ||
1442 : | if(get_pcvar_num(p_climb)) | ||
1443 : | { | ||
1444 : | //new players[32], cl | ||
1445 : | //get_players( players, cl, "ach" ) | ||
1446 : | new id = find_player( "i" ) | ||
1447 : | //if(0<cl<3&&!id){ | ||
1448 : | new cl = get_playersnum( ) | ||
1449 : | if( cl < MAXPLAYERS - 2 && !id ) | ||
1450 : | { | ||
1451 : | //Start borrowed code : from Space Headed's AMXX Bot(bot_api.sma) v0.5.1 | ||
1452 : | new name[32] | ||
1453 : | format( name, 31, "Climb v%s", VERSION ) | ||
1454 : | id = engfunc( EngFunc_CreateFakeClient, name ) | ||
1455 : | if( pev_valid( id ) ) | ||
1456 : | { | ||
1457 : | engfunc( EngFunc_FreeEntPrivateData, id ) | ||
1458 : | dllfunc( MetaFunc_CallGameEntity, "player", id ) | ||
1459 : | set_user_info( id, "rate", "3500" ) | ||
1460 : | set_user_info( id, "cl_updaterate", "25" ) | ||
1461 : | set_user_info( id, "cl_lw", "1" ) | ||
1462 : | set_user_info( id, "cl_lc", "1" ) | ||
1463 : | set_user_info( id, "cl_dlmax", "128" ) | ||
1464 : | set_user_info( id, "cl_righthand", "1" ) | ||
1465 : | set_user_info( id, "_vgui_menus", "0" ) | ||
1466 : | set_user_info( id, "_ah", "0" ) | ||
1467 : | set_user_info( id, "dm", "0" ) | ||
1468 : | set_user_info( id, "tracker", "0" ) | ||
1469 : | set_user_info( id, "friends", "0" ) | ||
1470 : | set_user_info( id, "*bot", "1" ) | ||
1471 : | set_pev( id, pev_flags, pev( id, pev_flags ) | FL_FAKECLIENT ) | ||
1472 : | set_pev( id, pev_colormap, id ) | ||
1473 : | |||
1474 : | new msg[128] | ||
1475 : | dllfunc( DLLFunc_ClientConnect, id, name, "127.0.0.1", msg ) | ||
1476 : | dllfunc( DLLFunc_ClientPutInServer, id ) | ||
1477 : | engfunc( EngFunc_RunPlayerMove, id, Float:{0.0,0.0,0.0}, 0.0, 0.0, 0.0, 0, 0, 76 ) | ||
1478 : | //End borrowed code | ||
1479 : | |||
1480 : | cs_set_user_team( id, 2 ) | ||
1481 : | cs_user_spawn( id ) | ||
1482 : | } | ||
1483 : | } | ||
1484 : | //else if(cl>2&&id)server_cmd("kick #%d",get_user_userid(id)) | ||
1485 : | else if( cl == MAXPLAYERS - 1 && id ) | ||
1486 : | { | ||
1487 : | set_entity_visibility( id, 1 ) | ||
1488 : | server_cmd( "kick #%d", get_user_userid( id ) ) | ||
1489 : | } | ||
1490 : | else if( is_user_bot( id ) && id ) | ||
1491 : | { | ||
1492 : | set_entity_visibility( id, 0 ) | ||
1493 : | entity_set_int( id, EV_INT_solid, SOLID_NOT ) | ||
1494 : | set_pev( id, pev_takedamage, DAMAGE_NO ) | ||
1495 : | entity_set_vector( id, EV_VEC_origin, Float:{999999,999999,999999} ) | ||
1496 : | call_think( id ) | ||
1497 : | } | ||
1498 : | } | ||
1499 : | } | ||
1500 : | |||
1501 : | public check_cvars( ) | ||
1502 : | { | ||
1503 : | static bool:nodraw | ||
1504 : | if( get_pcvar_num( p_water_nodraw ) && !nodraw ) | ||
1505 : | { | ||
1506 : | new ent = find_ent_by_class( -1, "func_water" ) | ||
1507 : | while( ent > 0 ) | ||
1508 : | { | ||
1509 : | set_entity_visibility( ent, 0 ) | ||
1510 : | ent = find_ent_by_class( ent, "func_water" ) | ||
1511 : | } | ||
1512 : | nodraw = true | ||
1513 : | } | ||
1514 : | else if( !get_pcvar_num( p_water_nodraw ) && nodraw ) | ||
1515 : | { | ||
1516 : | new ent = find_ent_by_class( -1, "func_water" ) | ||
1517 : | while( ent > 0 ) | ||
1518 : | { | ||
1519 : | set_entity_visibility( ent, 1 ) | ||
1520 : | ent = find_ent_by_class( ent, "func_water" ) | ||
1521 : | } | ||
1522 : | nodraw = false | ||
1523 : | } | ||
1524 : | } | ||
1525 : | |||
1526 : | //Calculate a timeout, returns time remaining on timeout | ||
1527 : | stock check_timeout( id, &checktime, freq = 1, curtime = -1, nowrite = 0 ) | ||
1528 : | { | ||
1529 : | if( curtime < 0 ) curtime = get_systime( ) | ||
1530 : | |||
1531 : | new dif = checktime - curtime | ||
1532 : | if( dif > 3600 ) checktime = curtime + freq | ||
1533 : | |||
1534 : | if( curtime >= checktime ) | ||
1535 : | { | ||
1536 : | if( !nowrite ) checktime = curtime + freq | ||
1537 : | return 0 | ||
1538 : | } | ||
1539 : | |||
1540 : | new msg[76] | ||
1541 : | if( id > 0) | ||
1542 : | { | ||
1543 : | format( msg, 75, "You must wait %d more seconds to use this command again.", dif ) | ||
1544 : | clmsg( id, msg ) | ||
1545 : | } | ||
1546 : | |||
1547 : | return dif | ||
1548 : | } | ||
1549 : | |||
1550 : | public change_boost( id, newboost ) | ||
1551 : | {//Change Boost flags | ||
1552 : | if( !( cvar_enabled( id, p_boost ) && isalive( id ) ) && notpaused( id ) ) return PLUGIN_HANDLED | ||
1553 : | |||
1554 : | new msg[151], rmflag, cflags = timer[ id - 1 ][ TMR_CFLAGS ] | ||
1555 : | if( cflags & CF_SOLID ) | ||
1556 : | { | ||
1557 : | if( task_exists( 150 + id ) ) remove_task( 150 + id ) | ||
1558 : | rmflag = CF_SOLID | ||
1559 : | msg = "Solid Boost Disabled.^n" | ||
1560 : | } | ||
1561 : | else if( cflags & CF_SUPER_JUMP ) | ||
1562 : | { | ||
1563 : | rmflag = CF_SUPER_JUMP | ||
1564 : | msg = "Super Jump Disabled.^n" | ||
1565 : | } | ||
1566 : | else if( cflags & CF_DOUBLE_JUMP) | ||
1567 : | { | ||
1568 : | rmflag = CF_DOUBLE_JUMP | ||
1569 : | msg = "Double Jump Disabled.^n" | ||
1570 : | } | ||
1571 : | if( rmflag > 0 ) timer[ id - 1 ][ TMR_CFLAGS ] -= rmflag | ||
1572 : | if( !( rmflag & newboost ) && \ | ||
1573 : | ian | 19 | !check_timeout( id, time_stamps[id][TS_BOOST], BOOST_TIMEOUT, ( cflags & CF_START ? get_climber_time( id ) : get_systime() ) ) ) |
1574 : | ian | 1 | { |
1575 : | if( newboost == CF_SOLID ) | ||
1576 : | { | ||
1577 : | format( msg, 150, "%sSolid Boost Enabled.", msg ) | ||
1578 : | new ida[1] | ||
1579 : | ida[0] = id | ||
1580 : | set_task( 15.0, "solid_boost_timer", 150 + id, ida, 1 ) | ||
1581 : | if( timer[ id - 1 ][ TMR_CFLAGS ] & CF_START ) timer[ id - 1 ][ TMR_CNTBST ]++ | ||
1582 : | } | ||
1583 : | if( newboost == CF_SUPER_JUMP ) format( msg, 150, "%sSuper Jump Enabled.", msg ) | ||
1584 : | if( newboost == CF_DOUBLE_JUMP ) format( msg, 150, "%sDouble Jump Enabled.", msg ) | ||
1585 : | timer[ id - 1 ][ TMR_CFLAGS ] |= newboost | ||
1586 : | } | ||
1587 : | if(strlen(msg))clmsg(id,msg) | ||
1588 : | return PLUGIN_HANDLED | ||
1589 : | } | ||
1590 : | |||
1591 : | //Task to auto disable solid boost after timeout | ||
1592 : | public solid_boost_timer( ida[] ) | ||
1593 : | change_boost( ida[0], CF_SOLID ) | ||
1594 : | |||
1595 : | /*public server_frame( ) | ||
1596 : | {//Semi-clip | ||
1597 : | if( get_pcvar_num( p_climb ) ) | ||
1598 : | { | ||
1599 : | new players[32], bool:skip[32], num, i, j | ||
1600 : | new Float:orig_i[3], Float:orig_j[3] | ||
1601 : | new Float:vel_i[3], Float:vel_iz[3] | ||
1602 : | new id_i, id_j, cflags_i, cflags_j | ||
1603 : | get_players( players, num, "ac" ) | ||
1604 : | for( i = 0; i < num; i++ ) | ||
1605 : | { | ||
1606 : | id_i = players[i] | ||
1607 : | ian | 19 | cflags_i = timer[id_i][TMR_CFLAGS] |
1608 : | ian | 1 | |
1609 : | if( !( cflags_i & CF_PAUSE ) ) | ||
1610 : | { | ||
1611 : | entity_get_vector( id_i, EV_VEC_origin, orig_i ) | ||
1612 : | entity_get_vector( id_i, EV_VEC_velocity, vel_i ) | ||
1613 : | |||
1614 : | vel_iz[0] = vel_i[0] > 0 ? -70.0 : 70.0 | ||
1615 : | vel_iz[1] = vel_i[1] > 0 ? -70.0 : 70.0 | ||
1616 : | vel_iz[2] = vel_i[2] > 0 ? -120.0 : 120.0 | ||
1617 : | |||
1618 : | if( !vel_i[0] ) vel_i[0] = vel_iz[0] * -1 | ||
1619 : | if( !vel_i[1] ) vel_i[1] = vel_iz[1] * -1 | ||
1620 : | if( !vel_i[2] ) vel_i[2] = vel_iz[2] * -1 | ||
1621 : | |||
1622 : | for( j=0; j<num; j++ ) | ||
1623 : | { | ||
1624 : | if( i != j ) | ||
1625 : | { | ||
1626 : | id_j = players[j] | ||
1627 : | ian | 19 | cflags_j = timer[id_j][TMR_CFLAGS] |
1628 : | ian | 1 | |
1629 : | if( ( !( cflags_i & CF_SOLID && cflags_j & CF_SOLID ) || skip[i] ) && !( cflags_j & CF_PAUSE ) ) | ||
1630 : | { | ||
1631 : | entity_get_vector( id_j, EV_VEC_origin, orig_j ) | ||
1632 : | |||
1633 : | if( is_between_f( orig_j[0], orig_i[0] + vel_iz[0], orig_i[0] + vel_i[0] ) && | ||
1634 : | is_between_f( orig_j[1], orig_i[1] + vel_iz[1], orig_i[1] + vel_i[1] ) && | ||
1635 : | is_between_f( orig_j[2], orig_i[2] + vel_iz[2], orig_i[2] + vel_i[2] ) ) | ||
1636 : | { | ||
1637 : | unsolid( id_i ) | ||
1638 : | unsolid( id_j ) | ||
1639 : | skip[i] = true | ||
1640 : | skip[j] = true | ||
1641 : | //maybe reset j first time i runs this, to unsolid anyone they might be boosting with | ||
1642 : | } | ||
1643 : | } | ||
1644 : | } | ||
1645 : | } | ||
1646 : | if( !skip[i] ) solid( id_i ) | ||
1647 : | } | ||
1648 : | } | ||
1649 : | } | ||
1650 : | return PLUGIN_CONTINUE | ||
1651 : | }*/ | ||
1652 : | public server_frame( ) | ||
1653 : | { | ||
1654 : | if( !get_pcvar_num(p_climb) ) | ||
1655 : | return PLUGIN_CONTINUE | ||
1656 : | |||
1657 : | sc_fcount++ | ||
1658 : | if( sc_fcount > 9 ) sc_fcount = 0 | ||
1659 : | |||
1660 : | //Semi-clip | ||
1661 : | new players[32],num,i,j,Float:c1[3],Float:c2[3] | ||
1662 : | new Float:c1z[3],Float:c2z[3] | ||
1663 : | new id_i,id_j,cflags_i,cflags_j | ||
1664 : | get_players(players,num,"ac") | ||
1665 : | //new Float:c1d[3],Float:c2d[3],xyadd,zadd | ||
1666 : | for(i=0;i<num;i++){ | ||
1667 : | id_i=players[i] | ||
1668 : | ian | 19 | cflags_i=timer[id_i][TMR_CFLAGS] |
1669 : | ian | 1 | if(!(cflags_i&CF_PAUSE)){ |
1670 : | //solid(players[i]) | ||
1671 : | entity_get_vector(id_i,EV_VEC_origin,c1) | ||
1672 : | //entity_get_vector(players[i],EV_VEC_velocity,c1d) | ||
1673 : | c1z[2]=c1[2] | ||
1674 : | c1[2]=0.0 | ||
1675 : | for(j=0;j<num;j++){ | ||
1676 : | id_j=players[j] | ||
1677 : | ian | 19 | cflags_j=timer[id_j][TMR_CFLAGS] |
1678 : | ian | 1 | if(!(cflags_j&CF_SOLID)&&i!=j){ |
1679 : | entity_get_vector(id_j,EV_VEC_origin,c2) | ||
1680 : | //entity_get_vector(players[j],EV_VEC_velocity,c2d) | ||
1681 : | c2z[2]=c2[2] | ||
1682 : | c2[2]=0.0 | ||
1683 : | if(vector_distance(c1,c2)<90&&vector_distance(c1z,c2z)<110){ | ||
1684 : | if(!(cflags_i&CF_SOLID&&cflags_j&CF_SOLID)){//&&vector_distance(c1,c2)>25&&vector_distance(c1z,c2z)>30)){ | ||
1685 : | unsolid(id_i) | ||
1686 : | unsolid(id_j) | ||
1687 : | j=num | ||
1688 : | } | ||
1689 : | } | ||
1690 : | } | ||
1691 : | if(j+1==num)solid(id_i) | ||
1692 : | } | ||
1693 : | } | ||
1694 : | } | ||
1695 : | return PLUGIN_CONTINUE | ||
1696 : | } | ||
1697 : | |||
1698 : | stock bool:is_between_f( Float:mid, Float:a, Float:b ) | ||
1699 : | { | ||
1700 : | if( a < b && ( a < mid < b ) ) return true | ||
1701 : | if( a > b && ( a > mid > b ) ) return true | ||
1702 : | return false | ||
1703 : | } | ||
1704 : | |||
1705 : | stock Float:vector_z_distance_f( Float:vec1[3], Float:vec2[3] ) | ||
1706 : | { | ||
1707 : | return Float:floatsqroot( ( vec1[2] - vec2[2] ) ^ 2.0 ) | ||
1708 : | } | ||
1709 : | |||
1710 : | stock Float:vector_xy_distance_f( Float:vec1[3], Float:vec2[3] ) | ||
1711 : | { | ||
1712 : | return Float:floatsqroot( ( ( vec1[0] - vec2[0] ) ^ 2.0 ) + ( ( vec1[1] - vec2[1] ) ^ 2.0 ) ) | ||
1713 : | } | ||
1714 : | |||
1715 : | public client_PreThink( id ) | ||
1716 : | { | ||
1717 : | if( !get_pcvar_num( p_climb ) || is_user_bot( id ) || !is_climber_alive( id ) ) | ||
1718 : | return PLUGIN_CONTINUE | ||
1719 : | |||
1720 : | ian | 19 | if( sclip[id] && sc_fcount == 9 ) entity_set_int( id, EV_INT_solid, SOLID_BBOX ) |
1721 : | ian | 1 | |
1722 : | //Detect button use. Replicated from HL SDK | ||
1723 : | if( get_user_button( id ) & IN_USE && !( get_user_oldbutton( id ) & IN_USE ) ) | ||
1724 : | { | ||
1725 : | new entlist[3], count | ||
1726 : | count = find_sphere_class( id, "func_button", 64.0, entlist, 3 ) | ||
1727 : | if( count ) | ||
1728 : | { | ||
1729 : | new Float:orig[3] | ||
1730 : | for( new i = 0; i < count; i++ ) | ||
1731 : | { | ||
1732 : | get_brush_entity_origin( entlist[i], orig ) | ||
1733 : | if( is_in_viewcone( id, orig ) ) button_used( id, entlist[i] ) | ||
1734 : | } | ||
1735 : | } | ||
1736 : | } | ||
1737 : | |||
1738 : | ian | 19 | new cflags = timer[id][TMR_CFLAGS] |
1739 : | ian | 1 | |
1740 : | //Double and super jump boosts | ||
1741 : | if( get_pcvar_num( p_boost ) ) | ||
1742 : | { | ||
1743 : | new bool:onground = false | ||
1744 : | if( get_entity_flags( id ) & FL_ONGROUND ) onground = true | ||
1745 : | if( get_user_button( id ) & IN_JUMP ) | ||
1746 : | { | ||
1747 : | if( cflags & CF_SUPER_JUMP && onground ) | ||
1748 : | { | ||
1749 : | ian | 19 | entity_get_vector( id, EV_VEC_velocity, post_think_vel[id] ) |
1750 : | if( post_think_vel[id][0] != 0.0 || post_think_vel[id][1] != 0.0) | ||
1751 : | ian | 1 | { |
1752 : | ian | 19 | velocity_by_aim( id, 400, post_think_vel[id] ) |
1753 : | if( post_think_vel[id][2] < 250.0) post_think_vel[id][2] = 250.0 | ||
1754 : | if( post_think_vel[id][2] > 350.0) post_think_vel[id][2] = 350.0 | ||
1755 : | ian | 1 | } |
1756 : | ian | 19 | else post_think_vel[id] = Float:{0.0,0.0,0.0} |
1757 : | ian | 1 | } |
1758 : | else if( cflags & CF_DOUBLE_JUMP ) | ||
1759 : | { | ||
1760 : | if( !onground && !(get_user_oldbutton( id ) & IN_JUMP ) ) | ||
1761 : | { | ||
1762 : | ian | 19 | entity_get_vector( id, EV_VEC_velocity, post_think_vel[id] ) |
1763 : | float_clamp( post_think_vel[id][0], -150.0, 150.0 ) | ||
1764 : | float_clamp( post_think_vel[id][1], -150.0, 150.0 ) | ||
1765 : | if( is_finished( id ) || post_think_vel[id][2] > -500 ) post_think_vel[id][2] = 250.0 | ||
1766 : | else post_think_vel[id] = Float:{ 0.0, 0.0, 0.0 } | ||
1767 : | ian | 1 | } |
1768 : | } | ||
1769 : | } | ||
1770 : | } | ||
1771 : | |||
1772 : | //Prevent drowning | ||
1773 : | // waterlevel 0 - not in water | ||
1774 : | // waterlevel 1 - feet in water | ||
1775 : | // waterlevel 2 - waist in water | ||
1776 : | // waterlevel 3 - head in water | ||
1777 : | if( pev( id, pev_waterlevel ) == 3 ) set_pev( id, pev_waterlevel, 2 ) | ||
1778 : | |||
1779 : | new button = pev( id, pev_button ) | ||
1780 : | new oldbutton = pev( id, pev_oldbuttons ) | ||
1781 : | |||
1782 : | //If measure flag is set, call measure function | ||
1783 : | if( !( oldbutton & IN_ATTACK ) && button & IN_ATTACK ) | ||
1784 : | if( cflags & CF_MEASURE ) do_measure( id ) | ||
1785 : | else if( cflags & CF_MEASURE2 ) do_measure2( id, 1 ) | ||
1786 : | |||
1787 : | //Knife attack timeout | ||
1788 : | new wpn, clip, ammo | ||
1789 : | wpn = get_user_weapon( id, clip, ammo ) | ||
1790 : | if( wpn == CSW_KNIFE ) | ||
1791 : | { | ||
1792 : | |||
1793 : | if( button & IN_ATTACK || button & IN_ATTACK2 ) | ||
1794 : | ian | 19 | if( check_timeout( 0, time_stamps[id][TS_KNIFE], KNIFE_TIMEOUT ) ) |
1795 : | ian | 1 | set_pev( id, pev_button, pev( id, pev_button ) & ~IN_ATTACK_EITHER ) |
1796 : | } | ||
1797 : | return PLUGIN_CONTINUE | ||
1798 : | } | ||
1799 : | |||
1800 : | public client_PostThink(id) | ||
1801 : | { | ||
1802 : | if( !( get_pcvar_num(p_climb) && get_pcvar_num(p_boost) && is_climber_alive( id ) ) || is_user_bot(id) ) | ||
1803 : | return PLUGIN_CONTINUE | ||
1804 : | |||
1805 : | ian | 19 | if( sclip[id] ) entity_set_int( id, EV_INT_solid, SOLID_NOT ) |
1806 : | ian | 1 | |
1807 : | ian | 19 | if( _:get_distance( _:post_think_vel[id], { 0, 0, 0 } ) ) |
1808 : | ian | 1 | { |
1809 : | ian | 19 | entity_set_vector( id, EV_VEC_velocity, post_think_vel[id] ) |
1810 : | post_think_vel[id] = Float:{ 0.0, 0.0, 0.0 } | ||
1811 : | if( timer[id][TMR_CFLAGS] & CF_START ) | ||
1812 : | ian | 1 | { |
1813 : | ian | 19 | timer[id][TMR_CNTBST]++ //Increment client boost count |
1814 : | ian | 1 | change_boost( id, CF_NULL ) |
1815 : | } | ||
1816 : | else if( !is_finished(id) )change_boost( id, CF_NULL ) | ||
1817 : | } | ||
1818 : | |||
1819 : | //Store pause data | ||
1820 : | ian | 19 | if( !( timer[id][TMR_CFLAGS] & CF_PAUSE ) ) |
1821 : | ian | 1 | { |
1822 : | new Float:coords[3] | ||
1823 : | entity_get_vector( id, EV_VEC_origin, coords ) | ||
1824 : | ian | 19 | for( new i=0; i<3; i++ ) origins[id][ORIG_PAUS+i] = coords[i] |
1825 : | origins[id][ORIG_PAUS+3] = entity_get_float( id, EV_FL_gravity ) | ||
1826 : | ian | 1 | } |
1827 : | return PLUGIN_CONTINUE | ||
1828 : | } | ||
1829 : | |||
1830 : | public button_used( id, button ) | ||
1831 : | { | ||
1832 : | new btn_type = 0 | ||
1833 : | for( new i = 0; i < ST_BTN_CNT || i < FN_BTN_CNT; i++ ) | ||
1834 : | { | ||
1835 : | if( i < ST_BTN_CNT ) | ||
1836 : | if( button == ST_BTNS[i] ) | ||
1837 : | { | ||
1838 : | btn_type = 1 | ||
1839 : | break | ||
1840 : | } | ||
1841 : | if( i < FN_BTN_CNT ) | ||
1842 : | if( button == FN_BTNS[i] ) | ||
1843 : | { | ||
1844 : | btn_type = 2 | ||
1845 : | break | ||
1846 : | } | ||
1847 : | } | ||
1848 : | |||
1849 : | ian | 19 | //new cflags = timer[id][TMR_CFLAGS] |
1850 : | ian | 1 | |
1851 : | if( btn_type == 1 )//Start Button | ||
1852 : | { | ||
1853 : | new Float:orig[3], bool:need_respawn = true //Float:view[3] | ||
1854 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_START ) need_respawn = false |
1855 : | ian | 1 | |
1856 : | ian | 19 | for( new i = 0; i < 48; i++ ) origins[id][i] = 0.0 //Erase checkpoints |
1857 : | ian | 1 | |
1858 : | //Set all associated variables | ||
1859 : | ian | 19 | timer[id][TMR_STARTD] = get_systime() |
1860 : | ian | 1 | change_status(id,CF_START) |
1861 : | ian | 19 | timer[id][TMR_CNTCPS] = 0 |
1862 : | timer[id][TMR_CNTGCS] = 0 | ||
1863 : | timer[id][TMR_CNTBST] = 0 | ||
1864 : | timer[id][TMR_CPPOS] = 0 | ||
1865 : | timer[id][TMR_CNTWPN] = 0 | ||
1866 : | time_stamps[id][TS_BOOST] = BOOST_TIMEOUT | ||
1867 : | ian | 1 | |
1868 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_COUNTDOWN ) set_countdown_time( id ) |
1869 : | ian | 1 | |
1870 : | //Record starting weapon | ||
1871 : | rank_mod_update( id ) | ||
1872 : | |||
1873 : | //Respawn client to clear items. | ||
1874 : | if( need_respawn && get_pcvar_num( p_start_respawn ) ) | ||
1875 : | { | ||
1876 : | entity_get_vector( id, EV_VEC_origin, orig ) | ||
1877 : | //entity_get_vector( id, EV_VEC_angles, view ) | ||
1878 : | cs_user_spawn( id ) | ||
1879 : | entity_set_vector( id, EV_VEC_origin, orig ) | ||
1880 : | //entity_set_vector( id, EV_VEC_angles, view ) | ||
1881 : | delay_duck( id ) | ||
1882 : | ian | 19 | //time_stamps[id][TS_SPAWN]=get_systime() |
1883 : | ian | 1 | } |
1884 : | heal( id ) | ||
1885 : | cs_set_user_money( id, get_pcvar_num( p_startmoney ) ) | ||
1886 : | |||
1887 : | //Play random start sound and text messages | ||
1888 : | if( get_pcvar_num( p_sounds ) ) switch( random_num( 0, 2 ) ) | ||
1889 : | { | ||
1890 : | case 0:client_cmd( id, "spk barney/beertopside" ) | ||
1891 : | case 1:client_cmd( id, "spk scientist/c3a2_sci_portopen" ) | ||
1892 : | case 2:client_cmd( id, "spk barney/c1a2_ba_climb" ) | ||
1893 : | } | ||
1894 : | |||
1895 : | change_boost( id, CF_NULL ) //Disable Boosts | ||
1896 : | ian | 19 | //time_stamps[id][TS_BOOST]=0 |
1897 : | ian | 1 | clmsg(id,"Timer started. Go Go Go!!!") |
1898 : | //client_print(id,print_chat,"Timer started. Go Go Go!!!") | ||
1899 : | |||
1900 : | sfexec( id, 2 ) //Execute commands from start/finish config | ||
1901 : | |||
1902 : | sortcssb( ) //Update frags to reorder scoreboard | ||
1903 : | } | ||
1904 : | else if( btn_type == 2 )//Finish Button | ||
1905 : | { | ||
1906 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_START) |
1907 : | ian | 1 | { |
1908 : | //Set client variables | ||
1909 : | ian | 19 | timer[id][TMR_FINISH] = get_systime( ) |
1910 : | ian | 1 | change_status( id, CF_STOP ) |
1911 : | ian | 19 | timer[id][TMR_SESFIN]++ |
1912 : | timer[id][TMR_MAPFIN]++ | ||
1913 : | ian | 1 | |
1914 : | //Announce to client | ||
1915 : | if( get_pcvar_num( p_sounds ) ) client_cmd( 0, "spk woop" ) | ||
1916 : | clmsg( id, "Congratulations 1337 climber." ) | ||
1917 : | //client_print(id,print_chat,"Congratulations 1337 climber.") | ||
1918 : | new name[32], msg[21] | ||
1919 : | formatex( msg, sizeof( msg ) - 1, "%s^t%s", getuserstatus( id ), parsetime( get_climber_time( id ) ) ) | ||
1920 : | //clmsg(id,msg) | ||
1921 : | //client_print(id,print_chat,msg) | ||
1922 : | |||
1923 : | new wpn[11] | ||
1924 : | ian | 19 | get_weapon_name( timer[id][TMR_CNTWPN], wpn, 10 ) |
1925 : | ian | 1 | |
1926 : | //Announce to all | ||
1927 : | get_user_name( id, name, 32 ) | ||
1928 : | client_print( 0, print_chat, "%s^t%s^t(%s/ %d CPS/ %d GCS/ %d Boosts)^tCompleted (%d, %d)", | ||
1929 : | name, msg, | ||
1930 : | ian | 19 | wpn, timer[id][TMR_CNTCPS], timer[id][TMR_CNTGCS], timer[id][TMR_CNTBST], |
1931 : | timer[id][TMR_SESFIN], timer[id][TMR_MAPFIN] ) | ||
1932 : | ian | 1 | |
1933 : | ian | 19 | new cnt_score = ( ( ( timer[id][TMR_CNTBST] > 0 ? 1 : 0 ) * 1000000 ) + |
1934 : | ( ( timer[id][TMR_CNTCPS] > 0 ? 1 : 0 ) * 100000 ) + | ||
1935 : | ( timer[id][TMR_CNTWPN] * 10000 ) + | ||
1936 : | ian | 1 | get_climber_time( id ) ) |
1937 : | |||
1938 : | ian | 19 | new bst_score = ( ( ( timer[id][TMR_BSTBST] > 0 ? 1 : 0 ) * 1000000 ) + |
1939 : | ( ( timer[id][TMR_BSTCPS] > 0 ? 1 : 0 ) * 100000 ) + | ||
1940 : | ( timer[id][TMR_BSTWPN] * 10000 ) + | ||
1941 : | timer[id][TMR_BSTTME] ) | ||
1942 : | ian | 1 | |
1943 : | if( cnt_score < bst_score || bst_score == 0 ) | ||
1944 : | { | ||
1945 : | ian | 19 | timer[id][TMR_BSTTME] = get_climber_time( id ) |
1946 : | timer[id][TMR_BSTCPS] = timer[id][TMR_CNTCPS] | ||
1947 : | timer[id][TMR_BSTGCS] = timer[id][TMR_CNTGCS] | ||
1948 : | timer[id][TMR_BSTBST] = timer[id][TMR_CNTBST] | ||
1949 : | timer[id][TMR_BSTWPN] = timer[id][TMR_CNTWPN] | ||
1950 : | ian | 1 | } |
1951 : | |||
1952 : | sfexec( id, 2 )//Execute commands from start/finish config | ||
1953 : | |||
1954 : | if( CLIMB_SAVE ) db_save( id ) | ||
1955 : | |||
1956 : | sortcssb( ) //Update frags to reorder scoreboard | ||
1957 : | } | ||
1958 : | ian | 19 | else if(timer[id][TMR_CFLAGS]&CF_STOP&&timer[id][TMR_SESFIN]==0){ |
1959 : | ian | 1 | //change_status(id,CF_FINISH) |
1960 : | ian | 19 | timer[id][TMR_SESFIN]++ |
1961 : | ian | 1 | new msg[100]="Congratulations, you finished! But you didn't start the timer. :(" |
1962 : | clmsg(id,msg) | ||
1963 : | client_print(id,print_chat,msg) | ||
1964 : | //Execute commands from start/finish config | ||
1965 : | sfexec(id,2) | ||
1966 : | //If stats save enabled warn unregistered clients to register | ||
1967 : | //if(CLIMB_SAVE)regwarn(id) | ||
1968 : | } | ||
1969 : | heal(id) | ||
1970 : | } | ||
1971 : | return PLUGIN_HANDLED | ||
1972 : | } | ||
1973 : | |||
1974 : | //Execute commands from start/finish config | ||
1975 : | public sfexec(id,clevent){ | ||
1976 : | ian | 19 | new clstat[3],cflags=timer[id][TMR_CFLAGS] |
1977 : | /*switch(timer[id][TMR_CFLAGS]){ | ||
1978 : | ian | 1 | case TMR_CFLAGS_STOP: clstat="ns" |
1979 : | case TMR_CFLAGS_STRT: clstat="st" | ||
1980 : | case TMR_CFLAGS_FNSH: clstat="fn" | ||
1981 : | }*/ | ||
1982 : | if(is_finished(id))clstat="fn" | ||
1983 : | else if(cflags&CF_STOP)clstat="ns" | ||
1984 : | else if(cflags&CF_START)clstat="st" | ||
1985 : | ian | 19 | //else if(timer[id][TMR_CFLAGS]&CF_FINISH)clstat="fn" |
1986 : | //if(equal(clstat,"ns")&&(get_user_flags(id)&VIP||timer[id][TMR_SESFIN]>0))clstat="fn" | ||
1987 : | ian | 1 | |
1988 : | for(new i=0;i<sfcount;i++){ | ||
1989 : | new cmdstat[3],cmdevent[2],cmdtype[3],cmd[60],idtype[5] | ||
1990 : | parse(sfactions[i],cmdstat,2,cmdevent,1,cmdtype,2,cmd,sizeof(cmd)-1,idtype,4) | ||
1991 : | if((equali(cmdstat,clstat)||equali(cmdstat,"ay"))&&str_to_num(cmdevent)&clevent){ | ||
1992 : | if(equali(cmdtype,"sc")){ | ||
1993 : | if(equali(idtype,"uid"))format(cmd,sizeof(cmd)-1,cmd,get_user_userid(id)) | ||
1994 : | else{ | ||
1995 : | new name[24] | ||
1996 : | get_user_name(id,name,sizeof(name)-1) | ||
1997 : | format(name,sizeof(name),"^"%s^"",name) | ||
1998 : | format(cmd,sizeof(cmd)-1,cmd,name) | ||
1999 : | client_print(id,print_chat,cmd) | ||
2000 : | } | ||
2001 : | server_cmd(cmd) | ||
2002 : | } | ||
2003 : | else{ | ||
2004 : | client_cmd(id,cmd) | ||
2005 : | } | ||
2006 : | } | ||
2007 : | } | ||
2008 : | return PLUGIN_HANDLED | ||
2009 : | } | ||
2010 : | |||
2011 : | //Update frags to reorder scoreboard | ||
2012 : | public sortcssb( ) | ||
2013 : | { | ||
2014 : | new players[32], num, id | ||
2015 : | get_players_ordered( players, num ) | ||
2016 : | for( new i = 0 ; i < num; i++ ) | ||
2017 : | { | ||
2018 : | id = players[i] | ||
2019 : | set_user_frags( id, 0 ) | ||
2020 : | cs_set_user_deaths( id, i + 1 ) | ||
2021 : | |||
2022 : | message_begin( MSG_ALL, SVC_TEAMINFO ) | ||
2023 : | write_byte( id ) | ||
2024 : | write_string( "CT" ) | ||
2025 : | message_end( ) | ||
2026 : | } | ||
2027 : | |||
2028 : | //Show bot as spectator on scoreboard | ||
2029 : | message_begin( MSG_ALL, SVC_TEAMINFO ) | ||
2030 : | write_byte( find_player( "i" ) ) | ||
2031 : | write_string( "SPECTATOR" ) | ||
2032 : | message_end( ) | ||
2033 : | } | ||
2034 : | |||
2035 : | //Returns array of client id's sorted by climb time | ||
2036 : | public get_players_ordered( players[32], &num ) | ||
2037 : | { | ||
2038 : | get_players( players, num, "ch" ) | ||
2039 : | |||
2040 : | new i, id, pdata[32][3] //{ status, score, id } | ||
2041 : | for( i = 0; i < num; i++ ) | ||
2042 : | {//Fill player data sorting array | ||
2043 : | id = players[i] | ||
2044 : | pdata[i][2] = id | ||
2045 : | |||
2046 : | ian | 19 | if( timer[id][TMR_BSTTME] ) |
2047 : | ian | 1 | {//Has high score |
2048 : | pdata[i][0] = 0 | ||
2049 : | ian | 19 | pdata[i][1] = ( ( ( timer[id][TMR_BSTBST] > 0 ? 1 : 0 ) * 1000000 ) + |
2050 : | ( ( timer[id][TMR_BSTCPS] > 0 ? 1 : 0 ) * 100000 ) + | ||
2051 : | ( timer[id][TMR_BSTWPN] * 10000 ) + | ||
2052 : | timer[id][TMR_BSTTME] ) | ||
2053 : | ian | 1 | } |
2054 : | ian | 19 | else if( timer[id][TMR_CFLAGS] & CF_START || timer[id][TMR_CFLAGS] & CF_PAUSE ) |
2055 : | ian | 1 | {//Has time but no high score |
2056 : | pdata[i][0] = 1 | ||
2057 : | ian | 19 | pdata[i][1] = ( ( ( timer[id][TMR_CNTBST] > 0 ? 1 : 0 ) * 1000000 ) + |
2058 : | ( ( timer[id][TMR_CNTCPS] > 0 ? 1 : 0 ) * 100000 ) + | ||
2059 : | ( timer[id][TMR_CNTWPN] * 10000 ) + | ||
2060 : | ian | 1 | get_climber_time( id ) ) |
2061 : | } | ||
2062 : | else pdata[i][0] = 2 //No time or high score | ||
2063 : | } | ||
2064 : | |||
2065 : | SortStrings( pdata, num ) | ||
2066 : | for( i = 0; i < num; i++ ) | ||
2067 : | players[i] = pdata[i][2] | ||
2068 : | } | ||
2069 : | |||
2070 : | /*public get_limit(){ | ||
2071 : | //if(get_pcvar_num(p_webmod)) | ||
2072 : | //return 0 | ||
2073 : | new url[100] | ||
2074 : | get_pcvar_string(p_stats_url,url,99) | ||
2075 : | if(strlen(url)) | ||
2076 : | return false | ||
2077 : | return true | ||
2078 : | }*/ | ||
2079 : | |||
2080 : | /*public get_url( id, file[] ) | ||
2081 : | { | ||
2082 : | new url[100] | ||
2083 : | get_pcvar_string( p_stats_url, url, 99 ) | ||
2084 : | //if(get_pcvar_num(p_webmod)){ | ||
2085 : | // new ip[10],iip[33],eip[33],port[10] | ||
2086 : | // get_user_ip(id,ip,9) | ||
2087 : | // get_pcvar_string(p_ip_internal,iip,32) | ||
2088 : | // get_pcvar_string(p_ip_external,eip,32) | ||
2089 : | // get_pcvar_string(p_port,port,9) | ||
2090 : | // if(equal(ip,"192.168.",8))format(url,99,"http://%s:%s/%s",iip,port,file) | ||
2091 : | // else format(url,99,"http://%s:%s/%s",eip,port,file) | ||
2092 : | //} | ||
2093 : | if( strlen( url ) ) format( url, 99, "%sclimb_scores.html", url ) | ||
2094 : | return url | ||
2095 : | }*/ | ||
2096 : | |||
2097 : | stock sb_add_tabs( str[], size) | ||
2098 : | { | ||
2099 : | new len = strlen( str )// > 7 ? 1 : 2 | ||
2100 : | add( str[len], size, "^t") | ||
2101 : | if( len < 8 ) add( str[len+1], size, "^t") | ||
2102 : | } | ||
2103 : | |||
2104 : | public climbscores( id ) | ||
2105 : | {//Show scoreboard | ||
2106 : | if( get_pcvar_num( p_climb ) ) | ||
2107 : | { | ||
2108 : | if( get_systime() - ts_score > 2 ) | ||
2109 : | { | ||
2110 : | new fh = fopen( SCORES_PATH, "w" ) | ||
2111 : | |||
2112 : | //Header-8 cols: #, name, status, time, sct/cp/gc/boost, Best, cp/gc/boost, Completed | ||
2113 : | fprintf( fh, "<link rel=stylesheet href=http://ian.cammarata.us/sb><table><tr><td id=a>" ) | ||
2114 : | fprintf( fh, "<pre># Name Status Time Wpn/CP/GC/Bst Best ... Fin</pre>" ) | ||
2115 : | fprintf( fh, "</td></tr><tr id=b><td></td></tr><tr><td><pre>" ) | ||
2116 : | |||
2117 : | new line[251], name[NAMELEN+2], players[32], num, tid, written_len | ||
2118 : | new ctime, cwpn, ccp, cgc, cbst | ||
2119 : | new btime, bwpn, bcp, bgc, bbst | ||
2120 : | new ctime_str[20], btime_str[20] | ||
2121 : | |||
2122 : | get_players_ordered( players, num ) | ||
2123 : | |||
2124 : | for(new i = 1; i <= num; i++ ) | ||
2125 : | { | ||
2126 : | ian | 19 | tid = players[i] |
2127 : | ian | 1 | |
2128 : | get_user_name( tid, name, NAMELEN) | ||
2129 : | sb_add_tabs( name, NAMELEN+2 ) | ||
2130 : | |||
2131 : | ctime = get_climber_time(tid) | ||
2132 : | ian | 19 | cwpn = timer[tid][TMR_CNTWPN] |
2133 : | ccp = timer[tid][TMR_CNTCPS] | ||
2134 : | cgc = timer[tid][TMR_CNTGCS] | ||
2135 : | cbst = timer[tid][TMR_CNTBST] | ||
2136 : | ian | 1 | format( ctime_str, 19, "%d/%d/%d/%d", cwpn, ccp, cgc, cbst ) |
2137 : | sb_add_tabs( ctime_str, 19 ) | ||
2138 : | |||
2139 : | ian | 19 | btime = timer[tid][TMR_BSTTME] |
2140 : | bwpn = timer[tid][TMR_BSTWPN] | ||
2141 : | bcp = timer[tid][TMR_BSTCPS] | ||
2142 : | bgc = timer[tid][TMR_BSTGCS] | ||
2143 : | bbst = timer[tid][TMR_BSTBST] | ||
2144 : | ian | 1 | format( btime_str, 19, "%d/%d/%d/%d", bwpn, bcp, bgc, bbst ) |
2145 : | sb_add_tabs( btime_str, 19 ) | ||
2146 : | |||
2147 : | formatex( line, 250, | ||
2148 : | "%s%d %s%s %s %s%s %s%d%s", | ||
2149 : | ian | 22 | i % 2 ? NULLSTR : "<div>", |
2150 : | ian | 1 | i, htmlspecialchars( name ), |
2151 : | getuserstatus( tid ), | ||
2152 : | parsetime( ctime ), ctime_str, | ||
2153 : | parsetime( btime ), btime_str, | ||
2154 : | ian | 19 | timer[tid][TMR_MAPFIN], |
2155 : | ian | 22 | i % 2 ? NULLSTR : "</div>" ) |
2156 : | ian | 1 | written_len += strlen( line ) |
2157 : | //if( limit && written_len > ( 1263 - strlen( cust_msg ) ) ) break | ||
2158 : | if( written_len > 1263 ) break | ||
2159 : | fprintf( fh, line ) | ||
2160 : | } | ||
2161 : | //1530-150-117=1263 | ||
2162 : | new cust_msg[33] | ||
2163 : | get_pcvar_string( p_stats_msg, cust_msg, 32 ) | ||
2164 : | if( !strlen( cust_msg ) ) formatex( cust_msg, 32, "Climb %s", VERSION ) | ||
2165 : | fprintf( fh, "</pre></td></tr><tr id=d><td></td></tr><tr><td id=e></td></tr><tr>" ) | ||
2166 : | fprintf( fh, "<td id=a>%s</td></tr></table>", cust_msg ) | ||
2167 : | fclose( fh ) | ||
2168 : | ts_score = get_systime() | ||
2169 : | } | ||
2170 : | |||
2171 : | show_motd( id, SCORES_PATH, "Current Scores" ) | ||
2172 : | } | ||
2173 : | return PLUGIN_HANDLED | ||
2174 : | } | ||
2175 : | |||
2176 : | public parsetime(sec){//Convert seconds to time string with zero padded seconds field | ||
2177 : | new timestr[9],mins | ||
2178 : | mins=sec/60 | ||
2179 : | sec=sec%60 | ||
2180 : | formatex(timestr,8,"%d:%s%d",mins,sec<10?"0":"",sec) | ||
2181 : | return timestr | ||
2182 : | } | ||
2183 : | |||
2184 : | public get_climber_time( id ) | ||
2185 : | {//Calculate client climb time in seconds | ||
2186 : | ian | 19 | /*new ptime,cflags=timer[id][TMR_CFLAGS] |
2187 : | ptime=timer[id][TMR_FINISH]-timer[id][TMR_STARTD] | ||
2188 : | if(cflags&CF_STOP&&timer[id=1][TMR_SESFIN]>0)ptime=timer[id][TMR_FINISH]-timer[id][TMR_STARTD] | ||
2189 : | ian | 1 | else if(cflags&CF_STOP)ptime=0 |
2190 : | ian | 19 | else if(cflags&CF_START)ptime=get_systime()-timer[id][TMR_STARTD] |
2191 : | else if(cflags&CF_PAUSE)ptime=timer[id][TMR_STARTD]*/ | ||
2192 : | new cflags = timer[id][TMR_CFLAGS] | ||
2193 : | if( cflags & CF_START ) return get_systime()-timer[id][TMR_STARTD] | ||
2194 : | else if( cflags & CF_PAUSE ) return timer[id][TMR_STARTD] | ||
2195 : | return timer[id][TMR_FINISH]-timer[id][TMR_STARTD] | ||
2196 : | ian | 1 | } |
2197 : | |||
2198 : | public hudtime( ) | ||
2199 : | {//Set clock on HUD to current climb time | ||
2200 : | if( !get_pcvar_num( p_climb ) ) return | ||
2201 : | |||
2202 : | new id, players[32], num, cltime, cflags | ||
2203 : | get_players( players, num, "ach" ) | ||
2204 : | for( new i = 0; i < num; i++ ) | ||
2205 : | { | ||
2206 : | id = players[i] | ||
2207 : | ian | 19 | cflags = timer[id][TMR_CFLAGS] |
2208 : | ian | 1 | cltime = get_climber_time(id) + 1 |
2209 : | if( cflags & CF_PAUSE ) | ||
2210 : | { | ||
2211 : | clmsg( id, "PAUSED - say '/unpause' to resume." ) | ||
2212 : | cl_pause( id ) | ||
2213 : | } | ||
2214 : | |||
2215 : | ian | 19 | if( !( cflags & CF_COUNTDOWN ) || ( timer[id][TMR_BSTTME] - get_climber_time( id ) < 0 ) ) |
2216 : | ian | 1 | hudtime_msg( id, cltime ) |
2217 : | else if( cflags & CF_PAUSE ) | ||
2218 : | ian | 19 | hudtime_msg( id, timer[id][TMR_BSTTME] - cltime + 1 ) |
2219 : | ian | 1 | |
2220 : | ian | 19 | for( new j = 1; j <= spec_ids[id][0]; j++ ) |
2221 : | hudtime_msg( spec_ids[id][j], cltime ) | ||
2222 : | ian | 1 | } |
2223 : | } | ||
2224 : | |||
2225 : | public toggle_countdown( id ) | ||
2226 : | { | ||
2227 : | //Toggle countdown flag and print message | ||
2228 : | ian | 19 | timer[id][TMR_CFLAGS] ^= CF_COUNTDOWN |
2229 : | if( timer[id][TMR_CFLAGS] & CF_COUNTDOWN ) | ||
2230 : | ian | 1 | { |
2231 : | if( set_countdown_time( id ) ) | ||
2232 : | clmsg( id, "Countdown enabled." ) | ||
2233 : | } | ||
2234 : | else | ||
2235 : | clmsg( id, "Countdown disabled." ) | ||
2236 : | } | ||
2237 : | |||
2238 : | public bool:set_countdown_time( id ) | ||
2239 : | { | ||
2240 : | ian | 19 | new bsttime = timer[id][TMR_BSTTME] |
2241 : | ian | 1 | if( bsttime > 0 ) |
2242 : | { | ||
2243 : | ian | 19 | new cflags = timer[id][TMR_CFLAGS] |
2244 : | ian | 1 | if( cflags & CF_START || cflags & CF_PAUSE ) |
2245 : | ian | 19 | hudtime_msg( id, timer[id][TMR_BSTTME] - get_climber_time( id ) ) |
2246 : | ian | 1 | return true |
2247 : | } | ||
2248 : | clmsg( id, "Countdown disabled: No high score available." ) | ||
2249 : | ian | 19 | timer[id][TMR_CFLAGS] ^= CF_COUNTDOWN |
2250 : | ian | 1 | return false |
2251 : | } | ||
2252 : | |||
2253 : | public hudtime_msg( id, cltime ) | ||
2254 : | { | ||
2255 : | message_begin( MSG_ONE, SVC_ROUNDTIME, _, id ) | ||
2256 : | write_short( cltime ) | ||
2257 : | message_end( ) | ||
2258 : | } | ||
2259 : | |||
2260 : | public getuserstatus( id ) | ||
2261 : | {//Return string describing user status | ||
2262 : | ian | 19 | new msg[12], cflags = timer[id][TMR_CFLAGS] |
2263 : | ian | 1 | msg = "PAUSED" |
2264 : | ian | 19 | if( cflags & CF_STOP && timer[id][TMR_SESFIN] > 0 ) |
2265 : | ian | 1 | msg = "Finished" |
2266 : | else if( cflags & CF_STOP ) | ||
2267 : | msg = "Not Started" | ||
2268 : | else if( cflags & CF_START ) | ||
2269 : | msg = "Climbing" | ||
2270 : | //else if( cflags & CF_PAUSE ) msg = "PAUSED" | ||
2271 : | //return "PAUSED" | ||
2272 : | return msg | ||
2273 : | } | ||
2274 : | |||
2275 : | stock clmsg( id, msg[] ) | ||
2276 : | {//Show Hud Message | ||
2277 : | set_hudmessage( get_pcvar_num( p_msg_r ), get_pcvar_num( p_msg_g ), get_pcvar_num( p_msg_b ), | ||
2278 : | get_pcvar_float( p_msg_x ), get_pcvar_float( p_msg_y ), 0, 0.0, 5.0, 0.5, 0.5, 4 ) | ||
2279 : | show_hudmessage( id, msg ) | ||
2280 : | |||
2281 : | //Show to spectators | ||
2282 : | ian | 19 | for( new i = 1; i <= spec_ids[id][0]; i++ ) |
2283 : | show_hudmessage( spec_ids[id][i], msg ) | ||
2284 : | ian | 1 | |
2285 : | return PLUGIN_HANDLED | ||
2286 : | } | ||
2287 : | //Fill spectator data array used for msg replication | ||
2288 : | public spec_update(){ | ||
2289 : | if(get_pcvar_num(p_climb)){ | ||
2290 : | new players[32],num,id,id2,i | ||
2291 : | ian | 19 | for(i=1;i<33;i++)spec_ids[i][0]=0 |
2292 : | ian | 1 | get_players(players,num,"bch") |
2293 : | for(i=0;i<num;i++){ | ||
2294 : | id=players[i] | ||
2295 : | id2=pev(id,pev_iuser2) | ||
2296 : | if(id2){ | ||
2297 : | ian | 19 | spec_ids[id2][0]++ |
2298 : | spec_ids[id2][spec_ids[id2][0]]=id | ||
2299 : | ian | 1 | } |
2300 : | } | ||
2301 : | } | ||
2302 : | return PLUGIN_HANDLED | ||
2303 : | } | ||
2304 : | //Make client solid | ||
2305 : | public solid(id) | ||
2306 : | { | ||
2307 : | set_user_rendering(id,kRenderFxNone,0,0,0,kRenderNormal,255) | ||
2308 : | entity_set_int(id,EV_INT_solid,SOLID_BBOX) | ||
2309 : | ian | 19 | sclip[id]=false |
2310 : | ian | 1 | return PLUGIN_CONTINUE |
2311 : | } | ||
2312 : | //Make client unsolid | ||
2313 : | public unsolid(id) | ||
2314 : | { | ||
2315 : | if(get_pcvar_num(p_render))set_user_rendering(id,kRenderFxHologram,0,0,0,kRenderTransAdd,0) | ||
2316 : | else set_user_rendering(id,kRenderFxPulseSlow,0,0,0,kRenderTransTexture,50) | ||
2317 : | entity_set_int(id,EV_INT_solid,SOLID_NOT) | ||
2318 : | ian | 19 | sclip[id]=true |
2319 : | ian | 1 | return PLUGIN_CONTINUE |
2320 : | } | ||
2321 : | //////////////////////////////////////////////////////////////////////////////// | ||
2322 : | // Start: Functions for use in if statements | ||
2323 : | //////////////////////////////////////////////////////////////////////////////// | ||
2324 : | public is_climber_alive( id ) | ||
2325 : | { | ||
2326 : | new movetype = pev( id, pev_movetype ) | ||
2327 : | if( movetype == MOVETYPE_WALK || movetype == MOVETYPE_FLY ) | ||
2328 : | return 1 | ||
2329 : | return 0 | ||
2330 : | } | ||
2331 : | |||
2332 : | public playersolid( id ) | ||
2333 : | { | ||
2334 : | if(entity_get_int(id,EV_INT_solid)==SOLID_BBOX)return 1 | ||
2335 : | return 0 | ||
2336 : | } | ||
2337 : | |||
2338 : | public isct(id){//Used in IF statements a lot | ||
2339 : | if(get_user_team(id)==2)return 1 | ||
2340 : | return 0 | ||
2341 : | } | ||
2342 : | |||
2343 : | public is_finished( id ) | ||
2344 : | { | ||
2345 : | ian | 19 | new cflags = timer[id][TMR_CFLAGS] |
2346 : | if( cflags & CF_STOP && ( get_user_flags( id ) & VIP || timer[id][TMR_SESFIN] > 0 ) ) | ||
2347 : | ian | 1 | return 1 |
2348 : | return 0 | ||
2349 : | } | ||
2350 : | |||
2351 : | public isalive(id){//Use in IF statements to automatically print error if false | ||
2352 : | if( is_climber_alive( id ) )return 1 | ||
2353 : | clmsg(id,"You must be alive to execute this command.") | ||
2354 : | return 0 | ||
2355 : | } | ||
2356 : | |||
2357 : | public notpaused(id){//Use in IF statements to automatically print error if false | ||
2358 : | ian | 19 | if(!(timer[id][TMR_CFLAGS]&CF_PAUSE))return 1 |
2359 : | ian | 1 | clmsg(id,"You can't execute this command while paused.") |
2360 : | return 0 | ||
2361 : | } | ||
2362 : | |||
2363 : | /*public regwarn(id){ | ||
2364 : | ian | 19 | if(timer[id][TMR_DBUSER]<1){ |
2365 : | ian | 1 | saytext(id,id,"^x04You must register/login for your stats to save. Say /climbhelp for more info.") |
2366 : | return 1 | ||
2367 : | } | ||
2368 : | return 0 | ||
2369 : | }*/ | ||
2370 : | //////////////////////////////////////////////////////////////////////////////// | ||
2371 : | // End: Functions for use in if statements | ||
2372 : | //////////////////////////////////////////////////////////////////////////////// | ||
2373 : | // Start: Auto Heal functions | ||
2374 : | //////////////////////////////////////////////////////////////////////////////// | ||
2375 : | ian | 22 | public Health( id ) |
2376 : | {//Called when client takes damage | ||
2377 : | ian | 1 | new ida[1] |
2378 : | ian | 22 | ida[0] = id |
2379 : | set_task( 0.1, "damage_handle", _, ida, 1 ) | ||
2380 : | ian | 1 | } |
2381 : | |||
2382 : | public damage_handle( ida[1] ) | ||
2383 : | {//Damage hander, delayed to provide HUD consistency | ||
2384 : | new id = ida[0] | ||
2385 : | if( get_pcvar_num( p_climb )&& is_climber_alive( id ) ) | ||
2386 : | { | ||
2387 : | new chp = get_user_health( id ) | ||
2388 : | if( chp != hp ) | ||
2389 : | { | ||
2390 : | heal( id ) | ||
2391 : | /*new wpn, atk = get_user_attacker( id, wpn ) | ||
2392 : | |||
2393 : | //Heal hp immediately | ||
2394 : | if( ( atk == 0 || ( id == atk && wpn == 0) ) && !task_exists( 50 + id ) ) | ||
2395 : | heal(id) | ||
2396 : | |||
2397 : | //Heal delayed | ||
2398 : | else | ||
2399 : | { | ||
2400 : | if( task_exists( 50 + id ) ) remove_task( 50 + id ) | ||
2401 : | set_task( 5.0, "task_heal", 50 + id, ida, 1 ) | ||
2402 : | |||
2403 : | //Fix hp display at 0 | ||
2404 : | if( chp == 256 ) set_user_health( id, 257 ) | ||
2405 : | }*/ | ||
2406 : | } | ||
2407 : | else if( task_exists( 50 + id ) ) remove_task( 50 + id ) | ||
2408 : | } | ||
2409 : | return PLUGIN_HANDLED | ||
2410 : | } | ||
2411 : | |||
2412 : | public task_heal(ida[]){//Heal client to predetermined HP required by map | ||
2413 : | heal(ida[0]) | ||
2414 : | return PLUGIN_HANDLED | ||
2415 : | } | ||
2416 : | |||
2417 : | public heal(id){ | ||
2418 : | if( is_climber_alive( id ) ) | ||
2419 : | { | ||
2420 : | if(is_finished(id))set_user_health(id,511) | ||
2421 : | else if(hp)set_user_health(id,hp) | ||
2422 : | else if(get_user_health(id)>100)set_user_health(id,100) | ||
2423 : | } | ||
2424 : | } | ||
2425 : | //////////////////////////////////////////////////////////////////////////////// | ||
2426 : | // End: Auto Heal functions | ||
2427 : | //////////////////////////////////////////////////////////////////////////////// | ||
2428 : | // Start: Multiplay Bunny Hop functions | ||
2429 : | //////////////////////////////////////////////////////////////////////////////// | ||
2430 : | public pfn_touch( ent, id ) | ||
2431 : | { | ||
2432 : | if( !get_pcvar_num( p_climb ) ) | ||
2433 : | return PLUGIN_CONTINUE | ||
2434 : | |||
2435 : | //Clean up dropped stuff | ||
2436 : | new str[21] | ||
2437 : | entity_get_string( ent, EV_SZ_classname, str, 20 ) | ||
2438 : | if( equal( str, "weaponbox" ) || equal( str, "item_thighpack" ) ) | ||
2439 : | { | ||
2440 : | remove_entity( ent ) | ||
2441 : | return PLUGIN_HANDLED | ||
2442 : | } | ||
2443 : | if( pev_valid( id ) ) | ||
2444 : | { | ||
2445 : | entity_get_string( id, EV_SZ_classname, str, 20 ) | ||
2446 : | if( equal( str, "weaponbox" ) || equal( str, "item_thighpack" ) ) | ||
2447 : | { | ||
2448 : | remove_entity( id ) | ||
2449 : | return PLUGIN_HANDLED | ||
2450 : | } | ||
2451 : | } | ||
2452 : | else return PLUGIN_HANDLED | ||
2453 : | |||
2454 : | if ( !ent || !id ) | ||
2455 : | return PLUGIN_CONTINUE | ||
2456 : | |||
2457 : | //Make sure id is player and ent is object | ||
2458 : | if( 0 < ent <= MAXPLAYERS ) | ||
2459 : | { | ||
2460 : | new tmp = id | ||
2461 : | id = ent | ||
2462 : | ent = tmp | ||
2463 : | } | ||
2464 : | else if( !( 0 < id <= MAXPLAYERS ) ) | ||
2465 : | return PLUGIN_CONTINUE | ||
2466 : | |||
2467 : | //Bhop stuff | ||
2468 : | new dpos = door_in_array( ent ) | ||
2469 : | if( dpos > -1 ) | ||
2470 : | { | ||
2471 : | //Finished can stand on bhop blocks | ||
2472 : | if( is_finished( id ) ) | ||
2473 : | return PLUGIN_HANDLED | ||
2474 : | |||
2475 : | ian | 19 | if( bhop_failid[id] != ent ) |
2476 : | ian | 1 | { |
2477 : | ian | 19 | bhop_failid[id] = ent |
2478 : | bhop_fail[id] = false | ||
2479 : | ian | 1 | |
2480 : | new tskid = TSK_BHOP + id | ||
2481 : | if( task_exists( tskid ) ) | ||
2482 : | remove_task( tskid ) | ||
2483 : | set_task( 0.2, "bhop_set_fail", tskid ) | ||
2484 : | tskid = TSK_CLEAR_FAIL + id | ||
2485 : | if( task_exists( tskid ) ) | ||
2486 : | remove_task( tskid ) | ||
2487 : | set_task( 0.7, "bhop_clear_fail", tskid ) | ||
2488 : | } | ||
2489 : | ian | 19 | else if( bhop_fail[id] ) |
2490 : | ian | 1 | { |
2491 : | teleport( id, door_tp_pos[dpos] ) | ||
2492 : | ian | 19 | bhop_failid[id] = 0 |
2493 : | bhop_fail[id] = false | ||
2494 : | ian | 1 | } |
2495 : | return PLUGIN_HANDLED | ||
2496 : | } | ||
2497 : | |||
2498 : | return PLUGIN_CONTINUE | ||
2499 : | } | ||
2500 : | |||
2501 : | public door_in_array( door ) | ||
2502 : | { | ||
2503 : | for( new i = 0; i < door_count; i++ ) | ||
2504 : | if( func_doors[i][0] == door ) | ||
2505 : | return i | ||
2506 : | return -1 | ||
2507 : | } | ||
2508 : | |||
2509 : | public bhop_set_fail( tskid ) | ||
2510 : | { | ||
2511 : | ian | 19 | bhop_fail[tskid-TSK_BHOP] = true |
2512 : | ian | 1 | return PLUGIN_HANDLED |
2513 : | } | ||
2514 : | |||
2515 : | public bhop_clear_fail( tskid ) | ||
2516 : | { | ||
2517 : | new id = tskid - TSK_CLEAR_FAIL | ||
2518 : | ian | 19 | bhop_failid[id] = 0 |
2519 : | bhop_fail[id] = false | ||
2520 : | ian | 1 | return PLUGIN_HANDLED |
2521 : | } | ||
2522 : | |||
2523 : | //////////////////////////////////////////////////////////////////////////////// | ||
2524 : | // End: Multiplay Bunny Hop functions | ||
2525 : | //////////////////////////////////////////////////////////////////////////////// | ||
2526 : | |||
2527 : | /*public spawn_distance_sort(elem1[],elem2[]){ | ||
2528 : | if(elem1[1]<elem2[1])return -1 | ||
2529 : | if(elem1[1]>elem2[1])return 1 | ||
2530 : | return 0 | ||
2531 : | }*/ | ||
2532 : | |||
2533 : | //Future use, to block hook, or detect hook cheaters a.k.a. hookers | ||
2534 : | public phook( id ) | ||
2535 : | { | ||
2536 : | hooked[id] = 1 | ||
2537 : | return PLUGIN_CONTINUE | ||
2538 : | } | ||
2539 : | |||
2540 : | public mhook( id ) | ||
2541 : | { | ||
2542 : | hooked[id] = 0 | ||
2543 : | return PLUGIN_CONTINUE | ||
2544 : | } | ||
2545 : | |||
2546 : | //////////////////////////////////////////////////////////////////////////////// | ||
2547 : | // Start: Flashlight functions | ||
2548 : | //////////////////////////////////////////////////////////////////////////////// | ||
2549 : | public flight_icons( id ) | ||
2550 : | { | ||
2551 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_LIGHT_ON ) |
2552 : | ian | 1 | { |
2553 : | if( !task_exists( TSK_FLIGHT + id ) ) | ||
2554 : | set_task( 0.1, "flight_msg", TSK_FLIGHT + id, _, _, "b" ) | ||
2555 : | |||
2556 : | message_begin( MSG_ONE, SVC_FLASHLIGHT, _, id ) | ||
2557 : | write_byte( 1 ) | ||
2558 : | write_byte( 100 ) | ||
2559 : | message_end( ) | ||
2560 : | |||
2561 : | message_begin( MSG_ONE, SVC_STATUSICON, _, id ) | ||
2562 : | write_byte( 1 ) //on | ||
2563 : | write_string( "flash_beam" ) | ||
2564 : | write_byte( get_pcvar_num( p_light_r ) ) //r | ||
2565 : | write_byte( get_pcvar_num( p_light_g ) ) //g | ||
2566 : | write_byte( get_pcvar_num( p_light_b ) ) //b | ||
2567 : | message_end( ) | ||
2568 : | } | ||
2569 : | else | ||
2570 : | { | ||
2571 : | message_begin( MSG_ONE, SVC_FLASHLIGHT, _, id ) | ||
2572 : | write_byte( 0 ) | ||
2573 : | write_byte( 100 ) | ||
2574 : | message_end( ) | ||
2575 : | |||
2576 : | message_begin( MSG_ONE, SVC_STATUSICON, _, id ) | ||
2577 : | write_byte( 0 ) //off | ||
2578 : | write_string( "flash_beam" ) | ||
2579 : | message_end( ) | ||
2580 : | } | ||
2581 : | } | ||
2582 : | public tog_flight(id){ | ||
2583 : | if(!get_pcvar_num(p_climb))return PLUGIN_CONTINUE | ||
2584 : | ian | 19 | if(!(timer[id][TMR_CFLAGS]&CF_LIGHT_ON)){ |
2585 : | timer[id][TMR_CFLAGS]+=CF_LIGHT_ON | ||
2586 : | ian | 1 | set_task(0.1,"flight_msg",TSK_FLIGHT+id,_,_,"b") |
2587 : | } | ||
2588 : | ian | 19 | else timer[id][TMR_CFLAGS]-=CF_LIGHT_ON |
2589 : | ian | 1 | flight_icons(id) |
2590 : | return PLUGIN_HANDLED | ||
2591 : | } | ||
2592 : | |||
2593 : | public flight_msg(tskid){ | ||
2594 : | if(get_pcvar_num(p_climb)){ | ||
2595 : | new orig[3],id=tskid-TSK_FLIGHT | ||
2596 : | ian | 19 | if(!(timer[id][TMR_CFLAGS]&CF_LIGHT_ON))remove_task(tskid) |
2597 : | ian | 1 | get_user_origin(id,orig) |
2598 : | message_begin(MSG_ONE_UNRELIABLE,SVC_TEMPENTITY,_,id) | ||
2599 : | write_byte(TE_DLIGHT) | ||
2600 : | write_coord(orig[0])//x | ||
2601 : | write_coord(orig[1])//y | ||
2602 : | write_coord(orig[2])//z | ||
2603 : | write_byte(60)//radius | ||
2604 : | write_byte(get_pcvar_num(p_light_r))//r | ||
2605 : | write_byte(get_pcvar_num(p_light_g))//g | ||
2606 : | write_byte(get_pcvar_num(p_light_b))//b | ||
2607 : | write_byte(4)//life | ||
2608 : | write_byte(2)//decay | ||
2609 : | message_end() | ||
2610 : | } | ||
2611 : | return PLUGIN_HANDLED | ||
2612 : | } | ||
2613 : | //////////////////////////////////////////////////////////////////////////////// | ||
2614 : | // End: Flashlight functions | ||
2615 : | //////////////////////////////////////////////////////////////////////////////// | ||
2616 : | public teleport( id, Float:orig[3] ) | ||
2617 : | {//Used to teleport clients, prevents client collisions and getting stuck | ||
2618 : | //Don't tp if vector is all zeros | ||
2619 : | if( !( orig[0] || orig[1] || orig[2] ) ) return 0 | ||
2620 : | |||
2621 : | new Float:c2[3], player, players[32], num | ||
2622 : | get_players( players, num, "ac" ) | ||
2623 : | unsolid( id ) | ||
2624 : | for( new i = 0; i < num; i++ ) | ||
2625 : | { | ||
2626 : | player = players[i] | ||
2627 : | if( id != player ) | ||
2628 : | { | ||
2629 : | entity_get_vector( player, EV_VEC_origin, c2 ) | ||
2630 : | if( vector_distance( orig, c2 ) < 90 ) unsolid( player ) | ||
2631 : | } | ||
2632 : | } | ||
2633 : | entity_set_vector( id, EV_VEC_velocity, Float:{0.0, 0.0, 0.0} ) | ||
2634 : | entity_set_vector( id, EV_VEC_origin, orig ) | ||
2635 : | delay_duck( id ) | ||
2636 : | return 1 | ||
2637 : | } | ||
2638 : | |||
2639 : | public delay_duck(id){//Used by teleport and timer start respawn, prevents getting stuck | ||
2640 : | new ida[1] | ||
2641 : | ida[0]=id | ||
2642 : | set_task(0.01,"force_duck",_,ida,1) | ||
2643 : | set_entity_flags(ida[0],FL_DUCKING,1) | ||
2644 : | } | ||
2645 : | |||
2646 : | public force_duck(ida[1]){//Task for delay_duck | ||
2647 : | set_entity_flags(ida[0],FL_DUCKING,1) | ||
2648 : | } | ||
2649 : | |||
2650 : | public cvar_enabled(id,p_cvar){//Used in IF statements to automatically print error if false | ||
2651 : | if(get_pcvar_num(p_cvar)==0){ | ||
2652 : | clmsg(id,"This command is disabled.") | ||
2653 : | client_print(id,print_chat,"This command has been disabled by the server administrator.") | ||
2654 : | return 0 | ||
2655 : | } | ||
2656 : | return 1 | ||
2657 : | } | ||
2658 : | //////////////////////////////////////////////////////////////////////////////// | ||
2659 : | // Start: Climb command handling functions | ||
2660 : | //////////////////////////////////////////////////////////////////////////////// | ||
2661 : | |||
2662 : | public sunglasses( id ) | ||
2663 : | { | ||
2664 : | //Toggle flag for this measure and print message | ||
2665 : | ian | 19 | timer[id][TMR_CFLAGS] ^= CF_SUNGLASSES |
2666 : | if( timer[id][TMR_CFLAGS] & CF_SUNGLASSES ) | ||
2667 : | ian | 1 | { |
2668 : | message_begin( MSG_ONE, SVC_SCREENFADE, _, id ) | ||
2669 : | write_short( 1 ) //total duration | ||
2670 : | write_short( 0 ) //time it stays one color | ||
2671 : | write_short( 5 ) //fade type | ||
2672 : | write_byte( 0 ) //r | ||
2673 : | write_byte( 0 ) //g | ||
2674 : | write_byte( 0 ) //b | ||
2675 : | write_byte( 127 ) //a | ||
2676 : | message_end( ) | ||
2677 : | } | ||
2678 : | else | ||
2679 : | { | ||
2680 : | message_begin( MSG_ONE, SVC_SCREENFADE, _, id ) | ||
2681 : | write_short( 1 ) //total duration | ||
2682 : | write_short( 0 ) //time it stays one color | ||
2683 : | write_short( 0 ) //fade type | ||
2684 : | write_byte( 0 ) //r | ||
2685 : | write_byte( 0 ) //g | ||
2686 : | write_byte( 0 ) //b | ||
2687 : | write_byte( 127 ) //a | ||
2688 : | message_end( ) | ||
2689 : | } | ||
2690 : | } | ||
2691 : | |||
2692 : | public give_scout( id ) | ||
2693 : | ian | 19 | if( !check_timeout( id, time_stamps[id][TS_WPN], WPN_TIMEOUT ) ) |
2694 : | ian | 1 | give_item( id, "weapon_scout" ) |
2695 : | |||
2696 : | public give_usp( id ) | ||
2697 : | ian | 19 | if( !check_timeout( id, time_stamps[id][TS_WPN], WPN_TIMEOUT ) ) |
2698 : | ian | 1 | give_item( id, "weapon_usp" ) |
2699 : | |||
2700 : | public give_weapons( id ) | ||
2701 : | ian | 19 | if( !check_timeout( id, time_stamps[id][TS_WPN], WPN_TIMEOUT ) ) |
2702 : | ian | 1 | { |
2703 : | give_item( id, "weapon_awp" ) | ||
2704 : | give_item( id, "weapon_m249" ) | ||
2705 : | give_item( id, "weapon_m4a1" ) | ||
2706 : | give_item( id, "weapon_sg552" ) | ||
2707 : | give_item( id, "weapon_famas" ) | ||
2708 : | give_item( id, "weapon_p90" ) | ||
2709 : | give_item( id, "weapon_usp" ) | ||
2710 : | give_item( id, "weapon_scout" ) | ||
2711 : | } | ||
2712 : | |||
2713 : | |||
2714 : | public help_msg(id) | ||
2715 : | { | ||
2716 : | client_print( id, print_chat, "Say /climbhelp to get help with the Climb kz plugin." ) | ||
2717 : | return PLUGIN_CONTINUE | ||
2718 : | } | ||
2719 : | |||
2720 : | public climb_help(id) | ||
2721 : | if( get_pcvar_num( p_climb ) ) | ||
2722 : | show_motd( id, "http://ian.cammarata.us/projects/climb/help/2a3/en/commands?agent=hl", "Climb Plugin Help" ) | ||
2723 : | |||
2724 : | public boost_help(id) | ||
2725 : | if( get_pcvar_num( p_climb ) ) | ||
2726 : | show_motd( id, "http://ian.cammarata.us/projects/climb/help/2a3/en/boosts?agent=hl", "Climb Plugin Help" ) | ||
2727 : | |||
2728 : | public goto_player( id ) | ||
2729 : | {//Admin command, teleport to client | ||
2730 : | if( is_finished( id ) && get_pcvar_num( p_climb ) ) | ||
2731 : | { | ||
2732 : | new tid, arg[24] | ||
2733 : | read_argv( 1, arg, sizeof( arg ) - 1 ) | ||
2734 : | tid = cmd_target( tid, arg, 4 ) | ||
2735 : | if( tid ) | ||
2736 : | { | ||
2737 : | new Float:orig[3] | ||
2738 : | entity_get_vector( tid, EV_VEC_origin, orig ) | ||
2739 : | teleport( id, orig ) | ||
2740 : | } | ||
2741 : | } | ||
2742 : | return PLUGIN_HANDLED | ||
2743 : | } | ||
2744 : | |||
2745 : | public spectate( id ) | ||
2746 : | {//Client switch to spectator | ||
2747 : | if( get_pcvar_num( p_climb ) && !is_user_bot( id ) && !is_user_hltv( id ) ) | ||
2748 : | { | ||
2749 : | if( !is_climber_alive( id ) ) | ||
2750 : | { | ||
2751 : | /* | ||
2752 : | cs_set_user_team(id,3)//fixes respawn bug? | ||
2753 : | frespawn( id ) | ||
2754 : | */ | ||
2755 : | |||
2756 : | climb_user_spawn( id ) | ||
2757 : | |||
2758 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_PAUSE ) |
2759 : | ian | 1 | {//If they are paused tp to pause spot and freeze them again. |
2760 : | new Float:coords[3] | ||
2761 : | for( new i=0; i<3; i++ ) coords[i] = origins[ id - 1 ][ ORIG_PAUS + i ] | ||
2762 : | teleport( id, coords ) | ||
2763 : | cl_pause( id ) | ||
2764 : | } | ||
2765 : | |||
2766 : | } | ||
2767 : | else if( get_user_flags( id ) & VIP ? 1 : ( cvar_enabled( id, p_allow_spectators ) ) ) | ||
2768 : | { | ||
2769 : | //Move client way outside the map so we don't have to see their retarded model | ||
2770 : | new Float:orig[3] | ||
2771 : | entity_get_vector( id, EV_VEC_origin, orig ) | ||
2772 : | entity_set_vector( id, EV_VEC_origin, Float:{ 99999.9, 99999.9, 99999.9 } ) | ||
2773 : | |||
2774 : | //Set a task to move them back to where they were originally | ||
2775 : | new ida[4] | ||
2776 : | ida[0] = id | ||
2777 : | ida[1] = _:orig[0] | ||
2778 : | ida[2] = _:orig[1] | ||
2779 : | ida[3] = _:orig[2] | ||
2780 : | set_task( 0.1, "tsk_spec_tp_back", _, ida, 4 ) | ||
2781 : | |||
2782 : | set_pev( id, pev_movetype, MOVETYPE_NOCLIP ) | ||
2783 : | set_pev( id, pev_solid, SOLID_NOT ) | ||
2784 : | set_pev( id, pev_effects, EF_NODRAW ) | ||
2785 : | set_pev( id, pev_deadflag, DEAD_DEAD ) | ||
2786 : | set_pev( id, pev_takedamage, DAMAGE_NO ) | ||
2787 : | set_entity_flags( id, FL_FROZEN, 0 ) | ||
2788 : | |||
2789 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_START ) change_status( id, CF_PAUSE ) |
2790 : | ian | 1 | } |
2791 : | return PLUGIN_HANDLED | ||
2792 : | } | ||
2793 : | return PLUGIN_CONTINUE | ||
2794 : | } | ||
2795 : | |||
2796 : | public tsk_spec_tp_back( ida[4] ) | ||
2797 : | { | ||
2798 : | new Float:orig[3] | ||
2799 : | orig[0] = Float:ida[1] | ||
2800 : | orig[1] = Float:ida[2] | ||
2801 : | orig[2] = Float:ida[3] | ||
2802 : | entity_set_vector( ida[0], EV_VEC_origin, orig ) | ||
2803 : | } | ||
2804 : | |||
2805 : | public client_command( id ) | ||
2806 : | {//Forward to catch all formats for commands | ||
2807 : | if(!get_pcvar_num(p_climb)) | ||
2808 : | return PLUGIN_CONTINUE | ||
2809 : | new cmd[21] | ||
2810 : | read_argv(0,cmd,20) | ||
2811 : | |||
2812 : | //If say command, trim "say", abort if more than one word | ||
2813 : | if(equal(cmd,"say")||equal(cmd,"say_team")){ | ||
2814 : | read_argv(1,cmd,20) | ||
2815 : | trim(cmd) | ||
2816 : | if(contain(cmd," ")>-1)return PLUGIN_CONTINUE | ||
2817 : | } | ||
2818 : | |||
2819 : | //Remove slashes | ||
2820 : | if( equal(cmd,"/",1) || equal(cmd,"\",1) || equal(cmd,".",1) || equal(cmd,"!",1) ) | ||
2821 : | copy(cmd,20,cmd[1]) | ||
2822 : | |||
2823 : | //Make a checkpoint | ||
2824 : | if( equali(cmd,"checkpoint") || equali(cmd,"check") || equali(cmd,"cp") ) | ||
2825 : | check(id) | ||
2826 : | |||
2827 : | //Go to checkpoint | ||
2828 : | else if( equali(cmd,"gocheck") || equali(cmd,"gc") || equali(cmd,"tp") || equali(cmd,"tele") ) | ||
2829 : | gocheck(id) | ||
2830 : | |||
2831 : | //Ungocheck | ||
2832 : | else if( equali(cmd,"ungc") || equali(cmd,"ungocheck") ) | ||
2833 : | ungocheck(id) | ||
2834 : | |||
2835 : | //Boost help page | ||
2836 : | else if( equali(cmd,"boost") ) | ||
2837 : | boost_help(id) | ||
2838 : | |||
2839 : | //Solid Boost | ||
2840 : | else if( equali(cmd,"solid") || equali(cmd,"semiclip") ) | ||
2841 : | change_boost(id,CF_SOLID) | ||
2842 : | |||
2843 : | //Jump Boost | ||
2844 : | else if( equali(cmd,"superjump") || equali(cmd,"sjump") || equali(cmd,"sj") || equali(cmd,"longjump") ||\ | ||
2845 : | equali(cmd,"ljump") || equali(cmd,"lj") ) | ||
2846 : | change_boost(id,CF_SUPER_JUMP) | ||
2847 : | |||
2848 : | //Double Jump Boost | ||
2849 : | else if( equali(cmd,"doublejump") || equali(cmd,"djump") || equali(cmd,"dj") ) | ||
2850 : | change_boost(id,CF_DOUBLE_JUMP) | ||
2851 : | |||
2852 : | //Cycle CPs reverse | ||
2853 : | else if( equali(cmd,"cp-") || equali(cmd,"stuck") || equali(cmd,"unstuck") ) | ||
2854 : | { | ||
2855 : | cp_back( id ) | ||
2856 : | return PLUGIN_CONTINUE | ||
2857 : | } | ||
2858 : | |||
2859 : | //Cycle CPs forward | ||
2860 : | else if( equali(cmd,"cp+") ) | ||
2861 : | { | ||
2862 : | cp_forward( id ) | ||
2863 : | return PLUGIN_CONTINUE | ||
2864 : | } | ||
2865 : | |||
2866 : | //Pause | ||
2867 : | else if( equali(cmd,"pause") || equali(cmd,"unpause") ) | ||
2868 : | change_status(id,CF_PAUSE) | ||
2869 : | |||
2870 : | //Stop | ||
2871 : | else if( equali(cmd,"stop") ) | ||
2872 : | stop(id) | ||
2873 : | |||
2874 : | //Time/Scores | ||
2875 : | else if( equali(cmd,"scoreboard") || equali(cmd,"score") || equali(cmd,"scores") ) | ||
2876 : | climbscores(id) | ||
2877 : | |||
2878 : | //High Scores | ||
2879 : | else if( equali(cmd,"top10") || equali(cmd,"top15") || equali(cmd,"top") || equali(cmd,"highscores") ||\ | ||
2880 : | equali(cmd,"best") || equali(cmd,"rank") || equali(cmd,"pro15") || equali(cmd,"nub15") ) | ||
2881 : | highscores(id) | ||
2882 : | |||
2883 : | //Respawn | ||
2884 : | else if( equali( cmd, "respawn" ) || equali( cmd, "spawn" ) ) | ||
2885 : | frespawn( id ) | ||
2886 : | |||
2887 : | //TP to start button | ||
2888 : | else if( equali( cmd, "restart" ) || equali( cmd, "start" ) || equali( cmd, "reset" ) ) | ||
2889 : | tp_start_btn( id ) | ||
2890 : | |||
2891 : | //Spectate | ||
2892 : | else if( equali(cmd,"spectate") || equali(cmd,"spec") ) | ||
2893 : | spectate(id) | ||
2894 : | |||
2895 : | //Get scout | ||
2896 : | else if( equali( cmd, "scout" ) ) | ||
2897 : | give_scout( id ) | ||
2898 : | |||
2899 : | //Get usp | ||
2900 : | else if( equali( cmd, "usp" ) ) | ||
2901 : | give_usp( id ) | ||
2902 : | |||
2903 : | else if( equali( cmd, "weapons" ) ) | ||
2904 : | { | ||
2905 : | give_weapons( id ) | ||
2906 : | return PLUGIN_CONTINUE | ||
2907 : | } | ||
2908 : | |||
2909 : | else if( equali( cmd, "measure" ) ) | ||
2910 : | { | ||
2911 : | toggle_measure( id ) | ||
2912 : | return PLUGIN_CONTINUE | ||
2913 : | } | ||
2914 : | |||
2915 : | else if( equali( cmd, "measure2" ) ) | ||
2916 : | { | ||
2917 : | toggle_measure2( id ) | ||
2918 : | return PLUGIN_CONTINUE | ||
2919 : | } | ||
2920 : | |||
2921 : | else if( equali( cmd, "countdown" ) || equali( cmd, "countup" ) ) | ||
2922 : | { | ||
2923 : | toggle_countdown( id ) | ||
2924 : | return PLUGIN_CONTINUE | ||
2925 : | } | ||
2926 : | |||
2927 : | else if( equali( cmd, "sunglasses" ) ) | ||
2928 : | { | ||
2929 : | sunglasses( id ) | ||
2930 : | return PLUGIN_CONTINUE | ||
2931 : | } | ||
2932 : | |||
2933 : | //Climb Help | ||
2934 : | else if( equali( cmd, "climbhelp" ) || equali( cmd, "kzhelp" ) ) | ||
2935 : | climb_help( id ) | ||
2936 : | |||
2937 : | //If none of above conditions met, don't block the command | ||
2938 : | else return PLUGIN_CONTINUE | ||
2939 : | return PLUGIN_HANDLED | ||
2940 : | } | ||
2941 : | |||
2942 : | //////////////////////////////////////////////////////////////////////////////// | ||
2943 : | // End: Climb command handling functions | ||
2944 : | //////////////////////////////////////////////////////////////////////////////// | ||
2945 : | // Start: Measure functions | ||
2946 : | //////////////////////////////////////////////////////////////////////////////// | ||
2947 : | |||
2948 : | public toggle_measure( id ) | ||
2949 : | { | ||
2950 : | //Remove flag for other measure | ||
2951 : | ian | 19 | new cflags = timer[id][TMR_CFLAGS] |
2952 : | if( cflags & CF_MEASURE2 ) timer[id][TMR_CFLAGS] = cflags & ~CF_MEASURE2 | ||
2953 : | ian | 1 | |
2954 : | //Toggle flag for this measure and print message | ||
2955 : | ian | 19 | timer[id][TMR_CFLAGS] ^= CF_MEASURE |
2956 : | ian | 1 | if( cflags & CF_MEASURE ) |
2957 : | clmsg( id, "Measure disabled." ) | ||
2958 : | else | ||
2959 : | clmsg( id, "Measure enabled, use attack to measure." ) | ||
2960 : | } | ||
2961 : | |||
2962 : | public do_measure( id ) | ||
2963 : | { | ||
2964 : | new Float:orig[3], Float:look[3], Float:end[3], Float:ret[3] | ||
2965 : | new Float:ln_st[3], Float:ln_fn[3] | ||
2966 : | |||
2967 : | entity_get_vector( id, EV_VEC_origin, orig ) | ||
2968 : | entity_get_vector( id, EV_VEC_view_ofs, ret ) | ||
2969 : | for( new i = 0; i < 3; i++ ) orig[i] += ret[i] | ||
2970 : | |||
2971 : | velocity_by_aim( id, 1, ret ) | ||
2972 : | for( new i = 0; i < 3; i++ ) end[i] = orig[i] + ( ret[i] * 9999 ) | ||
2973 : | |||
2974 : | trace_line( id, orig, end, ln_st ) | ||
2975 : | trace_normal( id, orig, end, look ) | ||
2976 : | |||
2977 : | for( new i = 0; i < 3; i++ ) end[i] = ln_st[i] + ( look[i] * 9999 ) | ||
2978 : | |||
2979 : | trace_line( id, ln_st, end, ln_fn ) | ||
2980 : | |||
2981 : | end[0] = ln_st[0] + ( ret[0] * -9999 ) | ||
2982 : | end[1] = ln_st[1] + ( ret[1] * -9999 ) | ||
2983 : | end[2] = ln_st[2] | ||
2984 : | |||
2985 : | trace_line( id, ln_st, end, orig ) | ||
2986 : | |||
2987 : | new msg[101] | ||
2988 : | format( msg, 100, "Distance: red %d / blue %d", | ||
2989 : | floatround( vector_distance( ln_st, ln_fn ), floatround_ceil ), | ||
2990 : | floatround( vector_distance( ln_st, orig ), floatround_ceil ) ) | ||
2991 : | clmsg( id, msg ) | ||
2992 : | console_print( id, msg ) | ||
2993 : | |||
2994 : | message_begin( MSG_ONE, SVC_TEMPENTITY, _, id ) | ||
2995 : | write_byte( TE_BEAMPOINTS ) | ||
2996 : | write_coord( floatround( ln_st[0] ) ) | ||
2997 : | write_coord( floatround( ln_st[1] ) ) | ||
2998 : | write_coord( floatround( ln_st[2] ) ) | ||
2999 : | write_coord( floatround( ln_fn[0] ) ) | ||
3000 : | write_coord( floatround( ln_fn[1] ) ) | ||
3001 : | write_coord( floatround( ln_fn[2] ) ) | ||
3002 : | write_short( beam_sprite ) // sprite index | ||
3003 : | write_byte( 0 ) // starting frame | ||
3004 : | write_byte( 10 ) // frame rate in 0.1's | ||
3005 : | write_byte( 100 ) // life in 0.1's | ||
3006 : | write_byte( 10 ) // line width in 0.1's | ||
3007 : | write_byte( 2 ) // noise amplitude in 0.01's | ||
3008 : | write_byte( 255 ) // Red | ||
3009 : | write_byte( 0 ) // Green | ||
3010 : | write_byte( 0 ) // Blue | ||
3011 : | write_byte( 127 ) // brightness | ||
3012 : | write_byte( 50 ) // scroll speed in 0.1's | ||
3013 : | message_end( ) | ||
3014 : | |||
3015 : | message_begin( MSG_ONE, SVC_TEMPENTITY, _, id ) | ||
3016 : | write_byte( TE_BEAMPOINTS ) | ||
3017 : | write_coord( floatround( ln_st[0] ) ) | ||
3018 : | write_coord( floatround( ln_st[1] ) ) | ||
3019 : | write_coord( floatround( ln_st[2] ) ) | ||
3020 : | write_coord( floatround( orig[0] ) ) | ||
3021 : | write_coord( floatround( orig[1] ) ) | ||
3022 : | write_coord( floatround( orig[2] ) ) | ||
3023 : | write_short( beam_sprite ) // sprite index | ||
3024 : | write_byte( 0 ) // starting frame | ||
3025 : | write_byte( 10 ) // frame rate in 0.1's | ||
3026 : | write_byte( 100 ) // life in 0.1's | ||
3027 : | write_byte( 10 ) // line width in 0.1's | ||
3028 : | write_byte( 2 ) // noise amplitude in 0.01's | ||
3029 : | write_byte( 0 ) // Red | ||
3030 : | write_byte( 0 ) // Green | ||
3031 : | write_byte( 255 ) // Blue | ||
3032 : | write_byte( 127 ) // brightness | ||
3033 : | write_byte( 50 ) // scroll speed in 0.1's | ||
3034 : | message_end( ) | ||
3035 : | } | ||
3036 : | |||
3037 : | public toggle_measure2( id ) | ||
3038 : | { | ||
3039 : | //Remove flag for other measure | ||
3040 : | ian | 19 | new cflags = timer[id][TMR_CFLAGS] |
3041 : | if( cflags & CF_MEASURE ) timer[id][TMR_CFLAGS] = cflags & ~CF_MEASURE | ||
3042 : | ian | 1 | |
3043 : | //Toggle flag for this measure and print message | ||
3044 : | ian | 19 | timer[id][TMR_CFLAGS] ^= CF_MEASURE2 |
3045 : | ian | 1 | if( cflags & CF_MEASURE2 ) |
3046 : | clmsg( id, "Measure 2 disabled." ) | ||
3047 : | else | ||
3048 : | clmsg( id, "Measure 2 enabled, use attack to measure." ) | ||
3049 : | } | ||
3050 : | |||
3051 : | public tsk_do_measure2( tskid ) | ||
3052 : | do_measure2( tskid - TSK_MEASURE2 ) | ||
3053 : | |||
3054 : | stock do_measure2( id, set = 0 ) | ||
3055 : | { | ||
3056 : | new tskid = TSK_MEASURE2 + id | ||
3057 : | |||
3058 : | ian | 19 | static Float:ln_st_static[33][3] |
3059 : | ian | 1 | |
3060 : | new Float:orig[3], Float:ret[3], Float:end[3] | ||
3061 : | |||
3062 : | entity_get_vector( id, EV_VEC_origin, orig ) | ||
3063 : | entity_get_vector( id, EV_VEC_view_ofs, ret ) | ||
3064 : | for( new i = 0; i < 3; i++ ) orig[i] += ret[i] | ||
3065 : | |||
3066 : | velocity_by_aim( id, 1, ret ) | ||
3067 : | |||
3068 : | for( new i = 0; i < 3; i++ ) end[i] = orig[i] + ( ret[i] * 9999 ) | ||
3069 : | trace_line( id, orig, end, ret ) | ||
3070 : | |||
3071 : | new Float:ln_st[3] | ||
3072 : | ian | 19 | ln_st = ln_st_static[id] |
3073 : | ian | 1 | |
3074 : | //If first iteration, save point to static and return | ||
3075 : | if( !( ln_st[0] || ln_st[0] || ln_st[0] ) ) | ||
3076 : | { | ||
3077 : | ian | 19 | ln_st_static[id] = ret |
3078 : | ian | 1 | set_task( 0.1, "tsk_do_measure2", tskid, _, _, "b" ) |
3079 : | return | ||
3080 : | } | ||
3081 : | |||
3082 : | new Float:ln_fn[3], Float:ln_stmid[3], Float:ln_fnmid[3] | ||
3083 : | ln_fn = ret | ||
3084 : | |||
3085 : | ln_stmid[0] = ln_st[0] | ||
3086 : | ln_stmid[1] = ln_st[1] | ||
3087 : | ln_stmid[2] = ln_fn[2] | ||
3088 : | |||
3089 : | ln_fnmid[0] = ln_fn[0] | ||
3090 : | ln_fnmid[1] = ln_st[1] | ||
3091 : | ln_fnmid[2] = ln_fn[2] | ||
3092 : | |||
3093 : | new msg[101] | ||
3094 : | format( msg, 100, "Distance: r %d / g %d / b %d", | ||
3095 : | floatround( vector_distance( ln_st, ln_stmid ), floatround_ceil ), | ||
3096 : | floatround( vector_distance( ln_stmid, ln_fnmid ), floatround_ceil ), | ||
3097 : | floatround( vector_distance( ln_fnmid, ln_fn ), floatround_ceil ) ) | ||
3098 : | clmsg( id, msg ) | ||
3099 : | |||
3100 : | new life = 1, dest = MSG_ONE_UNRELIABLE | ||
3101 : | if( set ) | ||
3102 : | { | ||
3103 : | life = 125 | ||
3104 : | dest = MSG_ONE | ||
3105 : | console_print( id, msg ) | ||
3106 : | } | ||
3107 : | |||
3108 : | message_begin( dest, SVC_TEMPENTITY, _, id ) | ||
3109 : | write_byte( TE_BEAMPOINTS ) | ||
3110 : | write_coord( floatround( ln_st[0] ) ) | ||
3111 : | write_coord( floatround( ln_st[1] ) ) | ||
3112 : | write_coord( floatround( ln_st[2] ) ) | ||
3113 : | write_coord( floatround( ln_stmid[0] ) ) | ||
3114 : | write_coord( floatround( ln_stmid[1] ) ) | ||
3115 : | write_coord( floatround( ln_stmid[2] ) ) | ||
3116 : | write_short( beam_sprite ) // sprite index | ||
3117 : | write_byte( 0 ) // starting frame | ||
3118 : | write_byte( 10 ) // frame rate in 0.1's | ||
3119 : | write_byte( life ) // life in 0.1's | ||
3120 : | write_byte( 10 ) // line width in 0.1's | ||
3121 : | write_byte( 2 ) // noise amplitude in 0.01's | ||
3122 : | write_byte( 255 ) // Red | ||
3123 : | write_byte( 0 ) // Green | ||
3124 : | write_byte( 0 ) // Blue | ||
3125 : | write_byte( 127 ) // brightness | ||
3126 : | write_byte( 50 ) // scroll speed in 0.1's | ||
3127 : | message_end( ) | ||
3128 : | |||
3129 : | message_begin( dest, SVC_TEMPENTITY, _, id ) | ||
3130 : | write_byte( TE_BEAMPOINTS ) | ||
3131 : | write_coord( floatround( ln_stmid[0] ) ) | ||
3132 : | write_coord( floatround( ln_stmid[1] ) ) | ||
3133 : | write_coord( floatround( ln_stmid[2] ) ) | ||
3134 : | write_coord( floatround( ln_fnmid[0] ) ) | ||
3135 : | write_coord( floatround( ln_fnmid[1] ) ) | ||
3136 : | write_coord( floatround( ln_fnmid[2] ) ) | ||
3137 : | write_short( beam_sprite ) // sprite index | ||
3138 : | write_byte( 0 ) // starting frame | ||
3139 : | write_byte( 10 ) // frame rate in 0.1's | ||
3140 : | write_byte( life ) // life in 0.1's | ||
3141 : | write_byte( 10 ) // line width in 0.1's | ||
3142 : | write_byte( 2 ) // noise amplitude in 0.01's | ||
3143 : | write_byte( 0 ) // Red | ||
3144 : | write_byte( 255 ) // Green | ||
3145 : | write_byte( 0 ) // Blue | ||
3146 : | write_byte( 127 ) // brightness | ||
3147 : | write_byte( 50 ) // scroll speed in 0.1's | ||
3148 : | message_end( ) | ||
3149 : | |||
3150 : | message_begin( dest, SVC_TEMPENTITY, _, id ) | ||
3151 : | write_byte( TE_BEAMPOINTS ) | ||
3152 : | write_coord( floatround( ln_fnmid[0] ) ) | ||
3153 : | write_coord( floatround( ln_fnmid[1] ) ) | ||
3154 : | write_coord( floatround( ln_fnmid[2] ) ) | ||
3155 : | write_coord( floatround( ln_fn[0] ) ) | ||
3156 : | write_coord( floatround( ln_fn[1] ) ) | ||
3157 : | write_coord( floatround( ln_fn[2] ) ) | ||
3158 : | write_short( beam_sprite ) // sprite index | ||
3159 : | write_byte( 0 ) // starting frame | ||
3160 : | write_byte( 10 ) // frame rate in 0.1's | ||
3161 : | write_byte( life ) // life in 0.1's | ||
3162 : | write_byte( 10 ) // line width in 0.1's | ||
3163 : | write_byte( 2 ) // noise amplitude in 0.01's | ||
3164 : | write_byte( 0 ) // Red | ||
3165 : | write_byte( 0 ) // Green | ||
3166 : | write_byte( 255 ) // Blue | ||
3167 : | write_byte( 127 ) // brightness | ||
3168 : | write_byte( 50 ) // scroll speed in 0.1's | ||
3169 : | message_end( ) | ||
3170 : | |||
3171 : | //Remove task if flag has been removed | ||
3172 : | ian | 19 | if( task_exists( tskid ) && !( timer[id][TMR_CFLAGS] & CF_MEASURE2 ) ) remove_task( tskid ) |
3173 : | ian | 1 | |
3174 : | //If a second point hasn't been set then end here | ||
3175 : | if( !set ) return | ||
3176 : | |||
3177 : | //If it gets this far it's the second iteration, /*so disable flag and*/ reset static var | ||
3178 : | ian | 19 | //timer[id][TMR_CFLAGS] ^= CF_MEASURE2 |
3179 : | ln_st_static[id] = Float:{ 0.0, 0.0, 0.0 } | ||
3180 : | ian | 1 | if( task_exists( tskid ) ) remove_task( tskid ) |
3181 : | } | ||
3182 : | |||
3183 : | //////////////////////////////////////////////////////////////////////////////// | ||
3184 : | // End: Measure functions | ||
3185 : | //////////////////////////////////////////////////////////////////////////////// | ||
3186 : | // Start: Blocked/Forwarded default CS commands | ||
3187 : | //////////////////////////////////////////////////////////////////////////////// | ||
3188 : | public client_kill( id ) | ||
3189 : | {//Block kill, forward to spectate command | ||
3190 : | if( get_pcvar_num( p_climb ) ) | ||
3191 : | { | ||
3192 : | spectate( id ) | ||
3193 : | return PLUGIN_HANDLED | ||
3194 : | } | ||
3195 : | return PLUGIN_CONTINUE | ||
3196 : | } | ||
3197 : | |||
3198 : | public block_cmd(id){//Block some commands if climb enabled | ||
3199 : | if(get_pcvar_num(p_climb))return PLUGIN_HANDLED | ||
3200 : | return PLUGIN_CONTINUE | ||
3201 : | } | ||
3202 : | |||
3203 : | public block_cmd2(id){//Used to block fullupdate always | ||
3204 : | return PLUGIN_HANDLED | ||
3205 : | } | ||
3206 : | |||
3207 : | public block_jointeam(id){//Block client trying to switch teams | ||
3208 : | if(get_pcvar_num(p_climb)&&isct(id))return PLUGIN_HANDLED | ||
3209 : | return PLUGIN_CONTINUE | ||
3210 : | } | ||
3211 : | |||
3212 : | public donothing(){//register_clcmd reference this function, but are picked up by the more flexible code in the client_command forward. | ||
3213 : | return PLUGIN_CONTINUE | ||
3214 : | } | ||
3215 : | |||
3216 : | public menuteam(id){//Connect choose team menu - force client to select CT | ||
3217 : | if(get_pcvar_num(p_climb))client_cmd(id,"slot2") | ||
3218 : | return PLUGIN_CONTINUE | ||
3219 : | } | ||
3220 : | |||
3221 : | public menuclass(id){//Force client to choose random model | ||
3222 : | if(get_pcvar_num(p_climb)){ | ||
3223 : | client_cmd(id,"slot5") | ||
3224 : | } | ||
3225 : | return PLUGIN_CONTINUE | ||
3226 : | } | ||
3227 : | |||
3228 : | //////////////////////////////////////////////////////////////////////////////// | ||
3229 : | // End: Blocked/Forwarded default CS commands | ||
3230 : | //////////////////////////////////////////////////////////////////////////////// | ||
3231 : | // Start: Database functions | ||
3232 : | //////////////////////////////////////////////////////////////////////////////// | ||
3233 : | public db_init( ) | ||
3234 : | { | ||
3235 : | |||
3236 : | static host[32], user[32], pass[32], name[32], type[12] | ||
3237 : | |||
3238 : | get_cvar_string( "climb_db_host", host, 31 ) | ||
3239 : | get_cvar_string( "climb_db_user", user, 31 ) | ||
3240 : | get_cvar_string( "climb_db_pass", pass, 31 ) | ||
3241 : | get_cvar_string( "climb_db_name", name, 31 ) | ||
3242 : | get_cvar_string( "climb_db_type", type, 11 ) | ||
3243 : | get_cvar_string( "climb_db_prefix", DB_PREFIX, 10 ) | ||
3244 : | get_cvar_string( "climb_db_serverid", DB_SERVER_ID, 15 ) | ||
3245 : | |||
3246 : | //SQL_SetAffinity(type) | ||
3247 : | DB_TUPLE=SQL_MakeDbTuple(host,user,pass,name) | ||
3248 : | |||
3249 : | if( !get_cvar_num( "climb_db_exists" ) ) | ||
3250 : | { | ||
3251 : | new autoinc[15]="autoincrement" | ||
3252 : | if(equal(type,"mysql"))autoinc="auto_increment" | ||
3253 : | new query[600] | ||
3254 : | |||
3255 : | formatex( query, 599, | ||
3256 : | "create table if not exists %splayers (\ | ||
3257 : | user_id integer primary key %s,\ | ||
3258 : | steam_id char(25) unique,\ | ||
3259 : | password char(6),\ | ||
3260 : | user_name varchar(20) unique,\ | ||
3261 : | alias varchar(32) unique,\ | ||
3262 : | email varchar(50) unique,\ | ||
3263 : | cflags integer)", | ||
3264 : | DB_PREFIX, autoinc ) | ||
3265 : | SQL_ThreadQuery( DB_TUPLE, "db_generic_handler", query ) | ||
3266 : | |||
3267 : | formatex( query, 599, | ||
3268 : | "create table if not exists %sscores (\ | ||
3269 : | score_id integer primary key %s,\ | ||
3270 : | score integer,\ | ||
3271 : | server_ip char(15),\ | ||
3272 : | user_id integer,\ | ||
3273 : | map_name varchar(32),\ | ||
3274 : | fin_time integer,\ | ||
3275 : | cps integer,\ | ||
3276 : | gcs integer,\ | ||
3277 : | boosts integer,\ | ||
3278 : | wpns integer,\ | ||
3279 : | server_time_stamp integer)", | ||
3280 : | DB_PREFIX, autoinc ) | ||
3281 : | SQL_ThreadQuery(DB_TUPLE,"db_generic_handler",query) | ||
3282 : | |||
3283 : | formatex( query, 599, "create index scores_score on %sscores (score)", DB_PREFIX ) | ||
3284 : | SQL_ThreadQuery( DB_TUPLE, "db_generic_handler", query ) | ||
3285 : | |||
3286 : | formatex( query, 599, | ||
3287 : | "create table if not exists %ssessions (\ | ||
3288 : | steam_id char(25) primary key,\ | ||
3289 : | user_id integer unique)", | ||
3290 : | DB_PREFIX ) | ||
3291 : | SQL_ThreadQuery( DB_TUPLE, "db_generic_handler", query ) | ||
3292 : | |||
3293 : | set_cvar_num( "climb_db_exists", 1 ) | ||
3294 : | } | ||
3295 : | } | ||
3296 : | |||
3297 : | public db_generic_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime) | ||
3298 : | return query_failed( failstate, error, errnum ) | ||
3299 : | |||
3300 : | public auto_login(ida[1]) | ||
3301 : | { | ||
3302 : | new id=ida[0] | ||
3303 : | |||
3304 : | //debug | ||
3305 : | new name[33],sid[33],data[2],query[151] | ||
3306 : | get_user_name( id, name, 32 ) | ||
3307 : | get_user_authid( id, sid, 32 ) | ||
3308 : | //log_amx( "CLIMB: auto_login( %d ) / %s / %s", id, name, sid ) | ||
3309 : | |||
3310 : | data[0] = id | ||
3311 : | data[1] = 2 | ||
3312 : | formatex( query, 150, | ||
3313 : | "select user_id, steam_id, password from %splayers where steam_id=^"%s^"", | ||
3314 : | DB_PREFIX, sid ) | ||
3315 : | //formatex( data[2], 24, sid) | ||
3316 : | SQL_ThreadQuery( DB_TUPLE, "login_handler", query, data, 2 ) | ||
3317 : | |||
3318 : | //log_amx( "CLIMB: Login Query for id=%d - ^"%s^";", id, query ) | ||
3319 : | |||
3320 : | //return client_cmd( id, "login" ) | ||
3321 : | //return db_login( id ) | ||
3322 : | } | ||
3323 : | |||
3324 : | public db_login( id ) | ||
3325 : | { | ||
3326 : | //log_amx( "CLIMB: Function entry - login( %d )", id ) | ||
3327 : | if( get_pcvar_num( p_climb ) ) | ||
3328 : | { | ||
3329 : | if( CLIMB_SAVE ) | ||
3330 : | { | ||
3331 : | //log_amx( "CLIMB: Begin login client id=%d.", id ) | ||
3332 : | ian | 19 | //log_amx( "CLIMB: timer[id][TMR_DBUSER]=%d.", timer[id][TMR_DBUSER] ) |
3333 : | ian | 1 | |
3334 : | ian | 19 | if( timer[id][TMR_DBUSER] > 0 ) //Already logged in |
3335 : | ian | 1 | { |
3336 : | client_print( id, print_console, "[Climb] Login Error: You are already logged in." ) | ||
3337 : | return PLUGIN_HANDLED | ||
3338 : | } | ||
3339 : | new query[151], data[2] //data[28] | ||
3340 : | data[0] = id | ||
3341 : | |||
3342 : | /*if( read_argc() > 1 ) //Client is logging in with a user/pass | ||
3343 : | { | ||
3344 : | new user[21], pass[21] | ||
3345 : | read_argv( 1, user, 20 ) | ||
3346 : | read_argv( 2, pass, 20 ) | ||
3347 : | rotwtf( pass, 6 ) | ||
3348 : | data[1] = 1 | ||
3349 : | formatex( query, 150, | ||
3350 : | "select user_id, steam_id, from %splayers where user_id=^"%s^" and password=^"%s^";", | ||
3351 : | DB_PREFIX, user, pass ) | ||
3352 : | //formatex( data[2], 24, user) | ||
3353 : | SQL_ThreadQuery( DB_TUPLE, "login_handler", query, data, 2 ) | ||
3354 : | } | ||
3355 : | else //Client is logging in with SteamID | ||
3356 : | {*/ | ||
3357 : | new sid[32] | ||
3358 : | get_user_authid( id, sid, 31 ) | ||
3359 : | data[1] = 2 | ||
3360 : | formatex( query, 150, | ||
3361 : | "select user_id, steam_id, password from %splayers where steam_id=^"%s^"", | ||
3362 : | DB_PREFIX, sid ) | ||
3363 : | //formatex( data[2], 24, sid) | ||
3364 : | SQL_ThreadQuery( DB_TUPLE, "login_handler", query, data, 2 ) | ||
3365 : | |||
3366 : | //log_amx( "CLIMB: Login Query for id=%d - ^"%s^";", id, query ) | ||
3367 : | //} | ||
3368 : | } | ||
3369 : | else client_print( id, print_console, "[Climb] Login Error: Can't Login; Stats not enabled." ) | ||
3370 : | } | ||
3371 : | return PLUGIN_HANDLED | ||
3372 : | } | ||
3373 : | |||
3374 : | public login_handler( failstate, Handle:query, error[], errnum, data[], size, Float:queuetime ) | ||
3375 : | { | ||
3376 : | new id = data[0] | ||
3377 : | //log_amx( "CLIMB: Function entry - login_handler( %d )", id ) | ||
3378 : | //If they've disonnected since the login attempt initiated, abort | ||
3379 : | if( !is_user_connected( id ) ) return log_amx( "CLIMB: Login Error id=%d - Client no longer exists.", id ) | ||
3380 : | |||
3381 : | if( SQL_NumResults( query ) < 1 ) | ||
3382 : | { | ||
3383 : | //log_amx( "CLIMB: Login Error id=%d - Not a valid account. 0 result returned", id ) | ||
3384 : | return client_print( id, print_console, "[Climb] Login Error: Not a valid account." ) | ||
3385 : | } | ||
3386 : | |||
3387 : | if( !query_failed( failstate, error, errnum) ) | ||
3388 : | { | ||
3389 : | //If database steamid doesn't match client steamid, abort | ||
3390 : | new db_sid[32], sid[32] | ||
3391 : | SQL_ReadResult( query, 1, db_sid, 31 ) | ||
3392 : | get_user_authid( id, sid, 31 ) | ||
3393 : | if( !equal( sid, db_sid ) ) return log_amx( "CLIMB: Login Error id=%d - SteamID mismatch.", id ) | ||
3394 : | |||
3395 : | //Fail if steamid login attempt, and steamid is registered as shared | ||
3396 : | if( data[1] == 2 ) | ||
3397 : | { | ||
3398 : | new pass[7] | ||
3399 : | SQL_ReadResult( query, 2, pass, 6 ) | ||
3400 : | if( equali( pass, "shared" ) ) | ||
3401 : | { | ||
3402 : | //log_amx( "CLIMB: Login Error id=%d - Shared SteamID.", id ) | ||
3403 : | return client_print( id, print_console,\ | ||
3404 : | "[Climb] Login Error: You are using a shared SteamID. Please login with a username and password." ) | ||
3405 : | } | ||
3406 : | } | ||
3407 : | |||
3408 : | //Everything is ok, add db userid to timer info, display login messages | ||
3409 : | ian | 19 | timer[id][TMR_DBUSER] = SQL_ReadResult( query, 0 ) |
3410 : | ian | 1 | new msg[100] |
3411 : | formatex( msg, 99, "[Climb] Login: Success - Account: %s", sid ) | ||
3412 : | //log_amx( "CLIMB: Login Success id=%d", id ) | ||
3413 : | client_print(id,print_console,msg ) | ||
3414 : | format( msg, 99, "^x04%s", msg ) | ||
3415 : | saytext( id, id, msg ) | ||
3416 : | |||
3417 : | //If they just registered and logged in, save score, else load score | ||
3418 : | ian | 19 | if( timer[id][TMR_CFLAGS] & CF_JUST_REGD ) |
3419 : | ian | 1 | { |
3420 : | db_save( id ) | ||
3421 : | ian | 19 | timer[id][TMR_CFLAGS] -= CF_JUST_REGD |
3422 : | ian | 1 | } |
3423 : | else db_load(id) | ||
3424 : | } | ||
3425 : | return PLUGIN_HANDLED | ||
3426 : | } | ||
3427 : | |||
3428 : | /*public logout(id) | ||
3429 : | { | ||
3430 : | ian | 19 | for(new i=0;i<8;i++)origins[id][i]=0.0 |
3431 : | for(new i=0;i<11;i++)timer[id][i]=0 | ||
3432 : | ian | 1 | }*/ |
3433 : | |||
3434 : | public db_load( id ) | ||
3435 : | { | ||
3436 : | new query[351], mapname[33], data[1] | ||
3437 : | data[0] = id | ||
3438 : | get_mapname( mapname, 32 ) | ||
3439 : | /*formatex( query, 149, | ||
3440 : | "select fin_time, cps, gcs, fin_cnt, boosts, wpns from %sscores where user_id=%d and map_name=^"%s^";", | ||
3441 : | ian | 19 | DB_PREFIX, timer[id][TMR_DBUSER], mapname )*/ |
3442 : | ian | 1 | formatex( query, 350, |
3443 : | "select s.fin_time, s.cps, s.gcs, g.fin_cnt, s.boosts, s.wpns from %sscores s, (select user_id, count(*) fin_cnt from %sscores where map_name = ^"%s^" group by user_id) g where map_name = ^"%s^" and s.user_id = %d and g.user_id = %d", | ||
3444 : | ian | 19 | DB_PREFIX, DB_PREFIX, mapname, mapname, timer[id][TMR_DBUSER], timer[id][TMR_DBUSER] ) |
3445 : | ian | 1 | SQL_ThreadQuery( DB_TUPLE, "db_load_handler", query, data, 1 ) |
3446 : | } | ||
3447 : | |||
3448 : | public db_load_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime) | ||
3449 : | { | ||
3450 : | new id=data[0] | ||
3451 : | if( !query_failed( failstate, error, errnum) ) | ||
3452 : | { | ||
3453 : | new msg[100] | ||
3454 : | if(!SQL_NumResults(query)) | ||
3455 : | msg="^x04No stats available for this account on the current map." | ||
3456 : | else | ||
3457 : | { | ||
3458 : | new mapname[33],timestr[9] | ||
3459 : | get_mapname(mapname,32) | ||
3460 : | ian | 19 | timer[id][TMR_BSTTME] = SQL_ReadResult( query, 0 ) |
3461 : | timer[id][TMR_BSTCPS] = SQL_ReadResult( query, 1 ) | ||
3462 : | timer[id][TMR_BSTGCS] = SQL_ReadResult( query, 2 ) | ||
3463 : | timer[id][TMR_MAPFIN] = SQL_ReadResult( query, 3 ) | ||
3464 : | timer[id][TMR_BSTBST] = SQL_ReadResult( query, 4 ) | ||
3465 : | timer[id][TMR_BSTWPN] = SQL_ReadResult( query, 5 ) | ||
3466 : | //timer[id][TMR_CFLAGS]+=SQL_ReadResult(query,5)?CF_BSTSCT:0 | ||
3467 : | ian | 1 | |
3468 : | ian | 19 | timestr = parsetime(timer[id][TMR_BSTTME]) |
3469 : | ian | 1 | formatex( msg, 99, |
3470 : | "^x04Stats loaded for %s - %s^t(%d/ %d CP/%d GC/%d Boost)^tCompleted %d", | ||
3471 : | ian | 19 | mapname, timestr, timer[id][TMR_BSTWPN], timer[id][TMR_BSTCPS], |
3472 : | timer[id][TMR_BSTGCS], timer[id][TMR_BSTBST], timer[id][TMR_MAPFIN] ) | ||
3473 : | ian | 1 | } |
3474 : | saytext( id, id, msg ) | ||
3475 : | } | ||
3476 : | else client_print( id, print_chat, "[Climb] DB Read Error: Please notify a server admin." ) | ||
3477 : | return PLUGIN_HANDLED | ||
3478 : | } | ||
3479 : | |||
3480 : | public db_save( id ) | ||
3481 : | { | ||
3482 : | ian | 19 | if( timer[id][TMR_DBUSER] < 1 ) |
3483 : | ian | 1 | { |
3484 : | auto_reg( id ) | ||
3485 : | return PLUGIN_HANDLED | ||
3486 : | } | ||
3487 : | new query[351], name[33], data[2] | ||
3488 : | data[0] = id | ||
3489 : | get_mapname( name, 32 ) | ||
3490 : | strtolower( name ) | ||
3491 : | |||
3492 : | ian | 19 | new user_id = timer[id][TMR_DBUSER] |
3493 : | ian | 1 | new fin_time = get_climber_time( id ) |
3494 : | |||
3495 : | ian | 19 | new wpn_rank = timer[id][TMR_CNTWPN] |
3496 : | ian | 1 | |
3497 : | ian | 19 | new score = ( ( ( timer[id][TMR_CNTBST] > 0 ? 1 : 0 ) * 1000000 ) + |
3498 : | ( ( timer[id][TMR_CNTCPS] > 0 ? 1 : 0 ) * 100000 ) + | ||
3499 : | ian | 1 | ( wpn_rank * 10000 ) + |
3500 : | fin_time ) | ||
3501 : | |||
3502 : | ian | 19 | /*if( timer[id][TMR_MAPFIN] == 1 ) |
3503 : | ian | 1 | formatex( query, 350, |
3504 : | "insert into %sscores (user_id, map_name, fin_time, cps, gcs, fin_cnt, boosts, wpns, score, server_time_stamp) values (%d, ^"%s^", %d, %d, %d, %d, %d, %d, %d, %d);",\ | ||
3505 : | ian | 19 | DB_PREFIX, user_id, name, fin_time, timer[id][TMR_BSTCPS], timer[id][TMR_BSTGCS], timer[id][TMR_MAPFIN], timer[id][TMR_BSTBST], sctd, sort, get_systime() ) |
3506 : | ian | 1 | else*/ |
3507 : | formatex( query, 350, | ||
3508 : | "insert into %sscores (server_ip, user_id, map_name, fin_time, cps, gcs, boosts, wpns, score, server_time_stamp) values (^"%s^", %d, ^"%s^", %d, %d, %d, %d, %d, %d, %d)",\ | ||
3509 : | ian | 19 | DB_PREFIX, DB_SERVER_ID, user_id, name, fin_time, timer[id][TMR_CNTCPS], timer[id][TMR_CNTGCS], timer[id][TMR_CNTBST], wpn_rank, score, get_systime() ) |
3510 : | ian | 1 | SQL_ThreadQuery(DB_TUPLE,"db_save_handler",query,data,2) |
3511 : | |||
3512 : | data[1] = 0 | ||
3513 : | get_user_name( id, name, 32 ) | ||
3514 : | ian | 19 | formatex( query, 350, "update %splayers set alias=^"%s^" where user_id=%d;", DB_PREFIX, name, timer[id][TMR_DBUSER] ) |
3515 : | ian | 1 | SQL_ThreadQuery( DB_TUPLE, "db_name_update_handler", query, data, 2 ) |
3516 : | return PLUGIN_HANDLED | ||
3517 : | } | ||
3518 : | |||
3519 : | public db_save_handler( failstate, Handle:query, error[], errnum, data[], size, Float:queuetime ) | ||
3520 : | { | ||
3521 : | if( query_failed( failstate, error, errnum ) ) | ||
3522 : | { | ||
3523 : | new id=data[0] | ||
3524 : | client_print(id,print_chat,"[Climb] DB Write Error: Could not update your score. Please notify a server admin.") | ||
3525 : | } | ||
3526 : | |||
3527 : | return PLUGIN_HANDLED | ||
3528 : | } | ||
3529 : | |||
3530 : | public db_name_update_handler( failstate, Handle:query, error[], errnum, data[], size, Float:queuetime ) | ||
3531 : | { | ||
3532 : | if( query_failed( failstate, error, errnum ) ) | ||
3533 : | { | ||
3534 : | new id = data[0] | ||
3535 : | |||
3536 : | if( data[1] > 9 ) | ||
3537 : | client_print(id,print_chat,"[Climb] DB Write Error: Could not update your name. Please notify a server admin.") | ||
3538 : | else | ||
3539 : | { | ||
3540 : | new query[250] | ||
3541 : | new data2[2] | ||
3542 : | data2[0] = id | ||
3543 : | data2[1] = data[1] + 1 | ||
3544 : | |||
3545 : | |||
3546 : | new name[33] | ||
3547 : | get_user_name( id, name, 29 ) | ||
3548 : | format( name, 32, "%s(%d)", name, data2[1] ) | ||
3549 : | |||
3550 : | formatex( query, 249,\ | ||
3551 : | "update %splayers set alias=^"%s^" where user_id=%d;",\ | ||
3552 : | ian | 19 | DB_PREFIX, name, timer[id][TMR_DBUSER] ) |
3553 : | ian | 1 | SQL_ThreadQuery(DB_TUPLE,"db_name_update_handler",query,data2,2) |
3554 : | } | ||
3555 : | } | ||
3556 : | |||
3557 : | return PLUGIN_HANDLED | ||
3558 : | } | ||
3559 : | |||
3560 : | public reg(id) | ||
3561 : | { | ||
3562 : | if(get_pcvar_num(p_climb)){ | ||
3563 : | if(CLIMB_SAVE){ | ||
3564 : | new query[100],sid[26],name[33],data[43] | ||
3565 : | data[0]=id | ||
3566 : | data[1]=0 | ||
3567 : | get_user_authid(id,sid,25) | ||
3568 : | get_user_name(id,name,32) | ||
3569 : | //Register user/pass | ||
3570 : | if(read_argc()>1){ | ||
3571 : | if(read_argc()!=3){ | ||
3572 : | client_print(id,print_console,"[Climb] Registration Error: Invalid number of arguments") | ||
3573 : | return PLUGIN_HANDLED | ||
3574 : | } | ||
3575 : | new user[21],pass[50] | ||
3576 : | //Read password and check length | ||
3577 : | read_argv(2,pass,20) | ||
3578 : | if(strlen(pass)<10){ | ||
3579 : | client_print(id,print_console,"[Climb] Registration Error: Password must be at least 10 characters.") | ||
3580 : | return PLUGIN_HANDLED | ||
3581 : | } | ||
3582 : | //Read user | ||
3583 : | read_argv(1,user,20) | ||
3584 : | //Store user/pass in data array to pass to handler for autologin | ||
3585 : | formatex(data[2],20,user) | ||
3586 : | formatex(data[22],20,pass) | ||
3587 : | //Create password hash | ||
3588 : | rotwtf(pass,6) | ||
3589 : | //Register shared SteamID | ||
3590 : | formatex(query,99,"insert into %splayers (steam_id,password) values (^"%s^",'shared')",DB_PREFIX,sid) | ||
3591 : | SQL_ThreadQuery(DB_TUPLE,"reg_handler",query,data,43) | ||
3592 : | //Register user/pass | ||
3593 : | data[1]=1 | ||
3594 : | formatex(query,99,"insert into %splayers (user_name,password,alias) values (^"%s^",^"%s^",^"%s^")",DB_PREFIX,user,pass,name) | ||
3595 : | SQL_ThreadQuery(DB_TUPLE,"reg_handler",query,data,43) | ||
3596 : | } | ||
3597 : | //Else register SteamID | ||
3598 : | ian | 19 | /*else if(timer[id][TMR_DBUSER]<1){ |
3599 : | ian | 1 | data[1]=2 |
3600 : | formatex(query,99,"insert into %splayers (steam_id,alias) values (^"%s^",^"%s^")",DB_PREFIX,sid,name) | ||
3601 : | SQL_ThreadQuery(DB_TUPLE,"reg_handler",query,data,43) | ||
3602 : | }*/ | ||
3603 : | } | ||
3604 : | else client_print(id,print_console,"[Climb] Registration Error: Can't Register; Stats not enabled.") | ||
3605 : | } | ||
3606 : | return PLUGIN_HANDLED | ||
3607 : | } | ||
3608 : | |||
3609 : | public auto_reg(id) | ||
3610 : | { | ||
3611 : | new query[100],sid[26],name[33],data[43] | ||
3612 : | data[0]=id | ||
3613 : | data[1]=2 | ||
3614 : | get_user_authid(id,sid,25) | ||
3615 : | get_user_name(id,name,32) | ||
3616 : | formatex(query,99,"insert into %splayers (steam_id,alias) values (^"%s^",^"%s^")",DB_PREFIX,sid,name) | ||
3617 : | SQL_ThreadQuery(DB_TUPLE,"reg_handler",query,data,43) | ||
3618 : | return PLUGIN_HANDLED | ||
3619 : | } | ||
3620 : | |||
3621 : | public reg_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime) | ||
3622 : | { | ||
3623 : | new id=data[0] | ||
3624 : | if( !query_failed( failstate, error, errnum) ) | ||
3625 : | { | ||
3626 : | new flag=data[1],user[21],pass[21] | ||
3627 : | format(user,20,data[2]) | ||
3628 : | format(pass,20,data[22]) | ||
3629 : | |||
3630 : | if(flag==0)client_print(id,print_console,"[Climb] Recorded shared SteamID.") | ||
3631 : | else if(flag==1){ | ||
3632 : | client_print(id,print_console,"[Climb] Registration Successful.") | ||
3633 : | |||
3634 : | new cmd[50] | ||
3635 : | formatex(cmd,49,"login %s %s",user,pass) | ||
3636 : | client_cmd(id,cmd) | ||
3637 : | } | ||
3638 : | else if(flag==2){ | ||
3639 : | ian | 19 | timer[id][TMR_CFLAGS]+=CF_JUST_REGD |
3640 : | ian | 1 | client_cmd(id,"login") |
3641 : | } | ||
3642 : | } | ||
3643 : | else client_print(id,print_chat,"[Climb] DB Registration Error: Please notify a server admin.") | ||
3644 : | return PLUGIN_HANDLED | ||
3645 : | } | ||
3646 : | |||
3647 : | public highscores(id) | ||
3648 : | {//Show High Scores | ||
3649 : | if( !CLIMB_SAVE ) return clmsg( id, "Stats not enabled.") | ||
3650 : | |||
3651 : | new hsurl[150], mapname[33] | ||
3652 : | get_pcvar_string( p_stats_hsurl, hsurl, 149 ) | ||
3653 : | get_mapname( mapname, 32 ) | ||
3654 : | if( strlen( hsurl ) ) | ||
3655 : | { | ||
3656 : | format( hsurl, 149, hsurl, mapname ) | ||
3657 : | show_motd( id, hsurl, "High Scores" ) | ||
3658 : | return PLUGIN_HANDLED | ||
3659 : | } | ||
3660 : | if( get_systime() - ts_hscore > 10 ) | ||
3661 : | { | ||
3662 : | new query[501], data[1] | ||
3663 : | data[0] = id | ||
3664 : | /*formatex( query, 249,\ | ||
3665 : | "select p.alias, s.fin_time, s.cps, s.gcs, s.fin_cnt, s.boosts, s.wpns from %sscores s, %splayers p where s.map_name=^"%s^" and p.user_id=s.user_id order by s.score, s.fin_time limit 20;",\ | ||
3666 : | DB_PREFIX, DB_PREFIX, mapname )*/ | ||
3667 : | formatex( query, 500, | ||
3668 : | "select distinct p.alias, s.fin_time, s.cps, s.gcs, g.fin_cnt, s.boosts, s.wpns, s.score from %sscores s join %splayers p on s.user_id = p.user_id join (select user_id, min(score) minscore, count(*) fin_cnt from %sscores where map_name=^"%s^" group by user_id, wpns) g on p.user_id=g.user_id where map_name=^"%s^" and s.score=g.minscore order by s.score limit 20", | ||
3669 : | DB_PREFIX, DB_PREFIX, DB_PREFIX, mapname, mapname ) | ||
3670 : | SQL_ThreadQuery( DB_TUPLE, "hs_handler", query, data, 1 ) | ||
3671 : | ts_hscore = get_systime() | ||
3672 : | } | ||
3673 : | else | ||
3674 : | { | ||
3675 : | if( has_hscores ) | ||
3676 : | show_motd( id, HSCORES_PATH, "High Scores" ) | ||
3677 : | else | ||
3678 : | { | ||
3679 : | new msg[101] | ||
3680 : | format( msg, 100, "^x04[Climb] No stats available for the current map." ) | ||
3681 : | return saytext( id, id, msg ) | ||
3682 : | } | ||
3683 : | } | ||
3684 : | |||
3685 : | return PLUGIN_HANDLED | ||
3686 : | } | ||
3687 : | |||
3688 : | public hs_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime) | ||
3689 : | { | ||
3690 : | if( !query_failed( failstate, error, errnum) ) | ||
3691 : | { | ||
3692 : | new id=data[0],msg[101],num=SQL_NumResults(query) | ||
3693 : | if(!num){ | ||
3694 : | format(msg,100,"^x04[Climb] No stats available for the current map.") | ||
3695 : | return saytext(id,id,msg) | ||
3696 : | } | ||
3697 : | |||
3698 : | has_hscores = true | ||
3699 : | |||
3700 : | new fh = fopen( HSCORES_PATH, "w" ) | ||
3701 : | |||
3702 : | fprintf( fh, "<link rel=stylesheet href=http://ian.cammarata.us/sb><table><tr><td id=a>" ) | ||
3703 : | fprintf( fh, "<pre># Name Time Wpn/CP/GC/Boost Fin</pre>" ) | ||
3704 : | fprintf( fh, "</td></tr><tr id=b><td></td></tr><tr><td><pre>" ) | ||
3705 : | |||
3706 : | new name[NAMELEN+2], line[151], written_len, btime_str[20] | ||
3707 : | for( new i = 1; i <= num; i++ ) | ||
3708 : | { | ||
3709 : | SQL_ReadResult( query, 0, name, NAMELEN ) | ||
3710 : | sb_add_tabs( name, NAMELEN+2 ) | ||
3711 : | |||
3712 : | |||
3713 : | format( btime_str, 19, "%d/%d/%d/%d",\ | ||
3714 : | SQL_ReadResult( query, 6 ),\ | ||
3715 : | SQL_ReadResult( query, 2 ),\ | ||
3716 : | SQL_ReadResult( query, 3 ),\ | ||
3717 : | SQL_ReadResult( query, 5 ) ) | ||
3718 : | sb_add_tabs( btime_str, 19 ) | ||
3719 : | |||
3720 : | formatex( line, 150,\ | ||
3721 : | "%s%d %s%s %s %d%s", | ||
3722 : | ian | 22 | i % 2 ? NULLSTR : "<div>", |
3723 : | ian | 1 | i, htmlspecialchars( name ), |
3724 : | parsetime( SQL_ReadResult( query, 1 ) ), | ||
3725 : | btime_str, | ||
3726 : | SQL_ReadResult( query, 4 ), | ||
3727 : | ian | 22 | i % 2 ? NULLSTR : "</div>" ) |
3728 : | ian | 1 | written_len += strlen( line ) |
3729 : | if( written_len > 1263 ) break | ||
3730 : | fprintf( fh, line ) | ||
3731 : | SQL_NextRow( query ) | ||
3732 : | } | ||
3733 : | |||
3734 : | //1530-150-117=1263 | ||
3735 : | new cust_msg[33] | ||
3736 : | get_pcvar_string( p_stats_msg, cust_msg, 32 ) | ||
3737 : | if( !strlen( cust_msg ) ) formatex( cust_msg, 32, "Climb %s", VERSION ) | ||
3738 : | fprintf( fh, "</pre></td></tr><tr id=d><td></td></tr><tr><td id=e></td></tr><tr>" ) | ||
3739 : | fprintf( fh, "<td id=a>%s</td></tr></table>", cust_msg ) | ||
3740 : | fclose( fh ) | ||
3741 : | |||
3742 : | show_motd( id, HSCORES_PATH, "High Scores" ) | ||
3743 : | } | ||
3744 : | return PLUGIN_HANDLED | ||
3745 : | } | ||
3746 : | |||
3747 : | public climb_dbwho(id,level,cid) | ||
3748 : | { | ||
3749 : | if(cmd_access(id,level,cid,0)) | ||
3750 : | { | ||
3751 : | console_print(id,"^n# DB ID (<0=Not in DB), Name") | ||
3752 : | |||
3753 : | new players[32],count,name[21],id2 | ||
3754 : | get_players( players, count, "ch" ) | ||
3755 : | for( new i=0; i<count; i++ ) | ||
3756 : | { | ||
3757 : | id2=players[i] | ||
3758 : | get_user_name(id2,name,20) | ||
3759 : | ian | 19 | console_print(id,"# %d, %s",timer[id2][TMR_DBUSER],name) |
3760 : | ian | 1 | } |
3761 : | console_print( id, "%d Players", count ) | ||
3762 : | } | ||
3763 : | return PLUGIN_HANDLED | ||
3764 : | } | ||
3765 : | |||
3766 : | public climb_dbmap( id, level, cid ) | ||
3767 : | { | ||
3768 : | if( cmd_access( id, level, cid, 0 ) ) | ||
3769 : | { | ||
3770 : | new mapname[33] | ||
3771 : | if( read_argc()>1 )read_argv( 1, mapname, 32 ) | ||
3772 : | if( !strlen(mapname) )get_mapname( mapname, 32 ) | ||
3773 : | |||
3774 : | new query[501], data[1] | ||
3775 : | data[0]=id | ||
3776 : | |||
3777 : | /*formatex( query, 500, | ||
3778 : | "select p.alias, s.score_id, s.fin_time, s.cps, s.gcs, s.boosts, s.wpns from %sscores s, %splayers p where s.map_name=^"%s^" and p.user_id=s.user_id order by s.score, s.fin_time limit 20;", | ||
3779 : | DB_PREFIX, DB_PREFIX, mapname)*/ | ||
3780 : | formatex( query, 500, | ||
3781 : | "select distinct p.alias, s.score_id, s.fin_time, s.cps, s.gcs, s.boosts, s.wpns from %sscores s join %splayers p on s.user_id = p.user_id join (select user_id, min(score) minscore, count(*) fin_cnt from %sscores where map_name=^"%s^" group by user_id, wpns) g on p.user_id=g.user_id where map_name=^"%s^" and s.score=g.minscore order by s.score limit 20", | ||
3782 : | DB_PREFIX, DB_PREFIX, DB_PREFIX, mapname, mapname ) | ||
3783 : | SQL_ThreadQuery( DB_TUPLE, "climb_dbmap_handler", query, data, 1 ) | ||
3784 : | } | ||
3785 : | return PLUGIN_HANDLED | ||
3786 : | } | ||
3787 : | |||
3788 : | public climb_dbmap_handler( failstate, Handle:query, error[], errnum, data[], size, Float:queuetime ) | ||
3789 : | { | ||
3790 : | if( !query_failed( failstate, error, errnum) ) | ||
3791 : | { | ||
3792 : | new id=data[0] | ||
3793 : | new count=SQL_NumResults( query ) | ||
3794 : | if( count ) | ||
3795 : | { | ||
3796 : | new name[21] | ||
3797 : | console_print( id, "^n# Alias, Score ID, Time, cps/gcs/boosts, Scout" ) | ||
3798 : | for( new i=0; i<count; i++ ) | ||
3799 : | { | ||
3800 : | SQL_ReadResult( query, 0, name, 20 ) | ||
3801 : | console_print( id, "# %s, %d, %d, %d/%d/%d, %s",\ | ||
3802 : | name,\ | ||
3803 : | SQL_ReadResult( query, 1 ),\ | ||
3804 : | SQL_ReadResult( query, 2 ),\ | ||
3805 : | SQL_ReadResult( query, 3 ),\ | ||
3806 : | SQL_ReadResult( query, 4 ),\ | ||
3807 : | SQL_ReadResult( query, 5 ),\ | ||
3808 : | SQL_ReadResult( query, 6 )?"y":"n") | ||
3809 : | SQL_NextRow( query ) | ||
3810 : | } | ||
3811 : | console_print( id, "%d Result(s)", count ) | ||
3812 : | } | ||
3813 : | else console_print( id, "Query returned no results." ) | ||
3814 : | } | ||
3815 : | return PLUGIN_HANDLED | ||
3816 : | } | ||
3817 : | |||
3818 : | public climb_dbuser( id, level, cid ) | ||
3819 : | { | ||
3820 : | if( cmd_access( id, level, cid, 1 ) ) | ||
3821 : | { | ||
3822 : | new db_user_id[10] | ||
3823 : | read_argv( 1, db_user_id, 9 ) | ||
3824 : | |||
3825 : | new query[250], data[1] | ||
3826 : | data[0]=id | ||
3827 : | |||
3828 : | formatex( query, 249,\ | ||
3829 : | "select map_name, score_id, fin_time, cps, gcs, boosts, wpns from %sscores where user_id=%d;",\ | ||
3830 : | DB_PREFIX, str_to_num( db_user_id ) ) | ||
3831 : | SQL_ThreadQuery( DB_TUPLE, "climb_dbuser_handler", query, data, 1 ) | ||
3832 : | } | ||
3833 : | return PLUGIN_HANDLED | ||
3834 : | } | ||
3835 : | |||
3836 : | public climb_dbuser_handler( failstate, Handle:query, error[], errnum, data[], size, Float:queuetime ) | ||
3837 : | { | ||
3838 : | if( !query_failed( failstate, error, errnum ) ) | ||
3839 : | { | ||
3840 : | new id=data[0] | ||
3841 : | new count=SQL_NumResults( query ) | ||
3842 : | if( count ) | ||
3843 : | { | ||
3844 : | new name[21] | ||
3845 : | console_print(id,"^n# Map, Score ID, Time, cps/gcs/boosts, Scout") | ||
3846 : | for( new i=0; i<count; i++ ) | ||
3847 : | { | ||
3848 : | SQL_ReadResult( query, 0, name, 20 ) | ||
3849 : | console_print( id, "# %s, %d, %d, %d/%d/%d, %s",\ | ||
3850 : | name,\ | ||
3851 : | SQL_ReadResult(query,1),\ | ||
3852 : | SQL_ReadResult(query,2),\ | ||
3853 : | SQL_ReadResult(query,3),\ | ||
3854 : | SQL_ReadResult(query,4),\ | ||
3855 : | SQL_ReadResult(query,5),\ | ||
3856 : | SQL_ReadResult(query,6) ? "y" : "n" ) | ||
3857 : | SQL_NextRow( query ) | ||
3858 : | } | ||
3859 : | console_print( id, "%d Result(s)", count ) | ||
3860 : | } | ||
3861 : | else console_print( id, "Query returned no results.") | ||
3862 : | } | ||
3863 : | return PLUGIN_HANDLED | ||
3864 : | } | ||
3865 : | |||
3866 : | public climb_dbdelete( id, level, cid ) | ||
3867 : | { | ||
3868 : | if(cmd_access(id,level,cid,1)) | ||
3869 : | { | ||
3870 : | new db_user_id[10] | ||
3871 : | read_argv( 1, db_user_id, 9 ) | ||
3872 : | |||
3873 : | new query[250], data[2], del_id | ||
3874 : | data[1]=del_id=str_to_num( db_user_id ) | ||
3875 : | data[0]=id | ||
3876 : | |||
3877 : | if(db_last_del_id!=del_id) | ||
3878 : | {//First time show data to be deleted and ask if they're sure. | ||
3879 : | formatex( query, 249,\ | ||
3880 : | "select p.alias, s.map_name, s.fin_time, s.cps, s.gcs, s.boosts, s.wpns from %sscores s, %splayers p where p.user_id=s.user_id and s.score_id=%d;",\ | ||
3881 : | DB_PREFIX, DB_PREFIX, del_id ) | ||
3882 : | SQL_ThreadQuery( DB_TUPLE, "climb_dbdelete_verify", query, data, 2 ) | ||
3883 : | } | ||
3884 : | else | ||
3885 : | {//Second time execute the delete | ||
3886 : | formatex( query, 249,\ | ||
3887 : | "delete from %sscores where score_id=%d;",\ | ||
3888 : | DB_PREFIX, del_id ) | ||
3889 : | SQL_ThreadQuery( DB_TUPLE, "climb_dbdelete_handler", query, data, 2 ) | ||
3890 : | db_last_del_id=0 | ||
3891 : | } | ||
3892 : | } | ||
3893 : | return PLUGIN_HANDLED | ||
3894 : | } | ||
3895 : | |||
3896 : | //For nightly builds | ||
3897 : | public climb_dbrecalc( id, level, cid ) | ||
3898 : | { | ||
3899 : | if( cmd_access( id, level, cid, 0 ) ) | ||
3900 : | SQL_ThreadQuery( DB_TUPLE, "db_generic_handler", | ||
3901 : | "update %sscores set score = ( ( (boosts>0) * 1000000 ) + ( (cps>0) * 100000 ) + ( wpns * 10000 ) + fin_time )", | ||
3902 : | DB_PREFIX ) | ||
3903 : | return PLUGIN_HANDLED | ||
3904 : | } | ||
3905 : | |||
3906 : | public climb_dbdelete_verify( failstate, Handle:query, error[], errnum, data[], size, Float:queuetime ) | ||
3907 : | { | ||
3908 : | if( !query_failed( failstate, error, errnum ) ) | ||
3909 : | { | ||
3910 : | new id=data[0] | ||
3911 : | new del_id=data[1] | ||
3912 : | new count=SQL_NumResults( query ) | ||
3913 : | if( count ) | ||
3914 : | { | ||
3915 : | new name[21],map[33] | ||
3916 : | console_print( id, "^n# Name, Map, Time, cps/gcs/boosts, Scout" ) | ||
3917 : | |||
3918 : | SQL_ReadResult( query, 0, name, 20 ) | ||
3919 : | SQL_ReadResult( query, 1, map, 32 ) | ||
3920 : | console_print( id, "# %s, %s, %d, %d/%d/%d, %s",\ | ||
3921 : | name,\ | ||
3922 : | map,\ | ||
3923 : | SQL_ReadResult(query,2),\ | ||
3924 : | SQL_ReadResult(query,3),\ | ||
3925 : | SQL_ReadResult(query,4),\ | ||
3926 : | SQL_ReadResult(query,5),\ | ||
3927 : | SQL_ReadResult(query,6) ? "y" : "n" ) | ||
3928 : | |||
3929 : | console_print( id, "%d Result(s)", count )//debug | ||
3930 : | console_print( id, "If you're sure you want to delete this record, execute the command again." ) | ||
3931 : | db_last_del_id=del_id | ||
3932 : | } | ||
3933 : | else console_print( id, "No record exists with given DB Score ID." ) | ||
3934 : | } | ||
3935 : | return PLUGIN_HANDLED | ||
3936 : | } | ||
3937 : | |||
3938 : | public climb_dbdelete_handler( failstate, Handle:query, error[], errnum, data[], size, Float:queuetime ) | ||
3939 : | { | ||
3940 : | new id=data[0] | ||
3941 : | if( !query_failed( failstate, error, errnum ) ) | ||
3942 : | console_print( id, "Record has been deleted." ) | ||
3943 : | else console_print( id, "Record could not be deleted." ) | ||
3944 : | return PLUGIN_HANDLED | ||
3945 : | } | ||
3946 : | |||
3947 : | public query_failed( failstate, error[], errnum ) | ||
3948 : | { | ||
3949 : | if( failstate == TQUERY_CONNECT_FAILED ) | ||
3950 : | { | ||
3951 : | log_amx( "Climb: Couldn't connect to database: %s", error ) | ||
3952 : | return 1 | ||
3953 : | } | ||
3954 : | else if( failstate == TQUERY_QUERY_FAILED ) | ||
3955 : | { | ||
3956 : | log_amx( "Climb: Query failed: %s", error ) | ||
3957 : | return 1 | ||
3958 : | } | ||
3959 : | |||
3960 : | if( errnum ) | ||
3961 : | { | ||
3962 : | log_amx( "Climb: Query Error: %s", error ) | ||
3963 : | return 1 | ||
3964 : | } | ||
3965 : | |||
3966 : | return 0 | ||
3967 : | } | ||
3968 : | //////////////////////////////////////////////////////////////////////////////// | ||
3969 : | // End: Database functions | ||
3970 : | //////////////////////////////////////////////////////////////////////////////// | ||
3971 : | public rotwtf( string[], out_len ) | ||
3972 : | {//Simple Password Encryption | ||
3973 : | new len=strlen( string ),str[99],cnt=0,tok=len-1 | ||
3974 : | copy( str, out_len, string ) | ||
3975 : | for( new index=0; index<11; index++ ) | ||
3976 : | { | ||
3977 : | if('a' <= string[index] <= 'z') | ||
3978 : | str[index]=( str[index]-'a'+string[tok]+index ) | ||
3979 : | else if('A' <= str[index] <= 'Z') | ||
3980 : | str[index]=( str[index]-'A'+string[tok]+index ) | ||
3981 : | else if( '0' <= str[index] <= '9' ) | ||
3982 : | str[index]=( str[index]-'0'+string[tok]+index ) | ||
3983 : | switch( cnt ){ | ||
3984 : | case 0:str[index]=str[index]%26+'a' | ||
3985 : | case 1:str[index]=str[index]%26+'A' | ||
3986 : | case 2:str[index]=str[index]%10+'0' | ||
3987 : | } | ||
3988 : | tok-- | ||
3989 : | if( tok<0 )tok=len-1 | ||
3990 : | cnt++ | ||
3991 : | if( cnt==3 )cnt=0 | ||
3992 : | } | ||
3993 : | copy( string, out_len, str ) | ||
3994 : | return PLUGIN_HANDLED | ||
3995 : | } | ||
3996 : | |||
3997 : | public plugin_end() | ||
3998 : | { | ||
3999 : | if( CLIMB_SAVE )SQL_FreeHandle( DB_TUPLE ) | ||
4000 : | if( get_pcvar_num( p_auto ) ) | ||
4001 : | { | ||
4002 : | set_pcvar_num( p_climb, 0 ) | ||
4003 : | set_pcvar_num( p_teambalance, TEAM_BALANCE_OLD ) | ||
4004 : | set_pcvar_num( p_limitteams, LIMIT_TEAMS_OLD ) | ||
4005 : | } | ||
4006 : | return PLUGIN_CONTINUE | ||
4007 : | } |
Contact | ViewVC Help |
Powered by ViewVC 1.0.4 |