Coins (Fork)

module Coins (Fork) 2.0.4

Нет прав для скачивания
Установка
1. Определите настройки подключения к БД которые вы будите использовать.
2. Скомпилируйте плагин (инструкция).
3. Скопируйте скомпилированный .amxx в директорию /amxmodx/plugins/
4. Пропишите .amxx в файле /amxmodx/configs/plugins.ini
5. Настройте .cfg по своему вкусу
6. Скопируйте конфиг .cfg в директорию /amxmodx/configs/
7. Скопируйте дополнительные файлы плагина (models, sound) в соответствующие директории на сервере
8. Смените карту или перезапустите сервер.
Настройки
C++:
// Флаги для притягивания и получения доп. монет
coin_priv_flag "t"

// Кол-во получаемых монет за простое убийство
coin_give_kill "1"

// Кол-во дополнительно получаемых монет за убийство в голову
coin_give_kill_head "1"

// Кол-во дополнительно получаемых монет за убйство гранатой
coin_give_kill_gren "1"

// Кол-во дополнительно получаемых монет за убийство ножом
coin_give_kill_knife "1"

// Кол-во дополнительно получаемых монет игроком, имеющих флаг
coin_give_kill_flag "1"

// Кол-во получаемых монет выйгравшей командой
coin_give_alive "0"

// Монеты может поднимать и видеть только убийца игрока (0 - выключено, 1 - включено)
coin_drop_only_killer "0"

// Анимация модели (0 - нет; 1 - движение вверх-вниз; вращение, 2 - вращение)
coin_anim_type "0"

// Скорость проигрывания анимации модели (дробное значение)
coin_anim_time "1.0"

// Подсветка (glow-свечение) монеты (0 - отключить, 1 - включить)
coin_glow_enable "0"

// Цвет свечения
coin_glow_color_red "255"
coin_glow_color_green "255"
coin_glow_color_blue "128"

// "Толщина" glow (0-255)
coin_glow_amount "45"

// Притягивание монет к привилегированным игрокам (0 - нет, 1 - да)
coin_pull_enable "1"

// Радиус действия для притягивания монет
coin_pull_radius "500.0"

// Показ худ-сообщения игроку о кол-ве монет (0 - нет, 1 - да)
coin_hud_enable "1"

// Цвет HUD
coin_hud_color_red "255"
coin_hud_color_green "100"
coin_hud_color_blue "0"

// Позиция HUD
coin_hud_position_x "0.01"
coin_hud_position_y "0.31"

// Удаление монет в конце раунда (0 - нет, 1 - да)
coin_clear "1"

// Таблица в которой будут находиться количество монет игроков
coin_sql_table "coins"

// Настройки подключения к MySQL
// Если вы используете собственные раскомментируйте их
// coin_sql_host "127.0.0.1"
// coin_sql_user "amxx"
// coin_sql_pass ""
// coin_sql_db "amxx"
API
C++:
#pragma semicolon 1

#define COIN_MODEL_PATH "models/coin.mdl"
#define COIN_SOUND_PATH "events/tutor_msg"
#define is_player(%1) !is_user_bot(%1) && !is_user_hltv(%1)
#define STEAMID_SIZE 35

/**
 * Determines whether the database connection settings from sql.cfg will be used.
 */
#define USING_SQL

#include <amxmodx>
#include <amxmisc>
#include <fakemeta_util>
#include <reapi>
#include <sqlx>

new const PLUGIN_NAME[] = "Coins";
new const PLUGIN_VERSION[] = "2.0.4";
new const PLUGIN_AUTHOR[] = "6u3oH && Clay Whitelytning";

new const Float: ENT_MINSIZE[] = { -2.0, -9.0, -1.0 };
new const Float: ENT_MAXSIZE[] = { 2.0, 7.0, 17.0 };

enum FWD_TYPE
{
  GIVE_COINS_PRE,
  GIVE_COINS_POST,
  COINS_PICKUP_PRE,
  COINS_PICKUP_POST,
  COIN_PULL
};

