Иконка ресурса

Spawns Fixer 1.3.3.7.

Нет прав для скачивания
Сообщения
1,668
Реакции
1,495
Помог
24 раз(а)
fl0wer добавил(а) новый ресурс:

Spawns Fixer - Добавляет новые точки возрождения

Надоело искать карты на большее количество игроков (как в этой теме)? Этот плагин добавит новые точки возрождения.

Не знаю, чего вы ждете от скриншотов, но вот:
$10000$
Посмотреть вложение 9798
de_nuke
Посмотреть вложение 9799
Узнать больше об этом ресурсе...
 
Сообщения
2,288
Реакции
1,737
Помог
31 раз(а)
Автор сам признает, что плагин имеет баг с первым спавном. К тому же непонятно расставляет ли он спавны за зоной закупки
 
Сообщения
198
Реакции
273
Помог
5 раз(а)
Pokemoshka, то, что имеем - уже неплохо.
 

Garey

ninjaCow
Сообщения
411
Реакции
1,051
Помог
10 раз(а)
Плагин не корректно работает на маленьких картах, да и сам метод не очень... Бывают специфические моды где спавны должны быть именно там где задумал маппер, правильно было бы просто спавнить на оригинальных точках, а если игрок находится в этой же точке то просто отключить этим игрокам коллизию (пока они находятся в одной точке), примерно так:

C:
#include < amxmodx >
#include < reapi >
#include < fakemeta >
#include < xs >

new find_ent_hook;
new current_player;
new current_team;
new Float:best_place[3];
new num_iterations;
new bool:need_semiclip[33];

new orig_spawn_nums[2];
new max_players_on_spot[2];
new iMaxPlayers;

public player_spawn_pre( iPlayer )
{
    need_semiclip[current_player] = false;
    current_player = iPlayer;
    current_team = get_member(iPlayer, m_iTeam) == TEAM_CT ? 0 : 1;
    num_iterations = 0;
    find_ent_hook = register_forward(FM_FindEntityInSphere, "find_entity_insphere", 0);
}

public  player_spawn_post( iPlayer )
{
    num_iterations = 0;
    current_player = 0;
    current_team = 0;
    
    if(need_semiclip[iPlayer])
    {
        set_entvar(iPlayer, var_origin, best_place);
    }
    unregister_forward(FM_FindEntityInSphere, find_ent_hook, 0);
    
    if(need_semiclip[iPlayer])
    {
        set_entvar(iPlayer, var_solid, SOLID_NOT);
        SetThink(iPlayer, "PlayerThink");
        set_entvar(iPlayer, var_nextthink, get_gametime() + 0.1);       
    }
}

public PlayerThink(iPlayer)
{
    if(!is_stuck(iPlayer))
    {       
        SetThink(iPlayer, "");
        set_entvar(iPlayer, var_solid, SOLID_BBOX);
    }
    else
    {       
        set_entvar(iPlayer, var_nextthink, get_gametime() + 0.1);
    }   
}

public find_entity_insphere(start, Float:origin[3], Float:radius)
{   
    if(radius != 64.0)
        return FMRES_IGNORED;
    num_iterations++;
    new orig_start= engfunc(EngFunc_FindEntityInSphere, start , origin, 65.0);
    if(orig_start)
    {       
        new plrs_on_spot = 0;
        start = -1;
        while((start= engfunc(EngFunc_FindEntityInSphere, start , origin, 65.0)))
        {
            if(is_entity(start) && is_user_alive(start))
            {
                need_semiclip[current_player] = true;   
                plrs_on_spot++;
            }       
        }
        if(plrs_on_spot < max_players_on_spot[current_team])
        {
            xs_vec_copy(origin, best_place);
        }
        if(num_iterations >= orig_spawn_nums[current_team])
        {
            forward_return(FMV_CELL, 0);
            return FMRES_SUPERCEDE;
        }
        
        forward_return(FMV_CELL, orig_start);
        return FMRES_SUPERCEDE;
    }
    else
    {
        forward_return(FMV_CELL, orig_start);
        return FMRES_SUPERCEDE;
    }
}

