Русское сообщество по скриптингу

semiclip

Все вопросы по скриптингу для AMXX, помощь в редактировании плагинов.

Модераторы: Subb98, liFe iS GoOD

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только скриптинга для AMX Mod X.

Правила при создании новой темы:
1. При вставке кода плагина необходимо использовать тег [code=php].
2. Любые изображения должны быть загружены, как вложения к вашему сообщению.
3. При описании проблемы или запросе на помощь в редактировании плагина обязательно выкладывайте исходник sma плагина.

semiclip

Сообщение Etnos » 11 авг 2010, 12:24

Есть такой замечательный плагин, который переделали, для паблик серверов. В начале раунда, игроки своей команды могут проходить через игроков определённое количество времени. Есть всего одна проблема. Когда время заканчивается, и если игрок в этот момент был в другом игроке - то он застревает. Помогите это как то исправить. К примеру чтобы в момент когда игрок находиться в другом игроке, и время закончилось его слепнуло на 0 хп.
Код: Выделить всё
#include <amxmodx>
#include <fakemeta>

#pragma semicolon 1

#define DISTANCE 120
#define TIME   7.0

new g_iTeam[33];
new bool:g_bSolid[33];
new bool:g_bHasSemiclip[33];
new Float:g_fOrigin[33][3];

new bool:g_bSemiclipEnabled;

new g_iForwardId[3];
new g_iMaxPlayers;
new g_iCvar[3];
new g_Work;

public plugin_init( )
{
   register_plugin( "(Team-)Semiclip", "1.2", "SchlumPF*/Empower" );
   
   g_iCvar[0] = register_cvar( "semiclip_enabled", "1" );
   g_iCvar[1] = register_cvar( "semiclip_teamclip", "0" );
   g_iCvar[2] = register_cvar( "semiclip_transparancy", "1" );
   
   register_forward( FM_ClientCommand, "fwdClientCommand" );
   
   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;
   
   g_iMaxPlayers = get_maxplayers( );
   
   register_event("HLTV", "event_round_start", "a", "1=0", "2=0");
}

public event_round_start()
{
   g_Work = true;
   set_task(TIME,"reset_state");
}

public reset_state()
   g_Work = false;