new cvar_sql_host,
  cvar_sql_user,
  cvar_sql_pass,
  cvar_sql_db,
  cvar_sql_table,

  cvar_coin_priv_flag,
  cvar_coin_anim_type,
  cvar_coin_give_kill,
  cvar_coin_give_kill_head,
  cvar_coin_give_kill_grenade,
  cvar_coin_give_kill_knife,
  cvar_coin_give_kill_flag,
  cvar_coin_give_alive,
  cvar_coin_glow_amount,
  
  cvar_coin_pull_enable,
  cvar_coin_hud_enable,
  cvar_coin_glow_enable,
  cvar_coin_clear,
  cvar_coin_drop_only_killer,
 
  cvar_coin_pull_radius,
  cvar_coin_anim_time,
  cvar_coin_glow_color_red,
  cvar_coin_glow_color_green,
  cvar_coin_glow_color_blue,
 
  cvar_coin_hud_color_red,
  cvar_coin_hud_color_green,
  cvar_coin_hud_color_blue,
  cvar_coin_hud_position_x,
  cvar_coin_hud_position_y;

new players[MAX_PLAYERS + 1], // Contains the number of coins
    bool:connected[MAX_PLAYERS + 1], // Determines the connection status
    forwards[FWD_TYPE];

new Handle: sql_tuple, Handle: sql_connection;

@register_cvars()
{
  cvar_coin_priv_flag = register_cvar("coin_priv_flag", "t");
  cvar_coin_give_kill = register_cvar("coin_give_kill", "1");
  cvar_coin_give_kill_head = register_cvar("coin_give_kill_head", "1");
  cvar_coin_give_kill_knife    = register_cvar("coin_give_kill_knife", "1");
  cvar_coin_give_kill_grenade = register_cvar("coin_give_kill_grenade", "1");
  cvar_coin_give_kill_flag = register_cvar("coin_give_kill_flag", "1");
  cvar_coin_give_alive=    register_cvar("coin_give_alive", "3");
  cvar_coin_drop_only_killer = register_cvar("coin_drop_only_killer", "0");
  cvar_coin_anim_type = register_cvar("coin_anim_type", "1");
  cvar_coin_anim_time = register_cvar("coin_anim_time", "0.5");
  cvar_coin_glow_enable    = register_cvar("coin_glow_enable", "1");
  cvar_coin_glow_color_red = register_cvar("coin_glow_color_red", "255");
  cvar_coin_glow_color_green = register_cvar("coin_glow_color_green", "255");
  cvar_coin_glow_color_blue    = register_cvar("coin_glow_color_blue", "128");
  cvar_coin_glow_amount    = register_cvar("coin_glow_amount", "45");
  cvar_coin_pull_enable    = register_cvar("coin_pull_enable", "1");
  cvar_coin_pull_radius    = register_cvar("coin_pull_radius", "500.0");
  cvar_coin_hud_enable = register_cvar("coin_hud_enable", "1");
  cvar_coin_hud_color_red = register_cvar("coin_hud_color_red", "200");
  cvar_coin_hud_color_green = register_cvar("coin_hud_color_green", "100");
  cvar_coin_hud_color_blue = register_cvar("coin_hud_color_blue", "0");
  cvar_coin_hud_position_x = register_cvar("coin_hud_position_x", "0.01");
  cvar_coin_hud_position_y = register_cvar("coin_hud_position_y", "0.31");
  cvar_coin_clear = register_cvar("coin_clear", "1");

  #if defined USING_SQL
  cvar_sql_host    = register_cvar("amx_sql_host", "127.0.0.1", FCVAR_PROTECTED);
  cvar_sql_db    = register_cvar("amx_sql_db", "amxx", FCVAR_PROTECTED);
  cvar_sql_user    = register_cvar("amx_sql_user", "root", FCVAR_PROTECTED);
  cvar_sql_pass    = register_cvar("amx_sql_pass", "", FCVAR_PROTECTED);
  #else
  cvar_sql_host    = register_cvar("coin_sql_host", "127.0.0.1", FCVAR_PROTECTED);
  cvar_sql_db    = register_cvar("coin_sql_db", "amxx", FCVAR_PROTECTED);
  cvar_sql_user    = register_cvar("coin_sql_user", "root", FCVAR_PROTECTED);
  cvar_sql_pass    = register_cvar("coin_sql_pass", "", FCVAR_PROTECTED);
  #endif
 
  cvar_sql_table = register_cvar("coin_sql_table", "coins", FCVAR_PROTECTED);
}