public plugin_init()
{
    if(orig_spawn_nums[0])
        max_players_on_spot[0] = floatround(iMaxPlayers/float(orig_spawn_nums[0]), floatround_ceil);
    else
        max_players_on_spot[0] = iMaxPlayers;
    
    if(orig_spawn_nums[1])
        max_players_on_spot[1] = floatround(iMaxPlayers/float(orig_spawn_nums[1]), floatround_ceil);
    else
        max_players_on_spot[1] = iMaxPlayers;
        
    RegisterHookChain( RG_CBasePlayer_Spawn, "player_spawn_pre", false );
    RegisterHookChain( RG_CBasePlayer_Spawn, "player_spawn_post", true );
}

public plugin_precache()
{   
    iMaxPlayers = get_maxplayers();
    
    enum _:SpawnsDatas
    {
        m_szAngles[64],
        m_szOrigins[64]
    }
    new Array:aSpawns[2];
    aSpawns[0] = ArrayCreate(SpawnsDatas);
    aSpawns[1] = ArrayCreate(SpawnsDatas);
    new mTempDatas[SpawnsDatas]

    enum
    {
        iAngles,
        iOrigins,
        iClassName
    }
    new Trie:tKeyType = TrieCreate()
    TrieSetCell(tKeyType, "angles", iAngles)
    TrieSetCell(tKeyType, "origin", iOrigins)
    TrieSetCell(tKeyType, "classname", iClassName)

    new szMapFile[64]
    get_mapname(szMapFile, charsmax(szMapFile))
    format(szMapFile, charsmax(szMapFile), "maps/%s.bsp", szMapFile)

    new szBuffer[64], szKey[16], szValue[32], iType
    new bool:bInEntityDatas, bool:bIsCTSpawn;
    new bool:bIsTTSpawn;
    new fp = fopen(szMapFile, "rb")

    new iOffset, iLength, iMaxPos
    fseek(fp, 4, SEEK_SET)
    fread(fp, iOffset, BLOCK_INT)
    fread(fp, iLength, BLOCK_INT)
    iMaxPos = iOffset + iLength
    fseek(fp, iOffset, SEEK_SET)

    while( ftell(fp) < iMaxPos )
    {
        fgets(fp, szBuffer, charsmax(szBuffer))
        trim(szBuffer)

        if( bInEntityDatas )
        {
            if( szBuffer[0] == '}' )
            {
                bInEntityDatas = false
                if( bIsCTSpawn )
                {
                    ArrayPushArray(aSpawns[0], mTempDatas)
                }
                if( bIsTTSpawn )
                {
                    ArrayPushArray(aSpawns[1], mTempDatas)
                }
            }
            else
            {
                parse(szBuffer, szKey, charsmax(szKey), szValue, charsmax(szValue))
                if( TrieGetCell(tKeyType, szKey, iType) )
                {
                    switch( iType )
                    {
                        case iAngles:
                        {
                            copy(mTempDatas[m_szAngles], charsmax(mTempDatas[m_szAngles]), szValue)
                        }
                        case iOrigins:
                        {
                            copy(mTempDatas[m_szOrigins], charsmax(mTempDatas[m_szOrigins]), szValue)
                        }
                        case iClassName:
                        {
                            if( equal(szValue, "info_player_start") )
                            {
                                bIsCTSpawn = true
                            }
                            else if ( equal(szValue, "info_player_deathmatch") )
                            {
                                bIsTTSpawn = true;
                            }
                        }
                    }
                }
            }
        }
        else if( szBuffer[0] == '{' )
        {
            bInEntityDatas = true
            bIsCTSpawn = false
            bIsTTSpawn = false;
        }
    }
    fclose(fp)

    for(new t = 0; t < 2; t++)
    {
        new iSpawnsNum = ArraySize( aSpawns[t] )
        orig_spawn_nums [t] = iSpawnsNum;
        new iNeededSpawns = max( iMaxPlayers - iSpawnsNum, 0)
    
    
        if( iSpawnsNum > 0 && iNeededSpawns > 0 )
        {
            new iFactor = (iNeededSpawns / iSpawnsNum) + _:!!(iNeededSpawns % iSpawnsNum)
            
            new iszClassName;
            if(!t)
            {
                iszClassName = engfunc(EngFunc_AllocString, "info_player_start");
                set_kvd(0, KV_ClassName, "info_player_start");
            }
            else
            {
                iszClassName = engfunc(EngFunc_AllocString, "info_player_deathmatch")           
                set_kvd(0, KV_ClassName, "info_player_deathmatch")
            }
            set_kvd(0, KV_fHandled, 0)
            for(new i, j, iEnt; i<iSpawnsNum; i++)
            {
                ArrayGetArray(aSpawns[t], i, mTempDatas)
                for(j=0; j<iFactor; j++)
                {
                    iEnt = engfunc(EngFunc_CreateNamedEntity, iszClassName)
                    DispatchKeyValueCustom(iEnt, "angles", mTempDatas[m_szAngles])
                    DispatchKeyValueCustom(iEnt, "origin", mTempDatas[m_szOrigins])
                    dllfunc(DLLFunc_Spawn, iEnt)
    
                    if( --iNeededSpawns == 0 )
                    {
                        goto delete_datas
                    }
                }
            }
        }
                
        delete_datas:
        ArrayDestroy( aSpawns[t] )
        TrieDestroy( tKeyType )
    }

}

