Paint Marker

Paint Marker 2.0.0

Нет прав для скачивания
Код:
/*
 * Credits to stupok69 for original plugin Magic Marker v3.1:
 */

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <reapi>
#include <xs>

#pragma semicolon 1

public stock const PluginName[] = "Paint Marker";
public stock const PluginVersion[] = "2.0.0";
public stock const PluginAuthor[] = "twisterniq";
public stock const PluginURL[] = "https://github.com/twisterniq/amxx-paint-marker";
public stock const PluginDescription[] = "Adds the ability to paint. It has API";

// Time for think, the more time the more you can paint but the less smooth it will be displayed
const Float:THINK_TIME = 0.1;

#define CHECK_NATIVE_PLAYER(%0,%1) \
    if (!(1 <= %0 <= MaxClients)) \
    { \
        abort(AMX_ERR_NATIVE, "Player out of range (%d)", %0); \
        return %1; \
    }

new bool:g_bAlive[MAX_PLAYERS + 1];
new bool:g_bIsPainting[MAX_PLAYERS + 1], bool:g_bIsHoldingPaint[MAX_PLAYERS + 1];
new bool:g_bCanUseMarker[MAX_PLAYERS + 1];
new Float:g_iOriginPaint[MAX_PLAYERS + 1][3];
new g_pSpriteLightning;
new g_iLifeTime;

public plugin_init()
{
#if AMXX_VERSION_NUM == 190
    register_plugin(
        .plugin_name = PluginName,
        .version = PluginVersion,
        .author = PluginAuthor);
#endif

    register_dictionary("paint_marker.txt");

    register_clcmd("+paint", "@func_PaintEnable");
    register_clcmd("-paint", "@func_PaintDisable");

    RegisterHookChain(RG_CSGameRules_PlayerSpawn, "@OnPlayerSpawn_Post", true);
    RegisterHookChain(RG_CBasePlayer_Killed, "@OnPlayerKilled_Post", true);

    bind_pcvar_num(create_cvar(
        .name = "paint_marker_life_time",
        .string = "25",
        .flags = FCVAR_NONE,
        .description = fmt("%L", LANG_SERVER, "PAINT_MARKER_CVAR_LIFE_TIME"),
        .has_min = true,
        .min_val = 1.0,
        .has_max = true,
        .max_val = 25.0), g_iLifeTime);

    AutoExecConfig(true, "paint_marker");

    new iEnt = rg_create_entity("info_target", true);

    if(iEnt)
    {
        SetThink(iEnt, "@think_Paint");
        set_entvar(iEnt, var_nextthink, get_gametime() + THINK_TIME);
    }
}

public plugin_precache()
{
    g_pSpriteLightning = precache_model("sprites/lgtning.spr");
}

public client_disconnected(id)
{
    g_bIsPainting[id] = false;
    g_bAlive[id] = false;
    g_bCanUseMarker[id] = false;
}

@OnPlayerSpawn_Post(const id)
{
    if(is_user_alive(id))
    {
        g_bAlive[id] = true;
        g_bIsPainting[id] = false;
    }
}

@OnPlayerKilled_Post(const iVictim)
{
    g_bAlive[iVictim] = false;
    g_bIsPainting[iVictim] = false;
}

@func_PaintEnable(const id)
{
    if(!g_bAlive[id])
    {
        return PLUGIN_HANDLED;
    }

    if(!g_bCanUseMarker[id])
    {
        client_print_color(id, print_team_red, "%l", "PAINT_MARKER_ERROR_ACCESS");
        return PLUGIN_HANDLED;
    }

    g_bIsPainting[id] = true;
    return PLUGIN_HANDLED;
}

@func_PaintDisable(const id)
{
    g_bIsPainting[id] = false;
    return PLUGIN_HANDLED;
}