@register_forwards()
{
  forwards[GIVE_COINS_PRE] = CreateMultiForward("sc_give_coins_pre", ET_STOP, FP_CELL, FP_CELL);
  forwards[GIVE_COINS_POST] = CreateMultiForward("sc_give_coins_post", ET_IGNORE, FP_CELL, FP_CELL);
  forwards[COINS_PICKUP_PRE] = CreateMultiForward("sc_coins_pickup_pre", ET_STOP, FP_CELL, FP_CELL);
  forwards[COINS_PICKUP_POST] = CreateMultiForward("sc_coins_pickup_post", ET_IGNORE, FP_CELL, FP_CELL);
  forwards[COIN_PULL] = CreateMultiForward("sc_coin_pull", ET_STOP, FP_CELL, FP_CELL);
}

@load_config()
{
  new filepath[128];
  get_localinfo("amxx_configsdir", filepath, charsmax(filepath));
  formatex(filepath, charsmax(filepath), "%s/%s", filepath, "coins.cfg");
  server_cmd("exec %s", filepath);
}

public plugin_precache()
{   
  precache_model(COIN_MODEL_PATH);

  new filepath[128];
  format(filepath, charsmax(filepath), "%s.%s", COIN_SOUND_PATH, "wav");
  precache_sound(filepath);
}

public plugin_natives()
{
  register_native("get_user_coins", "@native_get_user_coins");
  register_native("set_user_coins", "@native_set_user_coins");
  register_native("user_drop_coins", "@native_user_drop_coins");
}

public plugin_init()
{
  register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
  register_dictionary("coins.txt");

  @register_cvars();
  @register_forwards();
  @load_config();

  RegisterHookChain(RG_CBasePlayer_Killed, "@CBasePlayer_Killed_Post", true);
  RegisterHookChain(RG_RoundEnd, "@RoundEnd_Post", true);

  if(get_pcvar_bool(cvar_coin_clear)) {
    RegisterHookChain(RG_CSGameRules_CleanUpMap, "@CSGameRules_CleanUpMap", true);
  }
}

public client_putinserver(id)
{
  if (is_player(id)) {
    if(get_pcvar_bool(cvar_coin_hud_enable))
      set_task(1.0, "@show_hud_info", id, .flags = "b");

    players[id] = 0;
    connected[id] = true;
    @sql_read_client(id);
  }
}

public client_disconnected(id)
{
  if(get_pcvar_bool(cvar_coin_hud_enable))
    remove_task(id);

  players[id] = 0;
  connected[id] = false;
}

public plugin_end()
{
  if(sql_tuple) SQL_FreeHandle(sql_tuple);
}

@RoundEnd_Post(WinStatus: status, ScenarioEventEndRound: event, delay)
{
  if(status == WINSTATUS_TERRORISTS || status == WINSTATUS_CTS) {
    new coin_add_alive = get_pcvar_num(cvar_coin_give_alive);
    if (coin_add_alive) {
      for(new id = 0; id <= MAX_PLAYERS; ++id) {
        if (connected[id] && is_user_alive(id)) {
          set_user_coins(id, players[id] += coin_add_alive);
        }
      }
    }
  }
}

public plugin_cfg()
{
  new error, data[256], sql_host[32], sql_user[32], sql_pass[32], sql_db[32];
  get_pcvar_string(cvar_sql_host, sql_host, charsmax(sql_host));
  get_pcvar_string(cvar_sql_user, sql_user, charsmax(sql_user));
  get_pcvar_string(cvar_sql_pass, sql_pass, charsmax(sql_pass));
  get_pcvar_string(cvar_sql_db, sql_db, charsmax(sql_db));

  sql_tuple = SQL_MakeDbTuple(sql_host, sql_user, sql_pass, sql_db);
  sql_connection = SQL_Connect(sql_tuple, error, data, charsmax(data));
 
  if(sql_connection == Empty_Handle)
    set_fail_state("[%s] Error connecting to database (mysql)^nError: %s", PLUGIN_NAME, data);
 
  SQL_FreeHandle(sql_connection);
  @check_table();
}