DispatchKeyValueCustom(iEntity, szKey[], szValue[])
{
    set_kvd(0, KV_KeyName, szKey)
    set_kvd(0, KV_Value, szValue)
    dllfunc(DLLFunc_KeyValue, iEntity, 0)
}


stock bool:is_stuck(id)
{
    new Float:origin[3];   
    get_entvar(id, var_origin, origin);
    new found;
    while ( ( found = engfunc ( EngFunc_FindEntityInSphere, found, origin, 64.0 ) ) )
    {
        if(found == id)
            continue;
            
        if(is_entity(found) && is_user_alive(found))
        {
            return true;
        }
    }
    return false;
}
 

ifx

Сообщения
330
Реакции
149
Помог
4 раз(а)
fl0wer, я же правильно понял из описания, если карта не поддерживает 32 игрока изначально, напр тот же cs_office, то с помощью плагина будут автоматически проставлены доп респы и игроки будут респавнится на них, а не висеть в спектрах упершись в лимит?

Ps а можно допилить поддержку амхх 182?
 

ifx

Сообщения
330
Реакции
149
Помог
4 раз(а)
Garey, при компиляции на амхх 182 ошибка: warning 209: function "find_entity_insphere" should return a value
в игре это выражается тем, что игроки из чужих команд проходят друг сквозь друга и их нельзя убить

зы. в общем остановился на вот этом плагине под 182 - https://forums.alliedmods.net/showthread.php?t=50461
работает как положено.
 
Последнее редактирование:

Garey

ninjaCow
Сообщения
411
Реакции
1,051
Помог
10 раз(а)
ifx Я лишь показал метод, этот плагин не готов для использования
 
Сообщения
141
Реакции
201
Помог
5 раз(а)
Garey, при компиляции на амхх 182 ошибка: warning 209: function "find_entity_insphere" should return a value
в игре это выражается тем, что игроки из чужих команд проходят друг сквозь друга и их нельзя убить

зы. в общем остановился на вот этом плагине под 182 - https://forums.alliedmods.net/showthread.php?t=50461
работает как положено.
предупреждение не есть ошибка. добавь под фигурной скобкой на линии №94 return FMRES_IGNORED;
 
Сообщения
26
Реакции
4
В данном плагине у половину игроков нету ножей при респане! есть у кого рабочий без багов ?!
 

ifx

Сообщения
330
Реакции
149
Помог
4 раз(а)
SEREGA, на 3 поста выше глаза подними
 
Сообщения
11
Реакции
2
И ножей нет, и у кого по два пистолета бывает, а у других не одного
 
Сообщения
2,715
Реакции
2,996
Помог
59 раз(а)
Нашёл не очевидное поведение.

Как воспроизвести?
1) расположить de_nuke.ent в папку cstrike/maps/
2) включить на сервере sv_use_entity_file 1
3) установить этот плагин.
4) перезапустить карту командой restart


В ент-файле для карты оставлено только 2 спавна.
 

Download all Attachments

Сообщения
1,668
Реакции
1,495
Помог
24 раз(а)
wopox1337, так плагин работает, что ему необходимо минумум 2 за команду.
 
Сообщения
1,668
Реакции
1,495
Помог
24 раз(а)
wopox1337, или написать получше алгоритм.
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу