#include #include #include #include #include #include #include #pragma semicolon 1 #define DISTANCE 120 new g_Zombie[33]; new bool:g_bSolid[33]; new bool:g_bHasSemiclip[33]; new Float:g_fOrigin[33][3]; new Float:g_fSpawnTime[33]; new stuck[33]; enum SEMICLIP{ SEMICLIP_NULL, SEMICLIP_NONE, SEMICLIP_AUTO, SEMICLIP_ACTIVE, } new SEMICLIP:SemiClipType[33]; new gNotify[33]; new bool:g_bSemiclipEnabled; new g_iForwardId[3]; new g_iMaxPlayers; new g_iCvar[3]; public plugin_init( ) { register_plugin( "(Team-)Semiclip", "1.2", "SchlumPF*" ); g_iCvar[0] = register_cvar( "semiclip_enabled", "1" ); g_iCvar[2] = register_cvar( "semiclip_transparancy", "1" ); set_task(0.1,"checkstuck",0,"",0,"b"); register_forward( FM_ClientCommand, "fwdClientCommand" ); RegisterHam(Ham_Spawn, "player", "fw_PlayerSpawn"); RegisterHam(Ham_Killed, "player", "fw_PlayerKilled"); register_touch("player", "player", "player_touch"); register_clcmd("say /semiclip","semiclip_menu", 0, "- select semiclip mode"); if( get_pcvar_num( g_iCvar[0] ) ) { g_iForwardId[0] = register_forward( FM_PlayerPreThink, "fwdPlayerPreThink" ); g_iForwardId[1] = register_forward( FM_PlayerPostThink, "fwdPlayerPostThink" ); g_iForwardId[2] = register_forward( FM_AddToFullPack, "fwdAddToFullPack_Post", 1 ); g_bSemiclipEnabled = true; } else g_bSemiclipEnabled = false; } public client_connect( id ) { g_iMaxPlayers = max( id, g_iMaxPlayers ); SemiClipType[id] = SEMICLIP_NULL; } public client_authorized( id ) { SemiClipType[id] = SEMICLIP:player_get_num( id, "SemiClip", "Type" ); gNotify[id] = 0; } public client_disconnect( id ) { if( id == g_iMaxPlayers ) { new old = g_iMaxPlayers; for( new i=1; i 0.0) ? (100.0 - temp) : (100.0 + temp); origin[2] += 100.0; fm_entity_set_origin(victim, origin); client_print(victim, print_center, "Moved to avoid Spawn Kill"); _UnStuck(victim, true); return HAM_SUPERCEDE; } return HAM_IGNORED; } public fwdPlayerPreThink( plr ) { static id, last_think; if( last_think > plr ) { for( id = 1 ; id <= g_iMaxPlayers ; id++ ) { if( is_user_alive( id ) ) { g_Zombie[id] = zp_get_user_zombie( id ); g_bSolid[id] = pev( id, pev_solid ) == SOLID_SLIDEBOX ? true : false; pev( id, pev_origin, g_fOrigin[id] ); } else g_bSolid[id] = false; } } last_think = plr; switch( SemiClipType[plr] ) { case SEMICLIP_NULL, SEMICLIP_NONE: { return FMRES_IGNORED; } case SEMICLIP_AUTO: { } case SEMICLIP_ACTIVE: { if( !(entity_get_int(plr, EV_INT_button) & IN_USE) ) return FMRES_IGNORED; } } if( g_bSolid[plr] && !g_Zombie[plr] ) { for( id = 1 ; id <= g_iMaxPlayers ; id++ ) { if( g_bSolid[id] && get_distance_f( g_fOrigin[plr], g_fOrigin[id] ) <= DISTANCE && id != plr ) { if( g_Zombie[plr] != g_Zombie[id] ) return FMRES_IGNORED; set_pev( id, pev_solid, SOLID_NOT ); g_bHasSemiclip[id] = true; } } } return FMRES_IGNORED; } public fwdPlayerPostThink( plr ) { static id; for( id = 1 ; id <= g_iMaxPlayers ; id++ ) { if( g_bHasSemiclip[id] ) { set_pev( id, pev_solid, SOLID_SLIDEBOX ); g_bHasSemiclip[id] = false; } } } public fwdAddToFullPack_Post( es_handle, e, ent, host, hostflags, player, pset ) { if( player ) { if( g_bSolid[host] && g_bSolid[ent] && !g_Zombie[host] && !g_Zombie[ent] ) { switch( SemiClipType[host] ) { case SEMICLIP_NULL, SEMICLIP_NONE: { return FMRES_IGNORED; } case SEMICLIP_AUTO: { } case SEMICLIP_ACTIVE: { if( !(entity_get_int(host, EV_INT_button) & IN_USE) ) return FMRES_IGNORED; } } if( get_distance_f( g_fOrigin[host], g_fOrigin[ent] ) <= DISTANCE ) { set_es( es_handle, ES_Solid, SOLID_NOT ); // makes semiclip flawless switch( get_pcvar_num( g_iCvar[2] ) ) { case 1: { set_es( es_handle, ES_RenderMode, kRenderTransAlpha ); set_es( es_handle, ES_RenderAmt, 85 ); } case 2: { set_es( es_handle, ES_Effects, EF_NODRAW ); set_es( es_handle, ES_Solid, SOLID_NOT ); } } } } } return FMRES_IGNORED; } // is there a better way to detect changings of g_iCvar[0]? public fwdClientCommand( plr ) { // use the forwards just when needed, for good performance if( !get_pcvar_num( g_iCvar[0] ) && g_bSemiclipEnabled ) { unregister_forward( FM_PlayerPreThink, g_iForwardId[0] ); unregister_forward( FM_PlayerPostThink, g_iForwardId[1] ); unregister_forward( FM_AddToFullPack, g_iForwardId[2], 1 ); g_bSemiclipEnabled = false; } else if( get_pcvar_num( g_iCvar[0] ) && !g_bSemiclipEnabled ) { g_iForwardId[0] = register_forward( FM_PlayerPreThink, "fwdPlayerPreThink" ); g_iForwardId[1] = register_forward( FM_PlayerPostThink, "fwdPlayerPostThink" ); g_iForwardId[2] = register_forward( FM_AddToFullPack, "fwdAddToFullPack_Post", 1 ); g_bSemiclipEnabled = true; } } public checkstuck() { static players[32], pnum, player, i, bool:detect_players; get_players(players, pnum); static Float:origin[3], hull; for( i=0; i= 10 ) { detect_players = true; if( !g_Zombie[player] ) { switch( SemiClipType[player] ) { case SEMICLIP_NULL, SEMICLIP_NONE: { detect_players = true; } case SEMICLIP_AUTO: { detect_players = false; } case SEMICLIP_ACTIVE: { if( entity_get_int(player, EV_INT_button) & IN_USE ) detect_players = false; else detect_players = true; } } } if( _UnStuck( player, detect_players ) == 1 ) { effects(player); } stuck[player] = 0; } } else { stuck[player] = 0; } } } } stock _UnStuck(id, bool:detect_players) { new hullsize = (pev(id, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN; new Float:origin[3], tr = 0; pev(id, pev_origin, origin); if( detect_players ) engfunc(EngFunc_TraceHull, origin, origin, 0, hullsize, id, tr); else engfunc(EngFunc_TraceHull, origin, origin, IGNORE_MONSTERS, hullsize, id, tr); if( !get_tr2(tr,TR_StartSolid) && !get_tr2(tr,TR_AllSolid) && get_tr2(tr,TR_InOpen) ) return -1; new Float:new_origin[3], distance, i, trace, Float:fraction; const UNSTUCK_START_DISTANCE = 32; const UNSTUCK_MAX_ATTEMPTS = 128; distance = UNSTUCK_START_DISTANCE; while( distance < 1000 ) { // 1000 is just incase, should never get anywhere near that for( i = 0; i < UNSTUCK_MAX_ATTEMPTS; i++ ){ new_origin[0] = random_float(origin[0]-distance, origin[0]+distance); new_origin[1] = random_float(origin[1]-distance, origin[1]+distance); new_origin[2] = random_float(origin[2]-distance, origin[2]+distance); if ( fm_trace_hull(new_origin, hullsize, id) == 0 ) { engfunc(EngFunc_TraceLine, origin, new_origin, IGNORE_MONSTERS, id, trace); get_tr2(trace, TR_flFraction, fraction); if( fraction == 1.0 ) { fm_entity_set_origin(id, new_origin); return 1; } } } distance += UNSTUCK_START_DISTANCE; } return 0; } bool:is_hull_vacant(const Float:origin[3], hull,id) { static tr; engfunc(EngFunc_TraceHull, origin, origin, 0, hull, id, tr); if( !get_tr2(tr, TR_StartSolid) || !get_tr2(tr, TR_AllSolid) ) //get_tr2(tr, TR_InOpen)) return true; return false; } effects(id) { set_hudmessage(255,150,50, -1.0, 0.65, 0, 6.0, 1.5,0.1,0.7); // HUDMESSAGE show_hudmessage(id,"Automatic Unstuck!"); // HUDMESSAGE message_begin(MSG_ONE_UNRELIABLE,105,{0,0,0},id ); write_short(1<<10); // fade lasts this long duration write_short(1<<10); // fade lasts this long hold time write_short(1<<1); // fade type (in / out) write_byte(20); // fade red write_byte(255); // fade green write_byte(255); // fade blue write_byte(255); // fade alpha message_end(); client_cmd(id,"spk fvox/blip.wav"); }