@check_table()
{
  new sql_table[32], sql_query[256];
  get_pcvar_string(cvar_sql_table, sql_table, charsmax(sql_table));

  format(sql_query, charsmax(sql_query), "CREATE TABLE IF NOT EXISTS `%s` \
  (`steamid` varchar(%d) PRIMARY KEY NOT NULL, \
  `count` int NOT NULL)", sql_table, STEAMID_SIZE);
 
  SQL_ThreadQuery(sql_tuple, "@query_func_handler", .query = sql_query);
}

@sql_read_client(id)
{ 
  if (connected[id]) {
    new sql_table[32], index[2], data[256];
    get_pcvar_string(cvar_sql_table, sql_table, charsmax(sql_table));

    new authid[STEAMID_SIZE];
    get_user_authid(id, authid, charsmax(authid));
    format(data, charsmax(data), "SELECT count FROM %s WHERE steamid = '%s'", sql_table, authid);

    index[0] = id;
    SQL_ThreadQuery(sql_tuple, "@query_read_handler", data, index, charsmax(index));
  }
}

@query_func_handler(fail_state, Handle: query_handle, error_msg[], error_code, data[], size, Float: queue)
{
  if(fail_state != TQUERY_SUCCESS) {
    server_print("[%s] %s", PLUGIN_NAME, error_msg);
    log_amx("[%s] %s", PLUGIN_NAME, error_msg);
  }   
  SQL_FreeHandle(query_handle);
}

@query_read_handler(fail_state, Handle: query_handle, error_msg[], error_code, data[], size, Float: queue)
{
  if(size && fail_state == TQUERY_SUCCESS) {
    new id = data[0];
    if(connected[id] && SQL_NumResults(query_handle)) {
      players[id] = SQL_ReadResult(query_handle, 0);
    }
  } else {
    server_print("[%s] %s", PLUGIN_NAME, error_msg);
    log_amx("[%s] %s", PLUGIN_NAME, error_msg);
  }
  SQL_FreeHandle(query_handle);
}

bool:@sql_save_client(id)
{
  new bool:result = false;
  if ((result = connected[id])) {
    new sql_table[32], data[256], authid[STEAMID_SIZE];

    get_user_authid(id, authid, charsmax(authid));
    get_pcvar_string(cvar_sql_table, sql_table, charsmax(sql_table));
    format(data, charsmax(data), "REPLACE INTO %s (steamid, count) VALUES ('%s', '%i')", sql_table, authid, players[id]);
    
    SQL_ThreadQuery(sql_tuple, "@query_func_handler", .query = data);
  }
  return result;
}

// -----------------------------------------------------------------------------

bool:set_user_coins(id, number)
{   
  new result;
  ExecuteForward(forwards[GIVE_COINS_PRE], result, id, number);

  if(result == HC_CONTINUE) {
    ExecuteForward(forwards[GIVE_COINS_POST], result, id, players[id] - number);

    players[id] = number;
    return @sql_save_client(id);
  }
  return false;
}

@show_hud_info(id)
{
  if (connected[id] && is_user_alive(id)) {
    set_hudmessage(
      get_pcvar_num(cvar_coin_hud_color_red),
      get_pcvar_num(cvar_coin_hud_color_green),
      get_pcvar_num(cvar_coin_hud_color_blue),
      get_pcvar_float(cvar_coin_hud_position_x),
      get_pcvar_float(cvar_coin_hud_position_y), .holdtime = 1.0, .channel = 3);
    show_hudmessage(id, "%L: %i", LANG_PLAYER, "MONEY", players[id]);
  }
}

// -----------------------------------------------------------------------------

@CSGameRules_CleanUpMap()
{
  new entity = FM_NULLENT;
  while((entity = rg_find_ent_by_class(entity, "ent_coin"))) {
    if(!is_nullent(entity)) {
      set_entvar(entity, var_flags, FL_KILLME);
    }
  }
}