public fwdPlayerPreThink( plr )
{
   if(!g_Work)
      return FMRES_IGNORED;
   
   static id, last_think;

   if( last_think > plr)
   {
      for( id = 1; id <= g_iMaxPlayers; id++ )
      {
         if( is_user_alive( id ) )
         {
            if( get_pcvar_num( g_iCvar[1] ) )
               g_iTeam[id] = get_user_team( 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;

   if( g_bSolid[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( get_pcvar_num( g_iCvar[1] ) && g_iTeam[plr] != g_iTeam[id] )
               return FMRES_IGNORED;
   
            set_pev( id, pev_solid, SOLID_NOT );
            g_bHasSemiclip[id] = true;
         }
      }
   }

   return FMRES_IGNORED;
}

public fwdPlayerPostThink( plr )
{
   if(!g_Work)
      return;
      
   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 && g_Work)
   {
      if( g_bSolid[host] && g_bSolid[ent] && get_distance_f( g_fOrigin[host], g_fOrigin[ent] ) <= DISTANCE )
      {
         if( get_pcvar_num( g_iCvar[1] ) && g_iTeam[host] != g_iTeam[ent] )
            return FMRES_IGNORED;
            
         set_es( es_handle, ES_Solid, SOLID_NOT ); // makes semiclip flawless
         
         if( get_pcvar_num( g_iCvar[2] ) == 1 )
         {
            set_es( es_handle, ES_RenderMode, kRenderTransAlpha );
            set_es( es_handle, ES_RenderAmt, 85 );
         }
         else if( get_pcvar_num( g_iCvar[2] ) == 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;
   }
}
Аватара пользователя
Etnos
 
Сообщения: 5
Зарегистрирован: 11 авг 2010, 12:08
Благодарил (а): 8 раз.
Поблагодарили: 1 раз.
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Team Fortress II
Left 4 Dead

Re: semiclip

Сообщение Skriptar » 11 авг 2010, 12:55

Etnos, Перемешать надо на респавн поинты до истечения времени, а потом уже прозрачность офф.

Или ловить спавн запоминать координаты каждого игрока, как только X секунд прошло, перемещать на запомненные координаты. и отключать прозрачность.
Я знаю только то, что я ничего не знаю.
Аватара пользователя
Skriptar
 
Сообщения: 953
Зарегистрирован: 20 окт 2009, 15:34
Благодарил (а): 180 раз.
Поблагодарили: 136 раз.
Языки программирования: Counter-Strike 1.6

Re: semiclip

Сообщение Etnos » 11 авг 2010, 13:33

Спасибо, что ответил, а вот как бы это реализовать в коде? :shout:
Аватара пользователя
Etnos
 
Сообщения: 5
Зарегистрирован: 11 авг 2010, 12:08
Благодарил (а): 8 раз.
Поблагодарили: 1 раз.
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Team Fortress II
Left 4 Dead

Re: semiclip

Сообщение Skriptar » 11 авг 2010, 13:48

Etnos, get_user_origin - получаешь координаты, set_user_origin устанавливаешь.
При событии round start
крутим цикл среди всех живых игроков, пишем полученные координаты в массив, время вышло опять цикл с расстановкой игроков на те места где были эти игроки во время старта.
Последний раз редактировалось Skriptar 11 авг 2010, 13:54, всего редактировалось 1 раз.
Я знаю только то, что я ничего не знаю.
Аватара пользователя
Skriptar
 
Сообщения: 953
Зарегистрирован: 20 окт 2009, 15:34
Благодарил (а): 180 раз.
Поблагодарили: 136 раз.
Языки программирования: Counter-Strike 1.6

Re: semiclip

Сообщение Tilos » 11 авг 2010, 13:51

Либо реализуй слапом игроков если застряли. Застряли игроки - слап обоих и они отлетают в конце концов.
Аватара пользователя
Tilos
 
Сообщения: 203
Зарегистрирован: 10 апр 2010, 21:03
Откуда: Егорьевск
Благодарил (а): 26 раз.
Поблагодарили: 7 раз.
Языки программирования: Не программирую

Re: semiclip

Сообщение qpAHToMAS » 11 авг 2010, 13:54

Либо реализуй слапом игроков если застряли. Застряли игроки - слап обоих и они отлетают в конце концов.

Вряд ли поможет, игроки ведь внутри друг друга.
Аватара пользователя
qpAHToMAS
 
Сообщения: 707
Зарегистрирован: 02 ноя 2009, 18:45
Благодарил (а): 79 раз.
Поблагодарили: 204 раз.
Языки программирования: CStrike

Re: semiclip

Сообщение Tilos » 11 авг 2010, 14:08

Поможет :) На одном сервере видел такую реализацию, плагин вроде бы называется UFPS AntiBlock, но распространять его запрещено.
Аватара пользователя
Tilos
 
Сообщения: 203
Зарегистрирован: 10 апр 2010, 21:03
Откуда: Егорьевск
Благодарил (а): 26 раз.
Поблагодарили: 7 раз.
Языки программирования: Не программирую

Re: semiclip

Сообщение Fedcomp » 11 авг 2010, 14:13

Вы напомнили мне что есть много плагинов типа "UnStuck"
Пища для ума Вы должны зарегистрироваться, чтобы видеть ссылки. ... edmods.net
Последний раз редактировалось Fedcomp 11 авг 2010, 15:13, всего редактировалось 1 раз.
Не помогаю в ЛС - есть форум.
Плагины тоже не пишу, на форуме достаточно хороших скриптеров.


"я ставлю зависимости потому что мне приятно" - subb98 @ 2017
Аватара пользователя
Fedcomp
Администратор
 
Сообщения: 4936
Зарегистрирован: 28 авг 2009, 20:47
Благодарил (а): 813 раз.
Поблагодарили: 1317 раз.
Языки программирования: =>
pawn / php / python / ruby
javascript / rust

Re: semiclip

Сообщение Northon » 11 авг 2010, 15:08

Можно попробовать так, но работать будет только если над застрявшими будет свободно место размером с человека.
Код: Выделить всё
#include <amxmodx>
#include <fakemeta>


#define DISTANCE 120
#define TIME   7.0

new g_iTeam[33];
new bool:g_bSolid[33];
new bool:g_bHasSemiclip[33];
new Float:g_fOrigin[33][3];

new bool:g_bSemiclipEnabled;

new g_iForwardId[3];
new g_iMaxPlayers;
new g_iCvar[3];
new g_Work;

public plugin_init( )
{
   register_plugin( "(Team-)Semiclip", "1.2", "SchlumPF*/Empower" );
   
   g_iCvar[0] = register_cvar( "semiclip_enabled", "1" );
   g_iCvar[1] = register_cvar( "semiclip_teamclip", "0" );
   g_iCvar[2] = register_cvar( "semiclip_transparancy", "1" );
   
   register_forward( FM_ClientCommand, "fwdClientCommand" );
   
   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;
   
   g_iMaxPlayers = get_maxplayers( );
   
   register_event("HLTV", "event_round_start", "a", "1=0", "2=0");
}

public event_round_start()
{
   g_Work = true;
   set_task(TIME,"reset_state");
}

public reset_state()
{
   g_Work = false;
   set_task(0.1, "unstuck_players")
}

public unstuck_players()
{   
   for (new id = 1; id <= g_iMaxPlayers; id++)
   {
      if(!is_user_alive(id))
         continue
      
      if(!is_player_stuck(id))
         continue
      
      static Float:origin[3]
      pev(id, pev_origin, origin)
      
      origin[2] += 65
      if (is_hull_vacant(origin, HULL_HUMAN))
         engfunc(EngFunc_SetOrigin, id, origin)
      else
         client_print(id, print_chat, "Sorry, you can not be unstuck")
   }
}

public fwdPlayerPreThink( plr )
{
   if(!g_Work)
      return FMRES_IGNORED;
   
   static id, last_think;

   if( last_think > plr)
   {
      for( id = 1; id <= g_iMaxPlayers; id++ )
      {
         if( is_user_alive( id ) )
         {
            if( get_pcvar_num( g_iCvar[1] ) )
               g_iTeam[id] = get_user_team( 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;

   if( g_bSolid[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( get_pcvar_num( g_iCvar[1] ) && g_iTeam[plr] != g_iTeam[id] )
               return FMRES_IGNORED;
   
            set_pev( id, pev_solid, SOLID_NOT );
            g_bHasSemiclip[id] = true;
         }
      }
   }

   return FMRES_IGNORED;
}

public fwdPlayerPostThink( plr )
{
   if(!g_Work)
     return;
    
   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 && g_Work)
   {
      if( g_bSolid[host] && g_bSolid[ent] && get_distance_f( g_fOrigin[host], g_fOrigin[ent] ) <= DISTANCE )
      {
         if( get_pcvar_num( g_iCvar[1] ) && g_iTeam[host] != g_iTeam[ent] )
            return FMRES_IGNORED;
         
         set_es( es_handle, ES_Solid, SOLID_NOT ); // makes semiclip flawless
      
         if( get_pcvar_num( g_iCvar[2] ) == 1 )
         {
            set_es( es_handle, ES_RenderMode, kRenderTransAlpha );
            set_es( es_handle, ES_RenderAmt, 85 );
         }
         else if( get_pcvar_num( g_iCvar[2] ) == 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;
   }
}

stock bool:is_hull_vacant(const Float:origin[3], hull) {
   new tr = 0
   engfunc(EngFunc_TraceHull, origin, origin, 0, hull, 0, tr)
   if (!get_tr2(tr, TR_StartSolid) && !get_tr2(tr, TR_AllSolid) && get_tr2(tr, TR_InOpen))
      return true
   
   return false
}

stock bool:is_player_stuck(id)
{
   static Float:originF[3]
   pev(id, pev_origin, originF)
   
   engfunc(EngFunc_TraceHull, originF, originF, 0, (pev(id, pev_flags) & FL_DUCKING) ? HULL_HEAD : HULL_HUMAN, id, 0)
   
   if (get_tr2(0, TR_StartSolid) || get_tr2(0, TR_AllSolid) || !get_tr2(0, TR_InOpen))
      return true;
   
   return false;
}
Аватара пользователя
Northon
 
Сообщения: 269
Зарегистрирован: 30 май 2010, 15:42
Благодарил (а): 9 раз.
Поблагодарили: 91 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: semiclip

Сообщение qpAHToMAS » 12 авг 2010, 12:21

Лучший алгоритм:
  1. После отключения пустотелости проверяем в цикле каждого игрока спец. функцией, которая определяет такое "залипание" (такая есть).
  2. Разбиваем найденных игроков на пары.
  3. Проводим линию через центры двух игроков.
  4. Отталкиваем по этой линии игроков в разные стороны на минимальное расстояние.
  5. После каждого отталкивания игроков проверяем их застревание опять, если есть — продолжаем отталкивать.
Единственный минус: отталкиваться будут не правильно если залипли больше 2-ух игроков, но при желании можно и это сделать. Надеюсь кто-нибудь сделает такой плагин.
Аватара пользователя
qpAHToMAS
 
Сообщения: 707
Зарегистрирован: 02 ноя 2009, 18:45
Благодарил (а): 79 раз.
Поблагодарили: 204 раз.
Языки программирования: CStrike

След.

Вернуться в Скриптинг

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7