Parent Directory | Revision Log
/* Climb v2.0a2 Copyright (C) 2006 Ian (Juan) Cammarata This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; go to http://www.opensource.org/licenses/gpl-license.php */ /* *To do: * Recalc limiter/timeout on stats pages. * Flags for weapons used * Save user/pass login data for sessions (don't require login ever map change) * Account management for accounts with user/pass login. email, change password, password recovery * Unsolid as function of position and velocity * Respawn vehicles if they go out of the map *=============================================================================== * Climb v2.0a2 * Created by Ian (Juan) Cammarata * http://ian.cammarata.us * AMXX 1.76 * 3/2/2007 1:23:06 AM *=============================================================================== * Description: * This plugin is designed for use in climbing maps like those available from * www.kreedz.com. If you want to disable this plugin for the duration of a * map you can set cvar "climb 0", this will disable the ability to make and * recall checkpoints and the automatic respawning. *=============================================================================== * Commands: * say /checkpoint : Save your position * say /gocheck : Teleport you to your last saved position * say /stuck : Teleport you to your previous checkpoint in case * you get stuck in a wall *=============================================================================== * Cvars: * climb <1|0> : Enables|Disables all climb.amx functionality. * climb_boost <1|0> : Enables|Disables boosting. * climb_cpprice <0|...> : Set to dollar amount for cost of checkpoints. * climb_startmoney <1337|0-16000> : Money amount set when players start timer. * * climb_render <0|1> : Changes unsolid rendering style, 0=classic, other=new more see through rendering. * climb_sounds <1|0> : Enables|Disables sounds build in to the Climb plugin. * * climb_webmod <0|1> : Disables|Enables web mod interoperability. * climb_stats_path <NULL|...> : Path to save generated stats pages. (If using * WebMod, enter path to webmods www folder.) * 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. * 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. * climb_stats_msg <NULL|...> : Message to display on scoreboard. Use HTML * * ip_internal <localhost|...> : Set to internal network IP or hostname. (If server behind NAT) * ip_external <localhost|...> : Set to external network IP or hostname. * * climb_msg_r <0|0-255> : Display message red value. * climb_msg_g <150|0-255> : Display message green value. * climb_msg_b <250|0-255> : Display message blue value. * climb_msg_x <0.05|0-1> : Display message x position. * climb_msg_y <0.5|0-1> : Display message y position. * * *The following cvars are only read at plugin load, changes will not take * effect until the map is changed. * climb_save <1|0> : Enables|Disables saving of stats to a database. * * climb_db_type <sqlite|mysql> : Database type. * climb_db_host <127.0.0.1> : Database host name/ip. * climb_db_user <NULL|...> : Database user name. * climb_db_pass <NULL|...> : Database password. * climb_db_name <climb|...> : Database name. * climb_db_prefix <climb_|...> : Table name prefix. *=============================================================================== * Requirements: * Modules: * Engine * Fakemeta * DB Module (MySQL or SQLite/Only need to use stats.) * AMXX 1.76 or higher *=============================================================================== * Notes: * Enjoy! *=============================================================================== * Change Log: * Key (+ added | - removed | c changed | f fixed | r refactored) * * v2.0a2 (FEB 16, 2007) * +: 2 addition boost types. Super jump and double jump. (No partner needed for boosting anymore) * +: Boosts are counted. (Not logged in DB yet.) * +: Stats saving in database. MySQL or SQLite. (MySQL not tested yet. Only works with single db module enabled) * +: Players now get rewarded for finishing even without starting the timer. * +: Cvars for message color and position. (climb_msg_r, ..._g, ..._b, ..._x, ..._y) * +: Cvar climb_startmoney - Value to set money to when players start timer. * +: Cvar climb_stats_msg - Message to display on the HTML scoreboards. * +: Cvar climb_unsolid_type - Change rendering style for unsolid players. * +: Cvar climb_sounds - Disabled Climb plugin sounds. * +: Several cvars for database settings. * +: All players spawn at spawn point closest to the start button. (Eliminates cheat in maps with a spawn point at the finish button.) * +: Additional spawns added during map load to fix maps without enough spawns. * +: Timeouts for respawning and boosting. * +: Command "help". Displays HTML help pages. * -: AMX compatability. (AMX is officially dead) * c: Cvars now prefixed with climb_ instead of amx_. * c: Minor code optimizations. * c: Command "Boost" now takes players to the boost help page instead of activating solid boost. * r: All internal cvar handling is now done with pointers. (With the acception of cvars used only during init functions.) * r: Solid boost only lasts 15 seconds at a time now since its usage is being tracked. * r: Major internal rewrite (Probably added a few bugs. More major rewrites coming in next release.) * v1.9.19 (AUG 02, 2006) * +: New public cvar 'climb_version' to aid in searching for server with this plugin. * +: Show checkpoints, gochecks, and finish stats (Stats will be more extensive in next version) with finish announcement. * -: Global chat. Use AllChat plugin instead. * -: Cvar: amx_climb_globchat * c: The /spec command now obeys the cvar "allow_spectators", clients with reserved slot always allowed. * c: Shows number of checks and gocheck on client finish announcement. * f: Bug caused by using stop command while paused. * r: Client commands reworked. Everything functions the same, but with more functionality. For example the gc command can be entered as any of the following: gc, /gc, \gc, say gc, say /gc, say \gc, say_team gc, etc... * v1.9.18 (MAY 15, 2006) * r: Recoded the way health is handled. Should work for any map now. * v1.9.17 (APR 07, 2006) * c: Plugin is now compatible with both AMX and AMXX. * c: The /spectate command can now be used by anyone. Admin no longer required. * v1.9.16a * f: Added health fix for kz_cfl_yamakasi. * c: New CSS theme for html scoreboard. * v1.9.16 * +: Counts usage of CP and GC commands(only displayed on html scoreboard). * f: Added health fix for kz_lighthouse and kz_phoogi. * v1.9.15 * +: Colorized global chat. ADMIN_RESERVATION has name in green instead of team color. * +: /stop command. Resets timer to zero, end climbing session. * c: Reset function. /stop + /respawn. Client is now reset automatically when pressing the start button if they are not already started. * f: YOU CAN'T GET STUCK ANYMORE!!! (Well almost. Doing gocheck a second time gets you unstuck.) * f: Global chat is now logged correctly and shows up in HLSW. * v1.9.14 * +: Hook is taken away when client starts timer, given back if they reset. * +: Max health fixes for several new maps. * +: Sort clients on CS scoreboard by climb rank. * +: Cvar amx_climb_boost - enable\disable boosting. * +: Cvar amx_climb_cpprice - charge money for checkpoints. * +: Custom configurable commands based on events. (climb.ini) * +: Global chat. cvar: amx_climb_globchat <1|0> * +: Client climb time is now shown using the round time HUD sprites. * -: Command /mytime, not needed because of HUD sprite timer. * -: Auto time display every 30 seconds, not needed because of HUD sprite timer. * c: Added another start button sound. * c: Super healing doors no longer removed. (Needed for shortcuts in some maps.) * f: Admins can't be alive as spectator even with 3rd party respawn plugin. * f: Keep godmode after respawning if finished map and not reset. * f: Admins VIP display on CS scoreboard is now updated whenever clients connect. * f: Health charger minimaps in kz_real_skyscraper & kz_northpole_b01. * f: Not teleporting to exact cp position if another client is on your cp. * f: Respawning outside of maps sometimes immediately after leaving spectator. */ #include <amxmodx> #include <fun> #include <amxmisc> #include <engine> #include <fakemeta> #include <sqlx> #include <string2> #include <cstrike> #include <cstrike2> #define SF_MAX 50 //Maximum number of start/finish commands in climb.ini #define VERSION "2.0a2" //DB variables new Handle:db_tuple,db_prefix[10],bool:climb_save //Client flags arrays new Float:origins[32][41],timer[32][13],time_stamps[33][2],Float:post_think_vel[32][3] //Temp save vars new steamid[32][32],savepos=0,Float:originssave[32][41],timersave[32][13] //Touch for unsolid clients new trig[100],trignum=0,brk[50],brknum=0 //Other stuff new hooked[32],hp=100 new sfactions[SF_MAX][50],sfcount=0 new score_ts,hscore_ts new dyn_spawn_ids[32],dyn_spawn_count=-1,Float:spawn_tp_orig[3] //Cvar Pointers new p_climb,p_webmod,p_boost,p_cpprice new p_msg_r,p_msg_g,p_msg_b,p_msg_x,p_msg_y new p_sounds,p_render new p_ip_internal,p_ip_external,p_port new p_allow_spectators,p_startmoney new p_stats_path,p_stats_url,p_stats_hsurl,p_stats_msg //Model size //standing 32x32x72 //crouched 32x32x36 //timestamps[id][x] #define TS_SPAWN 0 #define TS_BOOST 1 //Tasks: //#define TSK_AUTOHEAL 50 //50+ : Auto Heal //#define TSK_AUTORSPN 100 //100+: Auto Respawn //#define TSK_BOOSTTMR 150 //150+: Solid Boost Timer //timer[id][x]: #define TMR_CFLAGS 0 //Status #define TMR_STARTD 1 //Start Time #define TMR_FINISH 2 //Finish Time #define TMR_CPSCNT 3 //CP Count #define TMR_GCSCNT 4 //GC Count #define TMR_BSTTME 5 //Best Time #define TMR_BSTCPS 6 //Best CP #define TMR_BSTGCS 7 //Best GC #define TMR_SESFIN 8 //Finished this session #define TMR_MAPFIN 9 //Total times finished this map #define TMR_DBUSER 10 //Database player ID; 0=not registered; -1=not registered & shared steam id #define TMR_BOOSTS 11 //Number of boosts used #define TMR_WPNUSE 12 //Bit sum of used weapons //Status timer[id][TMR_CFLAGS]&=x #define CF_NULL 0 //Used to clear flags in change_status() and change_boost() functions #define CF_STOP (1<<0) //STATUS FLAG: Not Started #define CF_START (1<<1) //STATUS FLAG: Climbing #define CF_PAUSE (1<<2) //STATUS FLAG: Paused #define CF_SOLID (1<<3) //BOOST FLAG #define CF_SUPER_JUMP (1<<4) //BOOST FLAG #define CF_DOUBLE_JUMP (1<<5) //BOOST FLAG #define CF_SPAWN_NO_GC (1<<6) #define CF_NO_SCOUT (1<<7) #define CF_NO_VIP (1<<8) public client_putinserver(id){ if(get_pcvar_num(p_climb)&&!is_user_bot(id)){ new ida[1] ida[0]=id set_task(20.0,"connect_advert",0,ida,1) //Set CF_STOP status change_status(id,CF_STOP) //search steamid to position reference for match new searchid[32] get_user_authid(id,searchid,31) for(new i=0;i<32;i++) if(equal(searchid,steamid[i])){ //load origins & timer array if match found origins[id]=originssave[i] timer[id]=timersave[i] return PLUGIN_CONTINUE } if(climb_save&&timer[id][TMR_DBUSER]<1) set_task(5.0,"auto_login",0,ida,1) } return PLUGIN_CONTINUE } public connect_advert(ida[1]){ new id=ida[0] new msg[51] formatex(msg,50,"^x04 ^t^t^t^t^t^t^tThis server is using Climb v%s by:",VERSION) saytext(id,id,msg) saytext(id,id,"^x04 ^t^t^t^t^t^t^tIan (Juan) Cammarata (http://ian.cammarata.us)") } public auto_login(ida[1]) return client_cmd(ida[0],"login") public client_disconnect(id){ if(get_pcvar_num(p_climb)&&!is_user_bot(id)){ savepos++ if(savepos==31)savepos=0 new saveid[32] get_user_authid(id,saveid,32) //erase previous save if exists for(new i=0;i<32;i++)if(equal(saveid,steamid[i]))steamid[i]="" //save steamid to position reference steamid[savepos]=saveid //save origins originssave[savepos]=origins[id] //save timer array/Pause if running if(timer[id][TMR_CFLAGS]&CF_START)change_status(id,CF_PAUSE) timersave[savepos]=timer[id] //clear origins for new client in that slot for(new i=0;i<8;i++)origins[id][i]=0.0 for(new i=0;i<11;i++)timer[id][i]=0 hooked[id]=0 } return PLUGIN_HANDLED } public check(id){ if(get_pcvar_num(p_climb)&&isalive(id)&¬paused(id)){ new cpprice=get_pcvar_num(p_cpprice) if(cpprice>0){ new cash=cs_get_user_money(id) if(cpprice>cash){ clmsg(id,"You don't have enough cash for more checkpoints.") client_print(id,print_chat,"You don't have enough cash for more checkpoints.") return PLUGIN_HANDLED } cs_set_user_money(id,cash-cpprice) } if(!hooked[id]){ new Float:vel[3] entity_get_vector(id,EV_VEC_velocity,vel) if(vel[2]>=0){ new Float:coords[3] entity_get_vector(id,EV_VEC_origin,coords) if(coords[0]||coords[1]||coords[2]){ for(new i=39;i>3;i--) origins[id][i]=origins[id][i-4] for(new i=0;i<3;i++) origins[id][i]=coords[i] origins[id][3]=entity_get_float(id, EV_FL_gravity) new msg[100]="Checkpoint saved." if(timer[id][TMR_CFLAGS]&CF_START){ timer[id][TMR_CPSCNT]++ formatex(msg,99,"Checkpoint saved. (%d CPS/ %d GCS/ %d Boosts)",timer[id][TMR_CPSCNT],timer[id][TMR_GCSCNT],timer[id][TMR_BOOSTS]) } clmsg(id,msg) } else clmsg(id,"Can not save checkpoint at current location.") } else clmsg(id,"You can't make checkpoints while falling.") } else clmsg(id,"You can't make checkpoints while using hook.") } return PLUGIN_HANDLED } public gocheck(id){ if(get_pcvar_num(p_climb)&&isalive(id)&¬paused(id)){ if(origins[id][0]||origins[id][1]||origins[id][2]){ new Float:coords[3] for(new i=0;i<3;i++)coords[i]=origins[id][i] entity_set_float(id,EV_FL_gravity,origins[id][3]) teleport(id,coords) new msg[100]="Checkpoint restored." if(timer[id][TMR_CFLAGS]&CF_START){ timer[id][TMR_GCSCNT]++ formatex(msg,99,"Checkpoint restored. (%d CPS/ %d GCS/ %d Boosts)",timer[id][TMR_CPSCNT],timer[id][TMR_GCSCNT],timer[id][TMR_BOOSTS]) } clmsg(id,msg) } else{ clmsg(id,"You must make a checkpoint first.") return 0 } } return 1 } public stuck(id){ if(get_pcvar_num(p_climb)&&isalive(id)&¬paused(id)){ if(origins[id][4]||origins[id][5]||origins[id][6]){ new Float:coords[3] for(new i=0;i<36;i++) origins[id][i]=origins[id][i+4] for(new i=0;i<3;i++) coords[i]=origins[id][i] entity_set_float(id,EV_FL_gravity,origins[id][3]) teleport(id,coords) new msg[100]="Previous checkpoint restored." if(timer[id][TMR_CFLAGS]&CF_START){ timer[id][TMR_CPSCNT]-- formatex(msg,99,"Previous checkpoint restored. (%d CPS/ %d GCS/ %d Boosts)",timer[id][TMR_CPSCNT],timer[id][TMR_GCSCNT],timer[id][TMR_BOOSTS]) } clmsg(id,msg) new cpprice=get_pcvar_num(p_cpprice) if(cpprice>0){ new cash=cs_get_user_money(id) cs_set_user_money(id,cash+cpprice) } } else clmsg(id,"You have no previous checkpoints remaining.") } return PLUGIN_HANDLED } //Respawn client when they die public death_msg(){ if (get_pcvar_num(p_climb)){ new id=read_data(2) new ida[1] ida[0]=id if(task_exists(100+id))remove_task(100+id) if(isct(id)){ set_task(0.2,"respawn",100+id,ida,1) } } return PLUGIN_HANDLED } public change_status(id,newstat){ new cflags=timer[id][TMR_CFLAGS] if(cflags&CF_STOP)timer[id][TMR_CFLAGS]-=CF_STOP else if(cflags&CF_START)timer[id][TMR_CFLAGS]-=CF_START else if(cflags&CF_PAUSE)timer[id][TMR_CFLAGS]-=CF_PAUSE if(newstat&CF_PAUSE){ if(cflags&CF_PAUSE){ timer[id][TMR_CFLAGS]+=CF_START timer[id][TMR_STARTD]=get_systime()-timer[id][TMR_STARTD] set_entity_flags(id,FL_FROZEN,0) unsolid(id) entity_set_float(id,EV_FL_gravity,origins[id][40]) clmsg(id,"UNPAUSED") } else if(cflags&CF_START){ cl_pause(id) timer[id][TMR_CFLAGS]+=CF_PAUSE } else{ clmsg(id,"You must start the timer before you can pause.") timer[id][TMR_CFLAGS]=cflags } } else timer[id][TMR_CFLAGS]+=newstat return PLUGIN_HANDLED } public cl_pause(id){ timer[id][TMR_STARTD]=get_systime()-timer[id][TMR_STARTD] set_entity_flags(id,FL_FROZEN,1) unsolid(id) set_rendering(id,kRenderFxGlowShell,0,0,255,kRenderTransColor,1) origins[id][40]=entity_get_float(id,EV_FL_gravity) entity_set_float(id,EV_FL_gravity,0.0) clmsg(id,"PAUSED") return PLUGIN_HANDLED } public stop(id){ if(get_pcvar_num(p_climb)&&timer[id][TMR_CFLAGS]&CF_START/*&¬paused(id)*/){ change_status(id,CF_STOP) sfexec(id,4) //Execute commands from start/finish config } return PLUGIN_HANDLED } public reset(id){ if(get_pcvar_num(p_climb)&&check_timeout(id,get_systime(),time_stamps[id][TS_SPAWN],5)){ stop(id) frespawn(id) } return PLUGIN_HANDLED } public frespawn(id){ if(get_pcvar_num(p_climb)&&check_timeout(id,get_systime(),time_stamps[id][TS_SPAWN],5)){ if(get_user_team(id)==3)cs_set_user_team(id,2) timer[id][TMR_CFLAGS]+=CF_SPAWN_NO_GC cs_user_spawn(id) } return PLUGIN_HANDLED } public respawn(ida[]){ new id=ida[0] if(!get_user_team(id)||is_user_alive(id)||!isct(id)) return PLUGIN_HANDLED cs_user_spawn(id) //gocheck(id) return PLUGIN_HANDLED } public spawned(id){ if(get_pcvar_num(p_climb)){ //Block Buying new cflags=timer[id][TMR_CFLAGS] set_msg_block(get_user_msgid("StatusIcon"),2) if(is_user_alive(id)){ //Set them to CT if they're a spectator if(get_user_team(id)==3)cs_set_user_team(id,2) sortcssb() //If they are paused freeze them again. if(cflags&CF_PAUSE)cl_pause(id) set_user_health(id,hp) //Only admins can shoot other clients. //if(!(get_user_flags(id)&ADMIN_SLAY))set_user_hitzones(id,0,0) //Keeps players from seeing eachothers names. //Remove stuff dropped on death remove_entity_name("weaponbox") remove_entity_name("item_thighpack") //Execute commands from start/finish config sfexec(id,1) //Show admin as VIP on Scoreboard. if(get_user_flags(id)&ADMIN_SLAY)cs_set_user_scoreattrib(id,4) //Equip Task new ida[1] ida[0]=id set_task(0.1,"equip",_,ida,1) time_stamps[id][TS_SPAWN]=get_systime() //Teleport to safe place/old primary spawn position if(cflags&CF_SPAWN_NO_GC){ if(vector_distance(spawn_tp_orig,Float:{0,0,0}))teleport(id,spawn_tp_orig) timer[id][TMR_CFLAGS]-=CF_SPAWN_NO_GC } else if(!gocheck(id))if(!(cflags&CF_START&&!getusertime(id)))if(vector_distance(spawn_tp_orig,Float:{0,0,0}))teleport(id,spawn_tp_orig) } } else set_msg_block(get_user_msgid("StatusIcon"),0) return PLUGIN_CONTINUE } public equip(ida[]){ //Give equipment to client, delayed to prevent crash new id=ida[0] for(new i=0;i<2;i++)give_item(id,"weapon_scout") give_item(id,"weapon_c4") cs_set_user_nvg(id) } public check_timeout(id,time1,time2,freq){ if(time1<time2)return 1 new dif=time1-time2 if(dif<freq){ new msg[76] format(msg,75,"You must wait %d more seconds to use this command again.",freq-dif) if(id>0)clmsg(id,msg) return 0 } return 1 } public change_boost(id,newboost){ //Change Boost flags if(!(cvar_enabled(id,p_boost)&&isalive(id))&¬paused(id))return PLUGIN_HANDLED new msg[151],rmflag,cflags=timer[id][TMR_CFLAGS] if(cflags&CF_SOLID){ if(task_exists(150+id))remove_task(150+id) rmflag=CF_SOLID msg="Solid Boost Disabled.^n" } else if(cflags&CF_SUPER_JUMP){ rmflag=CF_SUPER_JUMP msg="Super Jump Disabled.^n" } else if(cflags&CF_DOUBLE_JUMP){ rmflag=CF_DOUBLE_JUMP msg="Double Jump Disabled.^n" } if(rmflag>0)timer[id][TMR_CFLAGS]-=rmflag if(!(rmflag&newboost)&&check_timeout(id,(cflags&CF_START?getusertime(id):get_systime()),time_stamps[id][TS_BOOST],5)){ if(newboost==CF_SOLID){ format(msg,150,"%sSolid Boost Enabled.",msg) new ida[1] ida[0]=id set_task(15.0,"solid_boost_timer",150+id,ida,1) if(timer[id][TMR_CFLAGS]&CF_START)timer[id][TMR_BOOSTS]++ } if(newboost==CF_SUPER_JUMP)format(msg,150,"%sSuper Jump Enabled.",msg) if(newboost==CF_DOUBLE_JUMP)format(msg,150,"%sDouble Jump Enabled.",msg) timer[id][TMR_CFLAGS]+=newboost } if(strlen(msg))clmsg(id,msg) return PLUGIN_HANDLED } public solid_boost_timer(ida[]){ //Task to auto disable solid boost after timeout //if(timer[id][TMR_CFLAGS]&CF_SOLID)solid_boost(id) //Shouldn't need the if statement change_boost(ida[0],CF_SOLID) return PLUGIN_HANDLED } //Semi-clip, and entity touch detection for non-solid clients //* Maybe move this to client prethink public server_frame(){ if(get_pcvar_num(p_climb)){ new players[32],num,i,j,Float:c1[3],Float:c2[3] new Float:c1z[3],Float:c2z[3] new id_i,id_j,cflags_i,cflags_j get_players(players,num,"ac") if(trignum){ for(i=0;i<num;i++){ id_i=players[i] if(!playersolid(id_i)){ for(j=0;j<trignum;j++){ id_j=trig[j] entity_get_vector(id_j,EV_VEC_absmin,c2) entity_get_vector(id_j,EV_VEC_absmax,c2z) entity_get_vector(id_i,EV_VEC_origin,c1) if(c2[0]<=c1[0]&&c2z[0]>=c1[0]&&c2[1]<=c1[1]&&c2z[1]>=c1[1]&&c2[2]<=c1[2]&&c2z[2]>=c1[2]){ fake_touch(id_j,id_i) j=trignum } } } } } if(brknum){ for(i=0;i<num;i++){ id_i=players[i] if(!playersolid(id_i)){ for(j=0;j<brknum;j++){ id_j=brk[j] entity_get_vector(id_j,EV_VEC_absmin,c2) entity_get_vector(id_j,EV_VEC_absmax,c2z) entity_get_vector(id_i,EV_VEC_origin,c1) c1[0]-=26 c1z[0]=c1[0]+32 c1[1]-=16 c1z[1]=c1[1]+32 c1[2]-=40 c1z[2]=c1[2]+50 if(((c2[0]<c1[0]<c2z[0])||(c2[0]<c1z[0]<c2z[0])||(c1[0]<c2[0]<c1z[0])||(c1[0]<c2z[0]<c1z[0])) &&((c2[1]<c1[1]<c2z[1])||(c2[1]<c1z[1]<c2z[1])||(c1[1]<c2[1]<c1z[1])||(c1[1]<c2z[1]<c1z[1])) &&((c2[2]<c1[2]<c2z[2])||(c2[2]<c1z[2]<c2z[2])||(c1[2]<c2[2]<c1z[2])||(c1[2]<c2z[2]<c1z[2])) ){ fake_touch(id_j,id_i) j=brknum } } } } } c1z[0]=0.0 c1z[1]=0.0 c2z[0]=0.0 c2z[1]=0.0 //new Float:c1d[3],Float:c2d[3],xyadd,zadd for(i=0;i<num;i++){ id_i=players[i] cflags_i=timer[id_i][TMR_CFLAGS] if(!(cflags_i&CF_PAUSE)){ //solid(players[i]) entity_get_vector(id_i,EV_VEC_origin,c1) //entity_get_vector(players[i],EV_VEC_velocity,c1d) c1z[2]=c1[2] c1[2]=0.0 for(j=0;j<num;j++){ id_j=players[j] cflags_j=timer[id_j][TMR_CFLAGS] if(!(cflags_j&CF_SOLID)&&i!=j){ entity_get_vector(id_j,EV_VEC_origin,c2) //entity_get_vector(players[j],EV_VEC_velocity,c2d) c2z[2]=c2[2] c2[2]=0.0 if(vector_distance(c1,c2)<90&&vector_distance(c1z,c2z)<110){ if(!(cflags_i&CF_SOLID&&cflags_j&CF_SOLID)){//&&vector_distance(c1,c2)>25&&vector_distance(c1z,c2z)>30)){ unsolid(id_i) unsolid(id_j) j=num } } } if(j+1==num)solid(id_i) } } } } return PLUGIN_CONTINUE } public client_PreThink(id){ if(!(get_pcvar_num(p_climb)&&get_pcvar_num(p_boost)&&isalive(id)))return PLUGIN_CONTINUE new cflags=timer[id][TMR_CFLAGS],bool:onground=false if(get_entity_flags(id)&FL_ONGROUND)onground=true if(get_user_button(id)&IN_JUMP){ if(cflags&CF_SUPER_JUMP&&onground){ entity_get_vector(id,EV_VEC_velocity,post_think_vel[id]) if(post_think_vel[id][0]!=0.0||post_think_vel[id][1]!=0.0){ velocity_by_aim(id,600,post_think_vel[id]) if(post_think_vel[id][2]<250.0)post_think_vel[id][2]=250.0 if(post_think_vel[id][2]>350.0)post_think_vel[id][2]=350.0 } else post_think_vel[id]=Float:{0.0,0.0,0.0} } else if(cflags&CF_DOUBLE_JUMP){ if(!onground&&!(get_user_oldbutton(id)&IN_JUMP)){ entity_get_vector(id,EV_VEC_velocity,post_think_vel[id]) if(is_finished(id)||post_think_vel[id][2]>-500)post_think_vel[id][2]=250.0 else post_think_vel[id]=Float:{0.0,0.0,0.0} } } } return PLUGIN_CONTINUE } public client_PostThink(id){ if(!(get_pcvar_num(p_climb)&&get_pcvar_num(p_boost)&&isalive(id)))return PLUGIN_CONTINUE if(_:get_distance(_:post_think_vel[id],{0,0,0})){ entity_set_vector(id,EV_VEC_velocity,post_think_vel[id]) post_think_vel[id]=Float:{0.0,0.0,0.0} if(timer[id][TMR_CFLAGS]&CF_START){ timer[id][TMR_BOOSTS]++ //Increment client boost count time_stamps[id][TS_BOOST]=getusertime(id) //Timeout based on timer so they can't pause to avoid timeout change_boost(id,CF_NULL) } else if(!is_finished(id)){ time_stamps[id][TS_BOOST]=get_systime() change_boost(id,CF_NULL) } } return PLUGIN_CONTINUE } public is_finished(id){ new cflags=timer[id][TMR_CFLAGS] if(cflags&CF_STOP&&(get_user_flags(id)&ADMIN_RESERVATION||timer[id][TMR_SESFIN]>0)) return 1 return 0 } public traceline(Float:v1[3], Float:v2[3], noMonsters, entity){ if(get_pcvar_num(p_climb)){ new id=entity new entity2=get_tr(TR_pHit) if(id>0&&entity2>0){ if(is_user_alive(id)){ new class[32] entity_get_string(entity2,EV_SZ_classname,class,32) new Float:orig1[3],Float:orig2[3] entity_get_vector(id,EV_VEC_origin,orig1) get_brush_entity_origin(entity2,orig2) //if(get_user_button(id)&IN_USE&&get_user_aiming(id,a,b)<70&&equal(class,"func_button")){ if(get_user_button(id)&IN_USE&&vector_distance(orig1,orig2)<95&&equal(class,"func_button")){ new targ[32] entity_get_string(entity2,EV_SZ_target,targ,32) //Timer Start //if((!(timer[id][TMR_CFLAGS]&CF_START)||getusertime(id)>4)&&/*(timer[id][TMR_CFLAGS]&CF_STOP||timer[id][TMR_CFLAGS]==TMR_CFLAGS_FNSH)&&(*/equal(targ,"counter_start")||equal(targ,"clockstartbutton")||equal(targ,"firsttimerelay")/*)*/){ if((!(timer[id][TMR_CFLAGS]&CF_START)||check_timeout(id,get_systime(),time_stamps[id][TS_SPAWN],5))&&(equal(targ,"counter_start")||equal(targ,"clockstartbutton")||equal(targ,"firsttimerelay"))){ new Float:orig[3],Float:view[3] //Erase checkpoints for(new i=0;i<8;i++)origins[id][i]=0.0 //Set all associated variables timer[id][TMR_STARTD]=get_systime() change_status(id,CF_START) timer[id][TMR_CPSCNT]=0 timer[id][TMR_GCSCNT]=0 timer[id][TMR_BOOSTS]=0 //Respawn client to clear items. entity_get_vector(id,EV_VEC_origin,orig) entity_get_vector(id,EV_VEC_angles,view) cs_user_spawn(id) entity_set_vector(id,EV_VEC_origin,orig) entity_set_vector(id,EV_VEC_angles,view) delay_duck(id) cs_set_user_money(id,get_pcvar_num(p_startmoney)) //Play random start sound and text messages if(get_pcvar_num(p_sounds))switch(random_num(0,2)){ case 0:client_cmd(id,"spk barney/beertopside") case 1:client_cmd(id,"spk scientist/c3a2_sci_portopen") case 2:client_cmd(id,"spk barney/c1a2_ba_climb") } //Disable Boosts change_boost(id,CF_NULL) time_stamps[id][TS_BOOST]=0 clmsg(id,"Timer started. Go Go Go!!!") client_print(id,print_chat,"Timer started. Go Go Go!!!") //Update frags to reorder scoreboard sortcssb() //If stats save enabled warn unregistered clients to register if(climb_save)regwarn(id) //Execute commands from start/finish config sfexec(id,2) time_stamps[id][TS_SPAWN]=get_systime() } //Timer Stop else if(equal(targ,"counter_off")||equal(targ,"clockstopbutton")||equal(targ,"clockstop")){ if(timer[id][TMR_CFLAGS]&CF_START){ //Set client variables timer[id][TMR_FINISH]=get_systime() change_status(id,CF_STOP) timer[id][TMR_SESFIN]++ timer[id][TMR_MAPFIN]++ //Update frags to reorder scoreboard sortcssb() //Announce to client if(get_pcvar_num(p_sounds))client_cmd(0,"spk woop") clmsg(id,"Congratulations 1337 climber.") client_print(id,print_chat,"Congratulations 1337 climber.") new name[32],msg[21] formatex(msg,sizeof(msg)-1,"%s^t%s",getuserstatus(id),parsetime(getusertime(id))) //clmsg(id,msg) //client_print(id,print_chat,msg) //Announce to all get_user_name(id,name,32) client_print(0,print_chat,"%s^t%s^t(%d CPS/ %d GCS/ %d Boosts)^tCompleted (%d, %d)",name,msg,timer[id][TMR_CPSCNT],timer[id][TMR_GCSCNT],timer[id][TMR_BOOSTS],timer[id][TMR_SESFIN],timer[id][TMR_MAPFIN]) //If new record if(getusertime(id)<timer[id][TMR_BSTTME]||timer[id][TMR_BSTTME]==0){ timer[id][TMR_BSTTME]=getusertime(id) timer[id][TMR_BSTCPS]=timer[id][TMR_CPSCNT] timer[id][TMR_BSTGCS]=timer[id][TMR_GCSCNT] } //Execute commands from start/finish config sfexec(id,2) //If stats enabled, warn unregistered clients to register, or save for registered clients if(climb_save) if(!regwarn(id)) db_save(id) } else if(timer[id][TMR_CFLAGS]&CF_STOP&&timer[id][TMR_SESFIN]==0){ //change_status(id,CF_FINISH) timer[id][TMR_SESFIN]++ new msg[100]="Congratulations, you finished! But you didn't start the timer. :(" clmsg(id,msg) client_print(id,print_chat,msg) //Execute commands from start/finish config sfexec(id,2) //If stats save enabled warn unregistered clients to register if(climb_save)regwarn(id) } } } } } } return PLUGIN_CONTINUE } //Execute commands from start/finish config public sfexec(id,clevent){ new clstat[3],cflags=timer[id][TMR_CFLAGS] /*switch(timer[id][TMR_CFLAGS]){ case TMR_CFLAGS_STOP: clstat="ns" case TMR_CFLAGS_STRT: clstat="st" case TMR_CFLAGS_FNSH: clstat="fn" }*/ if(is_finished(id))clstat="fn" else if(cflags&CF_STOP)clstat="ns" else if(cflags&CF_START)clstat="st" //else if(timer[id][TMR_CFLAGS]&CF_FINISH)clstat="fn" //if(equal(clstat,"ns")&&(get_user_flags(id)&ADMIN_RESERVATION||timer[id][TMR_SESFIN]>0))clstat="fn" for(new i=0;i<sfcount;i++){ new cmdstat[3],cmdevent[2],cmdtype[3],cmd[60],idtype[5] parse(sfactions[i],cmdstat,2,cmdevent,1,cmdtype,2,cmd,sizeof(cmd)-1,idtype,4) if((equali(cmdstat,clstat)||equali(cmdstat,"ay"))&&str_to_num(cmdevent)&clevent){ if(equali(cmdtype,"sc")){ if(equali(idtype,"uid"))format(cmd,sizeof(cmd)-1,cmd,get_user_userid(id)) else{ new name[24] get_user_name(id,name,sizeof(name)-1) format(name,sizeof(name),"^"%s^"",name) format(cmd,sizeof(cmd)-1,cmd,name) client_print(id,print_chat,cmd) } server_cmd(cmd) } else{ client_cmd(id,cmd) } } } return 1 } //Pad text for console score listing public pad(pad){ new j=4,str[50]="" for(new i=strlen(str);i<pad;i++){ if(j==5){ copy(str[i],1,"^t") j=0 } else copy(str[i],1," ") j++ } return str } //Update frags to reorder scoreboard public sortcssb(){ new players[32],num get_players_ordered(players,num) for(new i=0;i<num;i++){ set_user_frags(players[i],0) cs_set_user_deaths(players[i],i+1) } return 1 } //Returns array of client id's sorted by climb time public get_players_ordered(players[32],&num){ get_players(players,num,"c") //Insertion Sort clients by finished time for(new i=1;i<num;i++){ new j=i,tmp if(timer[players[i]][TMR_BSTTME]>0){ tmp=players[i] while(j>0&&(timer[players[j-1]][TMR_BSTTME]==0?18000:timer[players[j-1]][TMR_BSTTME])>timer[tmp][TMR_BSTTME]){ players[j]=players[j-1] j-- } players[j]=tmp } } //2nd Insertion Sort clients by climbing time for(new i=1;i<num;i++){ new j=i,tmp if(getusertime(players[i])>0){ tmp=players[i] while(j>0&&(getusertime(players[j-1])==0?18000:getusertime(players[j-1]))>getusertime(tmp)&&timer[players[j-1]][TMR_BSTTME]==timer[tmp][TMR_BSTTME]){ players[j]=players[j-1] j-- } players[j]=tmp } } return 1 } //Make pathname for scoreboard html files public pathname(filename[]){ new path[100] get_pcvar_string(p_stats_path,path,79) format(path,99,"%s%s",path,filename) return path } public get_limit(){ if(get_pcvar_num(p_webmod)) return 0 new url[100] get_pcvar_string(p_stats_url,url,99) if(strlen(url)) return 0 return 1 } public get_url(id,file[]){ new url[100] get_pcvar_string(p_stats_url,url,99) if(get_pcvar_num(p_webmod)){ new ip[10],iip[33],eip[33],port[10] get_user_ip(id,ip,9) get_pcvar_string(p_ip_internal,iip,32) get_pcvar_string(p_ip_external,eip,32) get_pcvar_string(p_port,port,9) if(equal(ip,"192.168.",8))format(url,99,"http://%s:%s/%s",iip,port,file) else format(url,99,"http://%s:%s/%s",eip,port,file) } else if(strlen(url)){ format(url,99,"%sclimb_scores.html",url) } return url } //Show scoreboard public climbscores(id){ if(get_pcvar_num(p_climb)){ new fpn[100],bool:limit=true,cust_msg[129] get_pcvar_string(p_stats_msg,cust_msg,128) if(!get_limit())limit=false fpn=pathname("climb_scores.html") if(get_systime()-score_ts>2){ new fh=fopen(fpn,"w") fprintf(fh,"<html><head>%s<link rel=stylesheet href=http://ian.cammarata.us/climb/sb.css></head><body><table><tr>",limit?"":"<meta http-equiv=pragma content=no-cache>") fprintf(fh,"<th height=1%%>Reg</th><th>#</th><th width=28%%>Name</th><th width=15%%>Status</th><th width=8%%>Time</th><th width=6%%>CP#</th><th width=6%%>GC#</th>") fprintf(fh,"<th width=8%%>Best</th><th width=6%%>CP#</th><th width=6%%>GC#</th><th width=10%%>Completed</th></tr><tr><td class=st colspan=11></td></tr>") //99+144+134=377 new line[251],name[33],players[32],num,tid,writen_len get_players_ordered(players,num) for(new i=1;i<=num;i++){ tid=players[i-1] if(!is_user_hltv(tid)&&is_user_connected(tid)){ get_user_name(tid,name,32) htmlspecialchars(name) formatex(line,250,"<tr%s><td height=1%>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td></tr>",i%2?"":" class='o'",timer[tid][TMR_DBUSER]>0?"y":"n",i,name,getuserstatus(tid),parsetime(getusertime(tid)),timer[tid][TMR_CPSCNT],timer[tid][TMR_GCSCNT],parsetime(timer[tid][TMR_BSTTME]),timer[tid][TMR_BSTGCS],timer[tid][TMR_BSTCPS],timer[tid][TMR_MAPFIN]) writen_len+=strlen(line) if(limit&&writen_len>(1003-strlen(cust_msg)))break fprintf(fh,line) } } //1530-150-377=1003 fprintf(fh,"<tr><td></td></tr><tr><td class=sb colspan=11></td></tr><tr><th colspan=4 height=1%>") fprintf(fh,"climb v%s by: Ian Cammarata</th><th colspan=7>%s</th></tr></table></body></html>",VERSION,cust_msg) fclose(fh) score_ts=get_systime() } if(!limit)fpn=get_url(id,"climb_scores.html") show_motd(id,fpn,"Current Scores") } return PLUGIN_HANDLED } //Show High Scores public highscores(id){ new hsurl[150],mapname[33] get_pcvar_string(p_stats_hsurl,hsurl,149) get_mapname(mapname,32) if(strlen(hsurl)){ formatex(hsurl,149,hsurl,mapname) show_motd(id,hsurl,"High Scores") return PLUGIN_HANDLED } if(get_systime()-hscore_ts>10){ new query[250],data[1] data[0]=id formatex(query,249,"select p.alias, s.fin_time, s.cps, s.gcs, s.fin_cnt from %sscores s, %splayers p where s.map_name='%s' and p.user_id=s.user_id order by s.fin_time, s.gcs, s.cps limit 20;",db_prefix,db_prefix,mapname) SQL_ThreadQuery(db_tuple,"hs_handler",query,data,1) hscore_ts=get_systime() } else{ new fpn[100],bool:limit=true if(!get_limit())limit=false fpn=pathname("climb_highscores.html") if(!limit)fpn=get_url(id,"climb_highscores.html") show_motd(id,fpn,"High Scores") } return PLUGIN_HANDLED } public hs_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){ if(failstate == TQUERY_CONNECT_FAILED) return server_print("Climb: Couldn't connect to database.") else if(failstate == TQUERY_QUERY_FAILED) return server_print("Climb: Query failed: %s",error) if(errnum) return server_print("Climb: Query Error: %s",error) new id=data[0],msg[50],num=SQL_NumResults(query) if(!num){ msg="^x04[Climb] No stats available for the current map." return saytext(id,id,msg) } new fpn[100],bool:limit=true,cust_msg[129] get_pcvar_string(p_stats_msg,cust_msg,128) if(!get_limit())limit=false fpn=pathname("climb_highscores.html") new fh=fopen(fpn,"w") fprintf(fh,"<html><head>%s<link rel=stylesheet href=http://ian.cammarata.us/climb/sb.css></head><body><table><tr>",limit?"":"<meta http-equiv=pragma content=no-cache>") fprintf(fh,"<th height=1%%>#</th><th width=45%%>Name</th><th width=20%%>Time</th><th width=10%%>CP#</th>") fprintf(fh,"<th width=10%%>GC#</th><th width=10%%>Completed</th></tr><tr><td class=st colspan=6></td></tr>") //99+88+92=279 new name[33],line[151],writen_len for(new i=1;i<=num;i++){ SQL_ReadResult(query,0,name,32) htmlspecialchars(name) formatex(line,150,"<tr%s><td height=1%>%d</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td><td>%d</td></tr>",i%2?"":" class='o'",i,name,parsetime(SQL_ReadResult(query,1)),SQL_ReadResult(query,2),SQL_ReadResult(query,3),SQL_ReadResult(query,4)) writen_len+=strlen(line) if(limit&&writen_len>(1101-strlen(cust_msg)))break fprintf(fh,line) SQL_NextRow(query) } //1530-150-279=1101 fprintf(fh,"<tr><td></td></tr><tr><td class=sb colspan=6></td></tr><tr><th colspan=2 height=1%>") fprintf(fh,"climb v %s by: Ian Cammarata</th><th colspan=4>%s</th></tr></table></body></html>",VERSION,cust_msg) fclose(fh) if(!limit)fpn=get_url(id,"climb_highscores.html") show_motd(id,fpn,"High Scores") return PLUGIN_HANDLED } //Convert seconds to time string with zero padded seconds field public parsetime(sec){ new timestr[9],mins mins=sec/60 sec=sec%60 formatex(timestr,8,"%d:%s%d",mins,sec<10?"0":"",sec) return timestr } //Calculate client climb time in seconds public getusertime(id){ new ptime,cflags=timer[id][TMR_CFLAGS] //ptime=timer[id][TMR_FINISH]-timer[id][TMR_STARTD] //if(cflags&CF_STOP&&timer[id][TMR_SESFIN]>0)ptime=ptime<10000?ptime:0 if(cflags&CF_STOP&&timer[id][TMR_SESFIN]>0)ptime=timer[id][TMR_FINISH]-timer[id][TMR_STARTD] else if(cflags&CF_STOP)ptime=0 else if(cflags&CF_START)ptime=get_systime()-timer[id][TMR_STARTD] else if(cflags&CF_PAUSE)ptime=timer[id][TMR_STARTD] return ptime } //Set clock on HUD to current climb time public hudtime(){ if(get_pcvar_num(p_climb)){ new player,players[32],num get_players(players,num,"ac") for(new i=0;i<num;i++){ player=players[i] message_begin(1,get_user_msgid("RoundTime"),{0,0,0},player) write_short(getusertime(player)+1) message_end() if(timer[player][TMR_CFLAGS]&CF_PAUSE)clmsg(player,"PAUSED") } } return 1 } //Return string describing user status public getuserstatus(id){ new msg[12] if(timer[id][TMR_CFLAGS]&CF_STOP&&timer[id][TMR_SESFIN]>0)msg="Finished" /*else switch(timer[id][TMR_CFLAGS]){ case TMR_CFLAGS_STOP: msg="Not Started" case TMR_CFLAGS_STRT: msg="Climbing" case TMR_CFLAGS_PAUS: msg="Paused" }*/ else if(timer[id][TMR_CFLAGS]&CF_STOP)msg="Not Started" else if(timer[id][TMR_CFLAGS]&CF_START)msg="Climbing" else if(timer[id][TMR_CFLAGS]&CF_PAUSE)msg="Paused" return msg } //Show Hud Message public clmsg(id, msg[]){ set_hudmessage(get_pcvar_num(p_msg_r),get_pcvar_num(p_msg_g),get_pcvar_num(p_msg_b),get_pcvar_float(p_msg_x),get_pcvar_float(p_msg_y),0,0.0,5.0,0.5,0.5,4) show_hudmessage(id,msg) return PLUGIN_HANDLED } //Make client solid public solid(id){ set_user_rendering(id,kRenderFxNone,0,0,0,kRenderNormal,255) entity_set_int(id,EV_INT_solid,SOLID_BBOX) return PLUGIN_CONTINUE } //Make client unsolid public unsolid(id){ if(get_pcvar_num(p_render))set_user_rendering(id,kRenderFxPulseSlow,0,0,0,kRenderTransTexture,50) else set_user_rendering(id,kRenderFxHologram,0,0,0,kRenderTransAdd,0) entity_set_int(id,EV_INT_solid,SOLID_NOT) return PLUGIN_CONTINUE } //Check client solid public playersolid(id){ if(entity_get_int(id,EV_INT_solid)==SOLID_BBOX)return 1 return 0 } //Use in IF statements to automatically print error if false public isalive(id){ if(is_user_alive(id))return 1 clmsg(id,"You must be alive to execute this command.") return 0 } //Use in IF statements to automatically print error if false public notpaused(id){ if(!(timer[id][TMR_CFLAGS]&CF_PAUSE))return 1 clmsg(id,"You can't execute this command while paused.") return 0 } //Used in IF statements a lot public isct(id){ if(get_user_team(id)==2)return 1 return 0 } //Called when client takes damage public damage(id){ new ida[1] ida[0]=id set_task(0.1,"damage_handle",_,ida,1) } //Damage hander, delayed to provide HUD consistency public damage_handle(ida[1]){ new id=ida[0] if(get_pcvar_num(p_climb)&&is_user_alive(id)){ new chp=get_user_health(id) if(chp!=hp){ new wpn,atk=get_user_attacker(id,wpn) //Heal hp immediately if((atk==0||(id==atk&&wpn==0))&&!task_exists(50+id))set_user_health(id,hp) //Heal delayed else{ if(task_exists(50+id))remove_task(50+id) set_task(5.0,"heal",50+id,ida,1) //Fix hp display at 0 if(chp==256)set_user_health(id,257) } } else if(task_exists(50+id))remove_task(50+id) } return PLUGIN_HANDLED } //Heal client to predetermined HP required by map public heal(ida[]){ if(is_user_alive(ida[0]))set_user_health(ida[0],hp) return PLUGIN_HANDLED } public pfn_keyvalue(ent){ static bool:first_run=true new temp_ent if(first_run){ for(new i=0;i<32;i++){ temp_ent=create_entity("info_player_start") if(temp_ent>0){ dyn_spawn_count++ dyn_spawn_ids[dyn_spawn_count]=temp_ent entity_set_int(temp_ent,EV_INT_iuser1,1) //DispatchKeyValue(temp_ent,"origin","0 0 0") //DispatchKeyValue(temp_ent,"angles","0 0 0") } } first_run=false } /*static bool:got_first=false,bool:done=false,first_id,first_orig[21],first_angle[21] new class[26],key[26],val[26] copy_keyvalue(class,25,key,25,val,25) if(equal(class,"info_player_start")&&is_valid_ent(ent)){ if(!done){ if(!got_first){ console_print(0,"DEBUG: Got First") first_id=ent got_first=true } if(got_first&&!done&&ent==first_id){ if(equal(key,"origin"))copy(first_orig,20,val) else if(equal(key,"angles"))copy(first_angle,20,val) if(strlen(first_orig)&&strlen(first_angle)){ done=true console_print(0,"DEBUG: orig:%s angle:%s",first_orig,first_angle) new i,sp for(i=0;i<31;i++){ sp=create_entity("info_player_start") if(ent>0){ entity_set_int(sp,EV_INT_iuser1,1) DispatchKeyValue(sp,"origin",first_orig) DispatchKeyValue(sp,"angles",first_angle) } } } } } if(done&&entity_get_int(ent,EV_INT_iuser1)!=1)remove_entity(ent) }*/ return PLUGIN_CONTINUE } public plugin_cfg(){ //fix timer built into map set_cvar_num("sv_restartround",1) set_cvar_num("sv_gravity",800) new ent,count=0,tmpstr[32],Float:tmpflt get_mapname(tmpstr,32) //map specific fixes : real gravity in nasa maps instead of trigger_push brush. if(equali(tmpstr,"kz_man_nasa")||equali(tmpstr,"kz_man_eznasa")){ remove_entity_name("trigger_push") set_cvar_num("sv_gravity",500) } //Non-Solid check: *trigger_teleport,trigger_once,trigger_gravity,trigger_push //trigger_teleport ent=find_ent_by_class(-1,"trigger_teleport") while(ent>0){ trig[trignum]=ent trignum++ ent=find_ent_by_class(ent,"trigger_teleport") } //trigger_gravity ent=find_ent_by_class(-1,"trigger_gravity") while(ent>0){ trig[trignum]=ent trignum++ ent=find_ent_by_class(ent,"trigger_gravity") } //trigger_once /* ent=find_ent_by_class(-1,"trigger_once") while(ent>0){ trig[trignum]=ent trignum++ ent=find_ent_by_class(ent,"trigger_once") } //trigger_push ent=find_ent_by_class(-1,"trigger_push") while(ent>0){ trig[trignum]=ent trignum++ ent=find_ent_by_class(ent,"trigger_push") }*/ //server_print("***** %d trigger entities found *****",trignum) //Remove neg dmg: *trigger_hurt,*func_door //func_door neg dmg removal ent=find_ent_by_class(-1,"func_door") while(ent>0){ tmpflt=entity_get_float(ent,EV_FL_dmg) if(tmpflt<0){ count++ hp=floatround(tmpflt) remove_entity(ent) ent=-1 } ent=find_ent_by_class(ent,"func_door") } server_print("***** %d neg dmg func_door entities removed *****",count) //trigger_hurt neg dmg removal count=0 ent=find_ent_by_class(-1,"trigger_hurt") while(ent>0){ tmpflt=entity_get_float(ent,EV_FL_dmg) if(tmpflt<0){ count++ hp=floatround(tmpflt) remove_entity(ent) ent=-1 } ent=find_ent_by_class(ent,"trigger_hurt") } server_print("***** %d neg dmg trigger_hurt entities removed *****",count) hp=abs(hp) hp=clamp(hp,100,511) //Healing door trigger button removal count=0 ent=find_ent_by_class(-1,"func_button") while(ent>0){ entity_get_string(ent,EV_SZ_target,tmpstr,32) if(containi(tmpstr,"heal")>-1||containi(tmpstr,"goddoor")>-1){ count++ remove_entity(ent) ent=-1 } ent=find_ent_by_class(ent,"func_button") } server_print("***** %d healing door buttons entities removed *****",count) //func_breakables ent=find_ent_by_class(-1,"func_breakable") while(ent>0){ if(entity_get_int(ent,EV_INT_spawnflags)==2){ brk[brknum]=ent brknum++ } ent=find_ent_by_class(ent,"func_breakable") } server_print("***** %d func_breakable entities found *****",brknum) //Remove unneeded entities if it's a climbing map. count=0 new bool:has_start_button=false,Float:sb_orig[3] ent=find_ent_by_class(-1,"func_button") while(ent>0){ entity_get_string(ent,EV_SZ_target,tmpstr,32) if(equal(tmpstr,"counter_start")||equal(tmpstr,"clockstartbutton")||equal(tmpstr,"firsttimerelay")){ has_start_button=true get_brush_entity_origin(ent,sb_orig) break } ent=find_ent_by_class(ent,"func_button") } if(has_start_button){ remove_entity_name("player_weaponstrip") remove_entity_name("armoury_entity") remove_entity_name("info_player_deathmatch") get_mapname(tmpstr,32) //Health chargers needed for some maps as climbing platforms, don't remove //if(!(equali(tmpstr,"kz_real_skyscraper")||equali(tmpstr,"kz_northpole_b01")))remove_entities("func_healthcharger") count++ //Remove map built in start button sounds ent=find_ent_by_class(-1,"ambient_generic") while(ent>0){ entity_get_string(ent,EV_SZ_targetname,tmpstr,32) if(equal(tmpstr,"counter_start")||equal(tmpstr,"clockstartbutton")||equal(tmpstr,"firsttimerelay")){ remove_entity(ent) } ent=find_ent_by_class(ent,"ambient_generic") } //Count original map spawns and remove extra dyn created spawns new map_spawns[32][2],map_spawns_count,Float:orig[3] ent=find_ent_by_class(-1,"info_player_start") while(ent>0&&map_spawns_count<32){ if(entity_get_int(ent,EV_INT_iuser1)!=1){ entity_get_vector(ent,EV_VEC_origin,orig) map_spawns[map_spawns_count][0]=floatround(vector_distance(orig,sb_orig)) map_spawns[map_spawns_count][1]=ent map_spawns_count++ while(dyn_spawn_count>=0){ entity_get_string(dyn_spawn_ids[dyn_spawn_count],EV_SZ_classname,tmpstr,31) if(equal(tmpstr,"info_player_start")&&entity_get_int(dyn_spawn_ids[dyn_spawn_count],EV_INT_iuser1)==1){ remove_entity(dyn_spawn_ids[dyn_spawn_count]) dyn_spawn_count-- break } else dyn_spawn_count-- } } ent=find_ent_by_class(ent,"info_player_start") } //Save origin of spawn closest to start and arrange all spawn points to positions of the next 4 closest //SortCustom2D(map_spawns,map_spawns_count,"spawn_distance_sort"); SortStrings(map_spawns,map_spawns_count) entity_get_vector(map_spawns[0][1],EV_VEC_origin,spawn_tp_orig) //remove_entity(map_spawns[0][1]) entity_set_vector(map_spawns[0][1],EV_VEC_origin,Float:{0,0,0}) for(new i=5;i<map_spawns_count;i++)//normal i=5 entity_set_vector(map_spawns[i][1],EV_VEC_origin,Float:{0,0,0}) /*new Float:orig2[3],i entity_get_vector(map_spawns[1][1],EV_VEC_origin,orig) entity_get_vector(map_spawns[2][1],EV_VEC_origin,orig2) for(i=3;i<map_spawns_count;i++){ if((i/2)==(i%2))entity_set_vector(map_spawns[i][1],EV_VEC_origin,orig) else entity_set_vector(map_spawns[i][1],EV_VEC_origin,orig2) }*/ } else{ while(dyn_spawn_count>=0){ ent=dyn_spawn_ids[dyn_spawn_count] entity_get_string(ent,EV_SZ_classname,tmpstr,31) //entity_get_string(dyn_spawn_ids[i],EV_SZ_classname,tmpstr,31) if(equal(tmpstr,"info_player_start")&&entity_get_int(ent,EV_INT_iuser1)==1)remove_entity(ent) dyn_spawn_count-- } } return PLUGIN_CONTINUE } /*public spawn_distance_sort(elem1[],elem2[]){ if(elem1[1]<elem2[1])return -1 if(elem1[1]>elem2[1])return 1 return 0 }*/ //Future use, to block hook, or detect hook cheaters a.k.a. hookers public phook(id){ hooked[id]=1 return PLUGIN_CONTINUE } public mhook(id){ hooked[id]=0 return PLUGIN_CONTINUE } //Make a public viewable help page for this on my web host. public climb_help(id){ if(get_pcvar_num(p_climb)){ show_motd(id,"http://ian.cammarata.us/climb/help/2a2/","Climb Plugin Help") } return PLUGIN_HANDLED } public boost_help(id){ if(get_pcvar_num(p_climb)){ show_motd(id,"http://ian.cammarata.us/climb/help/2a2/boost.html","Climb Plugin Help") } return PLUGIN_HANDLED } //Force client to CT public menuteam(id){ if(get_pcvar_num(p_climb))client_cmd(id,"slot2") return PLUGIN_CONTINUE } //Force client to choose random model public menuclass(id){ if(get_pcvar_num(p_climb)){ client_cmd(id,"slot5") } return PLUGIN_CONTINUE } //Used to teleport clients, prevents client collisions and getting stuck public teleport(id,Float:orig[3]){ new Float:c2[3],player,players[32],num get_players(players,num,"ac") unsolid(id) for(new i=0;i<num;i++){ player=players[i] if(id!=player){ entity_get_vector(player,EV_VEC_origin,c2) if(vector_distance(orig,c2)<74)unsolid(player) } } entity_set_vector(id,EV_VEC_velocity,Float:{0.0, 0.0, 0.0}) entity_set_vector(id,EV_VEC_origin,orig) delay_duck(id) return 1 } //Used by teleport and traceline-timer start, prevents getting stuck public delay_duck(id){ new ida[1] ida[0]=id set_task(0.01,"force_duck",_,ida,1) set_entity_flags(ida[0],FL_DUCKING,1) } //Task for delay_duck public force_duck(ida[1]){ set_entity_flags(ida[0],FL_DUCKING,1) } //Use in IF statements to automatically print error if false public cvar_enabled(id,p_cvar){ if(get_pcvar_num(p_cvar)==0){ clmsg(id,"This command is disabled.") client_print(id,print_chat,"This command has been disabled by the server administrator.") return 0 } return 1 } //Admin command, teleport to client public goto_player(id,level,cid){ if(cmd_access(id,level,cid,2)&&get_pcvar_num(p_climb)){ new tid,arg[24] read_argv(1,arg,sizeof(arg)-1) tid=cmd_target(tid,arg,4) if(tid){ new Float:orig[3] entity_get_vector(tid,EV_VEC_origin,orig) teleport(id,orig) } } return PLUGIN_HANDLED } //Move yourself to spectator public spectate(id){ if(get_pcvar_num(p_climb)&&(get_user_flags(id)&ADMIN_RESERVATION?1:(cvar_enabled(id,p_allow_spectators)))){ cs_set_user_team(id,3) set_msg_block(get_user_msgid("DeathMsg"),1) user_kill(id,1) } return PLUGIN_HANDLED } //Block client kill command public client_kill(id){ if(get_pcvar_num(p_climb)==1)return PLUGIN_HANDLED return PLUGIN_CONTINUE } //Used to block some commands public block_cmd(id){ if(get_pcvar_num(p_climb))return PLUGIN_HANDLED return PLUGIN_CONTINUE } public block_cmd2(id){ return PLUGIN_HANDLED } //Block client trying to switch teams public block_jointeam(id){ if(get_pcvar_num(p_climb)&&isct(id))return PLUGIN_HANDLED return PLUGIN_CONTINUE } //Forward to catch all formats for commands public client_command(id){ if(!get_pcvar_num(p_climb)) return PLUGIN_CONTINUE new cmd[21] read_argv(0,cmd,20) //If say command replace command with say text, abort if more than one word if(equal(cmd,"say")||equal(cmd,"say_team")){ read_argv(1,cmd,20) trim(cmd) if(contain(cmd," ")>-1)return PLUGIN_CONTINUE } //Remove slashes if(equal(cmd,"/",1)||equal(cmd,"\",1)||equal(cmd,".",1)||equal(cmd,"!",1))copy(cmd,20,cmd[1]) //Make a checkpoint if(equali(cmd,"checkpoint")||equali(cmd,"check")||equali(cmd,"cp"))check(id) //Go to checkpoint else if(equali(cmd,"gocheck")||equali(cmd,"gc")||equali(cmd,"tp")||equali(cmd,"tele"))gocheck(id) //Boost help page else if(equali(cmd,"boost"))boost_help(id) //Solid Boost else if(equali(cmd,"solid")||equali(cmd,"semiclip"))change_boost(id,CF_SOLID) //Jump Boost else if(equali(cmd,"superjump")||equali(cmd,"sjump")||equali(cmd,"sj")||equali(cmd,"longjump")||equali(cmd,"ljump")||equali(cmd,"lj"))change_boost(id,CF_SUPER_JUMP) //Double Jump Boost else if(equali(cmd,"doublejump")||equali(cmd,"djump")||equali(cmd,"dj"))change_boost(id,CF_DOUBLE_JUMP) //Stuck else if(equali(cmd,"stuck")||equali(cmd,"unstuck"))stuck(id) //Pause else if(equali(cmd,"pause")||equali(cmd,"unpause"))change_status(id,CF_PAUSE) //Restart else if(equali(cmd,"restart")||equali(cmd,"reset"))reset(id) //Stop else if(equali(cmd,"stop"))stop(id) //Time/Scores else if(equali(cmd,"scoreboard")||equali(cmd,"score")||equali(cmd,"scores"))climbscores(id) //Top Scores else if(equali(cmd,"top10")||equali(cmd,"top15")||equali(cmd,"top")||equali(cmd,"highscores")||equali(cmd,"best")||equali(cmd,"rank"))highscores(id) //Respawn else if(equali(cmd,"respawn")||equali(cmd,"spawn"))frespawn(id) //Spectate else if(equali(cmd,"spectate")||equali(cmd,"spec"))spectate(id) //Climb Help else if(equali(cmd,"help")||equali(cmd,"climbhelp")||equali(cmd,"kzhelp"))climb_help(id) //If none of above conditions met, don't block the command else return PLUGIN_CONTINUE return PLUGIN_HANDLED } public donothing(){ return PLUGIN_CONTINUE } public regwarn(id){ if(timer[id][TMR_DBUSER]<1){ saytext(id,id,"^x04You must register/login for your stats to save. Say /help for more info.") return 1 } return 0 } public db_init(){ //update from old db version //alter table climb_scores add boosts int //alter table climb_scores add wpns int //alter table climb_scores add score int //update climb_scores set boosts=-1 //update climb_scores set wpns=-1 static host[32],user[32],pass[32],name[32],type[12] get_cvar_string("climb_db_host",host,31) get_cvar_string("climb_db_user",user,31) get_cvar_string("climb_db_pass",pass,31) get_cvar_string("climb_db_name",name,31) get_cvar_string("climb_db_type",type,11) get_cvar_string("climb_db_prefix",db_prefix,31) //SQL_SetAffinity(type) db_tuple=SQL_MakeDbTuple(host,user,pass,name) new query[600] formatex(query,599,"\ create table %splayers (\ user_id integer primary key autoincrement,\ steam_id char(25) unique,\ password char(6),\ user_name varchar(20) unique,\ alias varchar(32) unique,\ email varchar(50) unique,\ cflags integer);\ ",db_prefix) SQL_ThreadQuery(db_tuple,"db_generic_handler",query) formatex(query,599,"\ create table %sscores (\ score_id integer primary key autoincrement,\ score integer,\ server_ip char(15),\ user_id integer,\ map_name varchar(32),\ fin_time integer,\ cps integer,\ gcs integer,\ fin_cnt integer,\ boosts integer,\ wpns integer,\ server_time_stamp integer);\ create unique index scores_usermap_idx on %sscores (user_id, map_name);\ create index scores_score on %sscores (score);\ ",db_prefix,db_prefix,db_prefix) SQL_ThreadQuery(db_tuple,"db_generic_handler",query) formatex(query,599,"\ create table %ssessions (\ steam_id char(25) primary key,\ user_id integer unique);\ ",db_prefix) SQL_ThreadQuery(db_tuple,"db_generic_handler",query) return PLUGIN_HANDLED } public db_generic_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){ if(failstate == TQUERY_CONNECT_FAILED) return server_print("Climb: Couldn't connect to database.") else if(failstate == TQUERY_QUERY_FAILED) return server_print("Climb: Query failed: %s",error) if(errnum) return server_print("Climb: Query Error: %s",error) return PLUGIN_HANDLED } public logout(id){ for(new i=0;i<8;i++)origins[id][i]=0.0 for(new i=0;i<11;i++)timer[id][i]=0 } public login(id){ if(get_pcvar_num(p_climb)){ if(climb_save){ if(timer[id][TMR_DBUSER]>0){//Already logged in client_print(id,print_console,"[Climb] Login Error: You are already logged in.") return PLUGIN_HANDLED } new query[99],data[28] data[0]=id if(read_argc()>1){//Client is logging in with a user/pass new user[21],pass[21] read_argv(1,user,20) read_argv(2,pass,20) rotwtf(pass,6) data[1]=1 formatex(query,98,"select user_id from %splayers where user_id='%s' and password='%s';",db_prefix,user,pass) formatex(data[2],25,user) SQL_ThreadQuery(db_tuple,"login_handler",query,data,28) } else{//Client is logging in with SteamID new sid[26] get_user_authid(id,sid,25) data[1]=2 formatex(query,98,"select user_id, password from %splayers where steam_id='%s';",db_prefix,sid) formatex(data[2],25,sid) SQL_ThreadQuery(db_tuple,"login_handler",query,data,28) } } else client_print(id,print_console,"[Climb] Login Error: Can't Login; Stats not enabled.") } return PLUGIN_HANDLED } public login_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){ new id=data[0] if(failstate == TQUERY_CONNECT_FAILED) return server_print("Climb: Couldn't connect to database.") else if(failstate == TQUERY_QUERY_FAILED) return server_print("Climb: Query failed: %s",error) if(errnum) return server_print("Climb: Query Error: %s",error) if(SQL_NumResults(query)<1) return client_print(id,print_console,"[Climb] Login Error: Not a valid account.") if(data[1]==2){ new pass[7] SQL_ReadResult(query,1,pass,6) if(equali(pass,"shared")){ client_print(id,print_console,"[Climb] Login Error: You are using a shared SteamID. Please login with a username and password.") return PLUGIN_HANDLED } } timer[id][TMR_DBUSER]=SQL_ReadResult(query,0) new msg[100] formatex(msg,99,"[Climb] Login: Success - Account: %s",data[2]) client_print(id,print_console,msg) format(msg,99,"^x04%s",msg) saytext(id,id,msg) db_load(id) return PLUGIN_HANDLED } public db_load(id){ new query[150],mapname[33],data[1] data[0]=id get_mapname(mapname,32) formatex(query,149,"select fin_time, cps, gcs, fin_cnt from %sscores where user_id=%d and map_name='%s';",db_prefix,timer[id][TMR_DBUSER],mapname) SQL_ThreadQuery(db_tuple,"db_load_handler",query,data,1) return PLUGIN_HANDLED } public db_load_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){ if(failstate == TQUERY_CONNECT_FAILED) return server_print("Climb: Couldn't connect to database.") else if(failstate == TQUERY_QUERY_FAILED) return server_print("Climb: Query failed: %s",error) if(errnum) return server_print("Climb: Query Error: %s",error) new msg[100],id=data[0] if(!SQL_NumResults(query)) msg="^x04No stats available for this account on the current map." else{ new mapname[33],timestr[9] get_mapname(mapname,32) timer[id][TMR_BSTTME]=SQL_ReadResult(query,0) timer[id][TMR_BSTCPS]=SQL_ReadResult(query,1) timer[id][TMR_BSTGCS]=SQL_ReadResult(query,2) timer[id][TMR_MAPFIN]=SQL_ReadResult(query,3) timestr=parsetime(timer[id][TMR_BSTTME]) formatex(msg,99,"^x04Stats loaded for %s - %s^t(%d CPS/ %d GCS)^tCompleted %d",mapname,timestr,timer[id][TMR_BSTCPS],timer[id][TMR_BSTGCS],timer[id][TMR_MAPFIN]) } saytext(id,id,msg) return PLUGIN_HANDLED } public db_save(id){ new query[150],name[33] get_mapname(name,32) if(timer[id][TMR_MAPFIN]==1) formatex(query,149,"insert into %sscores (user_id, map_name, fin_time, cps, gcs, fin_cnt)\ values (%d, '%s', %d, %d, %d, %d);\ ",db_prefix,timer[id][TMR_DBUSER],name,timer[id][TMR_BSTTME],timer[id][TMR_BSTCPS],timer[id][TMR_BSTGCS],timer[id][TMR_MAPFIN]) else formatex(query,149,"update %sscores set fin_time=%d, cps=%d, gcs=%d, fin_cnt=%d where user_id=%d and map_name='%s';",db_prefix,timer[id][TMR_BSTTME],timer[id][TMR_BSTCPS],timer[id][TMR_BSTGCS],timer[id][TMR_MAPFIN],timer[id][TMR_DBUSER],name) SQL_ThreadQuery(db_tuple,"db_save_handler",query) get_user_name(id,name,32) formatex(query,149,"update %splayers set alias='%s' where user_id=%d;",db_prefix,name,timer[id][TMR_DBUSER]) SQL_ThreadQuery(db_tuple,"db_save_handler",query) return PLUGIN_HANDLED } public db_save_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){ if(failstate == TQUERY_CONNECT_FAILED) return server_print("Climb: Couldn't connect to database.") else if(failstate == TQUERY_QUERY_FAILED) return server_print("Climb: Query failed: %s",error) if(errnum) return server_print("Climb: Query Error: %s",error) return PLUGIN_HANDLED } public reg(id){ if(get_pcvar_num(p_climb)){ if(climb_save){ new query[100],sid[26],name[33],data[43] data[0]=id data[1]=0 get_user_authid(id,sid,25) get_user_name(id,name,32) //Register user/pass if(read_argc()>1){ if(read_argc()!=3){ client_print(id,print_console,"[Climb] Registration Error: Invalid number of arguments") return PLUGIN_HANDLED } new user[21],pass[50] //Read password and check length read_argv(2,pass,20) if(strlen(pass)<10){ client_print(id,print_console,"[Climb] Registration Error: Password must be at least 10 characters.") return PLUGIN_HANDLED } //Read user read_argv(1,user,20) //Store user/pass in data array to pass to handler for autologin formatex(data[2],20,user) formatex(data[22],20,pass) //Create password hash rotwtf(pass,6) //Register shared SteamID formatex(query,99,"insert into %splayers (steam_id,password) values ('%s','shared')",db_prefix,sid) SQL_ThreadQuery(db_tuple,"reg_handler",query,data,43) //Register user/pass data[1]=1 formatex(query,99,"insert into %splayers (user_name,password,alias) values ('%s','%s','%s')",db_prefix,user,pass,name) SQL_ThreadQuery(db_tuple,"reg_handler",query,data,43) } //Else register SteamID else{ data[1]=2 formatex(query,99,"insert into %splayers (steam_id,alias) values ('%s','%s')",db_prefix,sid,name) SQL_ThreadQuery(db_tuple,"reg_handler",query,data,43) } } else client_print(id,print_console,"[Climb] Registration Error: Can't Register; Stats not enabled.") } return PLUGIN_HANDLED } public reg_handler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime){ new id=data[0],flag=data[1],user[21],pass[21] format(user,20,data[2]) format(pass,20,data[22]) if(failstate == TQUERY_CONNECT_FAILED) return server_print("[Climb] Couldn't connect to database.") else if(failstate == TQUERY_QUERY_FAILED) return server_print("[Climb] Query failed: %s",error) if(errnum){ client_print(id,print_console,"[Climb] Registration Error: Database error, please notify the server admin.") return server_print("[Climb] Query Error: %s",error) } if(flag==0)client_print(id,print_console,"[Climb] Recorded shared SteamID.") else{ client_print(id,print_console,"[Climb] Registration Successful.") new cmd[50] formatex(cmd,49,"login %s %s",user,pass) client_cmd(id,cmd) } return PLUGIN_HANDLED } public rotwtf(string[],out_len){ new len=strlen(string),str[99],cnt=0,tok=len-1 copy(str,out_len,string) for(new index=0;index<11;index++){ if('a'<=string[index]<='z') str[index]=(str[index]-'a'+string[tok]+index) else if('A'<=str[index]<='Z') str[index]=(str[index]-'A'+string[tok]+index) else if('0'<=str[index]<='9') str[index]=(str[index]-'0'+string[tok]+index) switch(cnt){ case 0:str[index]=str[index]%26+'a' case 1:str[index]=str[index]%26+'A' case 2:str[index]=str[index]%10+'0' } tok-- if(tok<0)tok=len-1 cnt++ if(cnt==3)cnt=0 } copy(string,out_len,str) return PLUGIN_HANDLED } public plugin_init(){ register_plugin("Climb",VERSION,"Ian Cammarata") register_cvar("climb_version",VERSION,FCVAR_SERVER) p_climb= register_cvar("climb","1",FCVAR_SERVER) p_boost= register_cvar("climb_boost","1") p_cpprice=register_cvar("climb_cpprice","0") register_cvar("climb_save","1") register_cvar("climb_db_type","sqlite") register_cvar("climb_db_host","127.0.0.1") register_cvar("climb_db_user","") register_cvar("climb_db_pass","") register_cvar("climb_db_name","climb") register_cvar("climb_db_prefix","climb_") p_msg_r=register_cvar("climb_msg_r","0") p_msg_g=register_cvar("climb_msg_g","150") p_msg_b=register_cvar("climb_msg_b","250") p_msg_x=register_cvar("climb_msg_x","0.05") p_msg_y=register_cvar("climb_msg_y","0.5") p_sounds=register_cvar("climb_sounds","1") p_render=register_cvar("climb_unsolid_type","0") p_ip_internal=register_cvar("ip_internal","localhost") p_ip_external=register_cvar("ip_external","localhost") p_port=get_cvar_pointer("port") p_webmod=register_cvar("climb_webmod","0") p_stats_path= register_cvar("climb_stats_path","") p_stats_url= register_cvar("climb_stats_url","") p_stats_hsurl= register_cvar("climb_stats_hsurl","") //Use %s in place of map name p_stats_msg= register_cvar("climb_stats_msg","") p_allow_spectators=get_cvar_pointer("allow_spectators") p_startmoney= register_cvar("climb_startmoney","1337") //General Client Commands //These commands get blocked always. register_clcmd("fullupdate","block_cmd2") //These commands get blocked when climb is enabled. register_clcmd("chooseteam","block_cmd") register_clcmd("buy","block_cmd") register_clcmd("buyammo1","block_cmd") register_clcmd("buyammo2","block_cmd") register_clcmd("buyequip","block_cmd") register_clcmd("jointeam","block_jointeam") //Commands to detect cheats. register_clcmd("+hook","phook") register_clcmd("+rope","phook") register_clcmd("-hook","mhook") register_clcmd("-rope","mhook") //Commands referencing function 'donothing' are picked up by the more flexible code in the client_command forward. register_clcmd("climbhelp","donothing",0,"- Veiw climb help.") register_clcmd("cp","donothing",_,"- Make a checkpoint") register_clcmd("gc","donothing",_,"- Teleport to last checkpoint") register_clcmd("stuck","donothing",_,"- Teleport to previous checkpoint") register_clcmd("restart","donothing",_,"- Stop and respawn.") register_clcmd("stop","donothing",_,"- End current climbing run.") register_clcmd("pause","donothing",_,"- Pause yourself.") register_clcmd("scoreboard","donothing",_,"- View score board.") register_clcmd("respawn","donothing",_,"- Force respawn") register_clcmd("boost","donothing",_,"- Boost.") register_clcmd("spec","donothing",_,"- Spectate mode.") //Commands related to stats account system. register_clcmd("register","reg",_,"- (Console Only) Register for stats tracking.") register_clcmd("login","login",_,"- (Console Only) Login to stats account.") //Admin Commands register_clcmd("amx_goto","goto_player",ADMIN_SLAY) //For scoreboard backend //register_srvcmd("amx_climb_sbrefresh","htmlscoreboard") //Events register_event("DeathMsg","death_msg","a") register_event("ResetHUD","spawned","b") //register_event("Damage","damage","b") register_event("Health","damage","b") register_event("ShowMenu","menuclass","b","4&CT_Select","4&Terrorist_Select") register_event("ShowMenu","menuteam","b","4&Team_Select_Spect","4&Team_Select","4&IG_Team_Select") //Init DB if(get_cvar_num("climb_save"))climb_save=true if(climb_save)db_init() //Init anti flood time stamps score_ts=get_systime() hscore_ts=get_systime() //Task to update time on clients HUD; Task set for half second to minimize flickering of the timer. set_task(0.5,"hudtime",_,_,_,"b") //Register FakeMeta Traceline forward. register_forward(FM_TraceLine, "traceline", 1) //Load Start/Finish Commands new ini[50] get_configsdir(ini,49) format(ini,49,"%s/climb.ini",ini) if(file_exists(ini)){ new line=0,text[50],len while(read_file(ini,line++,text,sizeof(text)-1,len)){ if(!equal(text,";",1)&&!equal(text,"#",1)&&!equal(text,"//",2)){ if(sfcount<SF_MAX){ sfactions[sfcount]=text sfcount++ } } } } return PLUGIN_CONTINUE } public plugin_end() if(climb_save) SQL_FreeHandle(db_tuple)
Contact | ViewVC Help |
Powered by ViewVC 1.0.4 |