@CBasePlayer_Killed_Post(victim, killer)
{
  if(connected[killer] && connected[victim] && victim != killer) {
    new coin_kill_head = get_pcvar_num(cvar_coin_give_kill_head);
    new coin_kill_grenade = get_pcvar_num(cvar_coin_give_kill_grenade);
    new coin_kill_knife = get_pcvar_num(cvar_coin_give_kill_knife);
    new coin_kill_flag = get_pcvar_num(cvar_coin_give_kill_flag);
    new coins = get_pcvar_num(cvar_coin_give_kill);
    
    if (get_member(killer, m_LastHitGroup) == HIT_HEAD)
      coins += coin_kill_head;
    
    if (get_member(killer, m_bitsDamageType) & DMG_GRENADE)
      coins += coin_kill_grenade;
    
    new item = get_member(killer, m_pActiveItem);
    if(!is_nullent(item) && get_member(item, m_iId) == WEAPON_KNIFE && killer == get_entvar(victim, var_dmg_inflictor))
      coins += coin_kill_knife;
    
    new string_flags[28];
    get_pcvar_string(cvar_coin_priv_flag, string_flags, charsmax(string_flags));

    new flags = read_flags(string_flags);       
    if (get_user_flags(killer) & flags) {
      coins += coin_kill_flag;
    }

    set_user_coins(victim, players[victim] -= coins);
    for (new i = 0; i < coins; ++i) @sc_create_ent_coin(victim, killer);
  }
}

// -----------------------------------------------------------------------------

@ent_set_glow(entity, color[3])
{
  new Float: render_color[3];
  new Float:coin_glow_amount = get_pcvar_float(cvar_coin_glow_amount);

  IVecFVec(color, render_color);
 
  set_entvar(entity, var_renderfx, kRenderFxGlowShell);
  set_entvar(entity, var_rendercolor, render_color);
  set_entvar(entity, var_rendermode, kRenderNormal);
  set_entvar(entity, var_renderamt, coin_glow_amount);
}

@sc_create_ent_coin(victim, killer)
{
  #define TIME_NEXTTHINK 0.1
  #define RANDOM_ANGLES 180.0
  #define RANDOM_VELOCITY 250.0
 
  new entity, Float: origin[3], Float: angles[3], Float: velocity[3];
  new coin_anim_type = get_pcvar_num(cvar_coin_anim_type);
  new Float:coin_anim_time = get_pcvar_float(cvar_coin_anim_time);

  entity = rg_create_entity("func_wall");
 
  get_entvar(victim, var_origin, origin);
  origin[2] += ENT_MAXSIZE[2];
 
  angles[1] = random_float(-RANDOM_ANGLES, RANDOM_ANGLES);
 
  velocity[0] = random_float(-RANDOM_VELOCITY, RANDOM_VELOCITY);
  velocity[1] = random_float(-RANDOM_VELOCITY, RANDOM_VELOCITY);
  velocity[2] = random_float(-RANDOM_VELOCITY, RANDOM_VELOCITY);
 
  engfunc(EngFunc_SetOrigin, entity, origin);
  engfunc(EngFunc_SetModel, entity, COIN_MODEL_PATH);
  engfunc(EngFunc_SetSize, entity, ENT_MINSIZE, ENT_MAXSIZE);
 
  set_entvar(entity, var_classname, "ent_coin");
  set_entvar(entity, var_solid, SOLID_TRIGGER);
  set_entvar(entity, var_movetype, MOVETYPE_TOSS);
  set_entvar(entity, var_sequence, coin_anim_type);
  set_entvar(entity, var_framerate, coin_anim_time);
  set_entvar(entity, var_angles, angles);
 
  if(get_pcvar_bool(cvar_coin_drop_only_killer) && is_user_connected(killer))
  {
    set_entvar(entity, var_owner, killer);
    set_entvar(entity, var_effects, EF_OWNER_VISIBILITY);
  }

  if(get_pcvar_bool(cvar_coin_glow_enable)) {
    new glow_color[3];

    glow_color[0] = get_pcvar_num(cvar_coin_glow_color_red);
    glow_color[1] = get_pcvar_num(cvar_coin_glow_color_green);
    glow_color[2] = get_pcvar_num(cvar_coin_glow_color_blue);

    @ent_set_glow(entity, glow_color);
  }

  set_entvar(entity, var_velocity, velocity);
 
  if(get_pcvar_bool(cvar_coin_pull_enable))
  {
    SetThink(entity, "@coin_think");
    set_entvar(entity, var_nextthink, get_gametime() + TIME_NEXTTHINK);
  }
 
  SetTouch(entity, "@coin_touch");
 
  #undef TIME_NEXTTHINK
  #undef RANDOM_ANGLES
  #undef RANDOM_VELOCITY
}