@think_Paint(const iEnt)
{
    static iPlayers[MAX_PLAYERS], iPlayerCount;
    get_players_ex(iPlayers, iPlayerCount, GetPlayers_ExcludeDead);

    for(new i, iPlayer; i < iPlayerCount; i++)
    {
        iPlayer = iPlayers[i];

        if(!g_bIsPainting[iPlayer] || func_IsAimingAtSky(iPlayer))
        {
            g_bIsHoldingPaint[iPlayer] = false;
            continue;
        }

        static Float:flOrigin[3], Float:flDistance;
        flOrigin = g_iOriginPaint[iPlayer];

        if(!g_bIsHoldingPaint[iPlayer])
        {
            func_GetAimOrigin(iPlayer, g_iOriginPaint[iPlayer]);
            func_MoveTowardClient(iPlayer, g_iOriginPaint[iPlayer]);
            g_bIsHoldingPaint[iPlayer] = true;

            continue;
        }

        func_GetAimOrigin(iPlayer, g_iOriginPaint[iPlayer]);
        func_MoveTowardClient(iPlayer, g_iOriginPaint[iPlayer]);

        flDistance = get_distance_f(g_iOriginPaint[iPlayer], flOrigin);

        if(flDistance > 2.0)
        {
            func_StartPainting(g_iOriginPaint[iPlayer], flOrigin);
        }
    }

    set_entvar(iEnt, var_nextthink, get_gametime() + THINK_TIME);
}

func_StartPainting(Float:flOrigin1[3], Float:flOrigin2[3])
{
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
    {
        write_byte(TE_BEAMPOINTS);
        write_coord_f(flOrigin1[0]);        // startposition x
        write_coord_f(flOrigin1[1]);        // startposition y
        write_coord_f(flOrigin1[2]);        // startposition z
        write_coord_f(flOrigin2[0]);        // endposition x
        write_coord_f(flOrigin2[1]);        // endposition y
        write_coord_f(flOrigin2[2]);        // endposition z
        write_short(g_pSpriteLightning);    // sprite index
        write_byte(0);                        // starting frame
        write_byte(10);                        // frame rate in 0.1's
        write_byte(g_iLifeTime * 10);        // life in 0.1's
        write_byte(50);                        // line width in 0.1's
        write_byte(0);                        // noise aimplitude in 0.01's
        write_byte(random_num(0, 255));        // red
        write_byte(random_num(0, 255));        // green
        write_byte(random_num(0, 255));        // blue
        write_byte(255);                    // brightness
        write_byte(0);                        // scroll speed in 0.1's
    }
    message_end();
}

stock func_GetAimOrigin(const id, Float:flOrigin[3])
{
    static Float:flStart[3], Float:flViewOfs[3];
    get_entvar(id, var_origin, flStart);
    get_entvar(id, var_view_ofs, flViewOfs);
    xs_vec_add(flStart, flViewOfs, flStart);

    static Float:flDest[3];
    get_entvar(id, var_v_angle, flDest);
    engfunc(EngFunc_MakeVectors, flDest);
    global_get(glb_v_forward, flDest);
    xs_vec_mul_scalar(flDest, 9999.0, flDest);
    xs_vec_add(flStart, flDest, flDest);

    engfunc(EngFunc_TraceLine, flStart, flDest, 0, id, 0);
    get_tr2(0, TR_vecEndPos, flOrigin);
}

stock func_MoveTowardClient(const id, Float:flOrigin[3])
{
    static Float:flPlayerOrigin[3];

    get_entvar(id, var_origin, flPlayerOrigin);

    flOrigin[0] += (flPlayerOrigin[0] > flOrigin[0]) ? 1.0 : -1.0;
    flOrigin[1] += (flPlayerOrigin[1] > flOrigin[1]) ? 1.0 : -1.0;
    flOrigin[2] += (flPlayerOrigin[2] > flOrigin[2]) ? 1.0 : -1.0;
}

bool:func_IsAimingAtSky(const id)
{
    new Float:flOrigin[3];
    func_GetAimOrigin(id, flOrigin);
    return (engfunc(EngFunc_PointContents, flOrigin) == CONTENTS_SKY);
}

/****************************************************************************************
****************************************************************************************/

public plugin_natives()
{
    register_library("paint_marker");

    register_native("paint_marker_set_user_access",    "@Native_SetUserAccess");
    register_native("paint_marker_has_user_access",    "@Native_HasUserAccess");
}

@Native_SetUserAccess(const iPlugin, const iParams)
{
    enum { arg_player = 1, arg_access };

    new iPlayer = get_param(arg_player);

    CHECK_NATIVE_PLAYER(iPlayer, false)

    g_bCanUseMarker[iPlayer] = bool:get_param(arg_access);

    if(!g_bCanUseMarker[iPlayer])
    {
        g_bIsPainting[iPlayer] = false;
    }

    return true;
}

bool:@Native_HasUserAccess(const iPlugin, const iParams)
{
    enum { arg_player = 1 };

    new iPlayer = get_param(arg_player);

    CHECK_NATIVE_PLAYER(iPlayer, false)

    return g_bCanUseMarker[iPlayer];
}
[/SPOILER]
Назад
Верх