- 听众
- 收听
- 积分
- 3894
- 主题
- 回帖
- 0
- 精华
注册时间2008-4-22
最后登录1970-1-1
该用户从未签到
|
发表于 2011-5-1 13:44:58
|
显示全部楼层
- Description:
- This plugin allows clients to jump across sections of bhops without the blocks being triggered. The blocks stay in place all the time making it much more suitable for multiplayer. It is also semiclip safe.
- See it in Action:
- 1337bunnies server: 66.55.131.63:27015
- Commands:
- Not Applicable.
- Cvars:
- mpbhops <0|1> Disables/enables bhop handling.
- Requirements:
- Engine module
- Notes:
- This is a stand alone version of the code from my climb plugin, for those who don't want all the features it offers.
- http://ian.cammarata.us/projects/climb
- Credits:
- Thanks to Lola for letting me use her awesome server for testing purposes.
- http://1337bunnies.com
- 66.55.131.63:27015
- Thanks to r33d and Woofie for testing.
- Supported Languages:
- Not Applicable.
- Change Log:
- Key (+ added | - removed | c changed | f fixed)
- v1.2 (SEPT 23, 2007)
- +: Semiclip support for BCM plugins by Emp` and Necro.
- v1.1 (SEPT 23, 2007)
- c: Increased fail check time from 0.1 seconds to 0.2 seconds. Should fix some people getting fail when doing a standupbhop.
- f: Teleporting to world origin rarely when hopping back and forth between func_door and world brush.
- f: Touch is detected even when clients aren't solid. (No more semiclip exploit)
- v1.0 (SEPT 21, 2007)
- !: Initial release
- */
- #include <amxmodx>
- #include <engine>
- #include <fakemeta>
- #define VERSION "1.2"
- #define MAX_DOORS 500
- #define TSK_BHOP 50
- #define TSK_CLEAR_FAIL 100
- //func_doors[x]{ id, speed, angles }
- new door_count = 0, func_doors[MAX_DOORS][3], Float:door_tp_pos[MAX_DOORS][3]
- new bhop_failid[32], bool:bhop_fail[32]
- new p_enabled
- new MAXPLAYERS
- public plugin_init( )
- {
- MAXPLAYERS = get_maxplayers( )
-
- register_plugin( "MP Bhops", VERSION, "Ian Cammarata" )
- register_cvar( "mpbhops_version", VERSION, FCVAR_SERVER )
-
- p_enabled = register_cvar( "mpbhops", "0", FCVAR_SERVER )
- }
- public pfn_keyvalue( ent )
- {
- static last_ent
- new class[31], key[31], val[31]
- copy_keyvalue( class, 30, key, 30, val, 30 )
-
- if( ent != last_ent && func_doors[door_count][0] && door_count < MAX_DOORS )
- door_count++
-
- if( equal( class, "func_door" ) )
- {
- if( ent != last_ent ) func_doors[door_count][0] = ent
- if( equal( key, "speed" ) )
- func_doors[door_count][1] = str_to_num(val)
- if( equal( key, "dmg" ) )
- func_doors[door_count][0] = 0
- if( equal( key, "angles" ) )
- {
- new angles[5]
- parse( val, angles, 4 )
- func_doors[door_count][2] = str_to_num( angles )
- }
- last_ent = ent
- }
-
- return PLUGIN_CONTINUE
- }
- public plugin_cfg( )
- {
- if( func_doors[door_count][0] && door_count < MAX_DOORS )
- door_count++
-
- new ent, ent2, tmpstr[33]
- new Float:dmins[3], Float:dmaxs[3]
-
- //Find tp spots for doors, in case they're used for bhop
- for( new i = 0; i < door_count; i++ )
- {
- ent = func_doors[i][0]
- if( !is_valid_ent( ent ) ) func_doors[i][0] = 0
- else
- {
- entity_get_vector( ent, EV_VEC_mins, dmins )
- entity_get_vector( ent, EV_VEC_maxs, dmaxs )
-
- new dwid = floatround( dmaxs[0] - dmins[0] )
- new dlen = floatround( dmaxs[1] - dmins[1] )
-
- //If the door moves up, or is thin, remove it's id from the array
- if( func_doors[i][2] < 0 || dwid < 24 || dlen < 24 )
- func_doors[i][0] = 0
- //Otherwise find a safe tp spot in case it's a bhop door
- else
- {
- //If it has a targetname, change the id in array to targeter
- entity_get_string( ent, EV_SZ_targetname, tmpstr, 32 )
- if( strlen( tmpstr ) )
- {
- ent2 = find_ent_by_target( -1, tmpstr )
- if( ent2 )
- {
- func_doors[i][0] = ent2
-
- //If targeter is a button, remove it's id from the array
- entity_get_string( ent2, EV_SZ_classname, tmpstr, 32 )
- if( equal( tmpstr, "func_button" ) )
- func_doors[i][0] = 0
- }
- }
-
- new Float:tmpvec[3], Float:tmpvec2[3]
-
- new Float:dr_tc[3]
- dr_tc[0] = ( dmaxs[0] + dmins[0] ) / 2
- dr_tc[1] = ( dmaxs[1] + dmins[1] ) / 2
- dr_tc[2] = dmaxs[2]
-
- tmpvec[0] = ( dmaxs[0] + dmins[0] ) / 2
- tmpvec[1] = dmaxs[1] + 20
- tmpvec[2] = dmaxs[2] + 20
- trace_line( ent, dr_tc, tmpvec, tmpvec2 )
- if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] )
- door_tp_pos[i] = tmpvec
- else
- {
- tmpvec[1] = dmins[1] - 20
- trace_line( ent, dr_tc, tmpvec, tmpvec2 )
- if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] )
- door_tp_pos[i] = tmpvec
- else
- {
- tmpvec[0] = dmaxs[0] + 20
- tmpvec[1] = ( dmaxs[1] + dmins[1] ) / 2
- trace_line( ent, dr_tc, tmpvec, tmpvec2 )
- if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] )
- door_tp_pos[i] = tmpvec
- else
- {
- tmpvec[0] = dmins[0] - 20
- door_tp_pos[i] = tmpvec
- }
- }
- }
- }
- }
- }
- }
- //This is a semiclip fix
- public client_PreThink( id )
- {
- //If they're on the ground and not solid...
- if( ( pev( id, pev_flags ) & FL_ONGROUND ) && !pev( id, pev_solid ) )
- {
- new Float:orig[3]
- entity_get_vector( id, EV_VEC_origin, orig )
-
- //do a hull trace 1 unit below their origin
- orig[2] -= 1
- engfunc( EngFunc_TraceHull, orig, orig, DONT_IGNORE_MONSTERS, HULL_HUMAN, id, 0 )
- new ent = get_tr2( 0, TR_pHit )
-
- //if all we hit is world or another player, who cares, exit
- if( ent <= MAXPLAYERS ) return PLUGIN_CONTINUE
-
- //if we hit a door in the array, send it to the handler then exit
- new dpos = door_in_array( ent )
- if( dpos > -1 )
- {
- bhop_check_fail( id, ent, dpos )
- return PLUGIN_CONTINUE
- }
-
- //if we hit a BCM entity, force touch so the BCM plugin can handle it
- new class[32]
- entity_get_string( ent, EV_SZ_classname, class, 31 )
- if( equal( class, "bcm" ) || equal( class, "bm_block" ) )
- fake_touch( ent, id )
- }
-
- return PLUGIN_CONTINUE
- }
- public pfn_touch( ent, id )
- {
- if( !get_pcvar_num( p_enabled ) || !ent || !id )
- return PLUGIN_CONTINUE
-
- //Make sure id is player and ent is object
- if( 0 < ent <= MAXPLAYERS )
- {
- new tmp = id
- id = ent
- ent = tmp
- }
- else if( !( 0 < id <= MAXPLAYERS ) )
- return PLUGIN_CONTINUE
-
- //Bhop stuff
- new dpos = door_in_array( ent )
- if( dpos > -1 )
- {
- bhop_check_fail( id, ent, dpos )
- return PLUGIN_HANDLED
- }
-
- return PLUGIN_CONTINUE
- }
- public bhop_check_fail( id, ent, dpos )
- {
- if( bhop_failid[id-1] != ent )
- {
- bhop_failid[id-1] = ent
- bhop_fail[id-1] = false
-
- new tskid = TSK_BHOP + id
- if( task_exists( tskid ) )
- remove_task( tskid )
- set_task( 0.2, "bhop_set_fail", tskid )
- tskid = TSK_CLEAR_FAIL + id
- if( task_exists( tskid ) )
- remove_task( tskid )
- set_task( 0.7, "bhop_clear_fail", tskid )
- }
- else if( bhop_fail[id-1] )
- {
- //Teleport to fail position
- entity_set_vector( id, EV_VEC_velocity, Float:{0.0, 0.0, 0.0} )
- entity_set_vector( id, EV_VEC_origin, door_tp_pos[dpos] )
-
- //Reset fail vars
- bhop_failid[id-1] = 0
- bhop_fail[id-1] = false
- }
- }
- public door_in_array( door )
- {
- for( new i = 0; i < door_count; i++ )
- if( func_doors[i][0] == door )
- return i
- return -1
- }
- public bhop_set_fail( tskid )
- {
- bhop_fail[ tskid - TSK_BHOP - 1 ] = true
- return PLUGIN_HANDLED
- }
- public bhop_clear_fail( tskid )
- {
- new id = tskid - TSK_CLEAR_FAIL
- bhop_failid[id-1] = 0
- bhop_fail[id-1] = false
- return PLUGIN_HANDLED
- }
复制代码
|
|