@coin_think(entity)
{
  #define UP_ORIGIN 10
  #define TIME_NEXTTHINK 0.1
  #define VELOCITY_MUL 999.0
 
  new Float:coin_pull_radius = get_pcvar_float(cvar_coin_pull_radius);
  static Float: game_time; game_time = get_gametime();
  set_entvar(entity, var_nextthink, game_time + TIME_NEXTTHINK);
 
  static id, Float: origin_start[3], Float: origin_end[3], Float: velocity[3], Float: min_dist, Float: temp, index_pull, owner;
 
  get_entvar(entity, var_origin, origin_start); origin_start[2] += UP_ORIGIN;
  id = index_pull = FM_NULLENT;
  min_dist = coin_pull_radius;
  owner = get_entvar(entity, var_owner);
 
  new string_flags[28];
  get_pcvar_string(cvar_coin_priv_flag, string_flags, charsmax(string_flags));

  new flags = read_flags(string_flags);
  while((id = engfunc(EngFunc_FindEntityInSphere, id, origin_start, coin_pull_radius))) {
    if(!is_user_alive(id) || !(get_user_flags(id) & flags) || (get_pcvar_bool(cvar_coin_drop_only_killer) && id != owner))
      continue;
 
    get_entvar(id, var_origin, origin_end);
    
    if(!fm_is_ent_visible(id, entity))
      continue;
    
    temp = get_distance_f(origin_start, origin_end);
    if(temp < min_dist) {
      min_dist = temp;
      index_pull = id;
    }
  }

  if(!is_user_alive(index_pull))
    return;
 
  static result;
  ExecuteForward(forwards[COIN_PULL], result, index_pull, entity);
 
  if(result == HC_CONTINUE) {
    get_entvar(index_pull, var_origin, origin_end);
    
    xs_vec_sub(origin_end, origin_start, velocity);
    xs_vec_normalize(velocity, velocity);
    xs_vec_mul_scalar(velocity, VELOCITY_MUL, velocity);
      
    set_entvar(entity, var_velocity, velocity);
  }
 
  #undef UP_ORIGIN
  #undef TIME_NEXTTHINK
  #undef VELOCITY_MUL
}

@coin_touch(entity, id)
{
  #define TIME_NEXTTCHEK 0.1

  if(!is_user_connected(id))
    return;

  static Float: game_time, Float: next_time[MAX_PLAYERS+1];
  game_time = get_gametime();
 
  if(next_time[id] < game_time) {
    next_time[id] = game_time + TIME_NEXTTCHEK;
 
    if(get_pcvar_bool(cvar_coin_drop_only_killer) && get_entvar(entity, var_owner) != id)
      return;
 
    static result;
    ExecuteForward(forwards[COINS_PICKUP_PRE], result, id, entity);
    
    if(result == HC_CONTINUE) {
      if (set_user_coins(id, ++players[id])) {
        client_cmd(id, "spk %s", COIN_SOUND_PATH);
      }

      SetThink(entity, "");
      SetTouch(entity, "");
      set_entvar(entity, var_flags, FL_KILLME);
      
      ExecuteForward(forwards[COINS_PICKUP_POST], result, id, entity);
    }
  }
 
  #undef TIME_NEXTTCHEK
}

// -----------------------------------------------------------------------------

/**
 * Returns the number of coins the player has (-1 if the player is not found).
 * @return int
 */
@native_get_user_coins()
{
  new id = get_param(1);
  return connected[id] ? players[id] : -1;
}

/**
 * Sets the specified number of coins.
 * @return bool
 */
bool:@native_set_user_coins()
{
  new id = get_param(1);
  new count = get_param(2);
  return set_user_coins(id, count);
}

/**
 * Drops the player a certain number of coins.
 * @return bool
 */
bool:@native_user_drop_coins()
{
  new id = get_param(1);
  new count = get_param(2);
  new bool:result = false;

  if ((result = set_user_coins(id, count))) { 
    for(new coin = 0; coin < count; ++coin) {
      @sc_create_ent_coin(id, 0);
    }
  }
  return result;
}
Сверху Снизу