Переделка плагина SF Levl Skins

Сообщения
143
Реакции
68
Помог
1 раз(а)
И так что ми имеем.
Немного изменив плагин SF Levl Skins, сделал поддержку для CMSStats Ranks
Получилось так
Код:
#include <amxmodx>
#include <reapi>
#include <fakemeta>
#include <hamsandwich>

#pragma semicolon 1

#define is_str_empty(%1) (%1[0] == EOS)

native cmsranks_get_user_level(id, string[] = "", len = 0);
native cmsapi_get_user_setting(iClient, szSettingName[], value[] = "", value_length = 0);
native bool:cmsapi_set_user_setting(iClient, szSettingName[], value[], bool:delete = false);

enum
{
  KI_MODEL_TT,
  KI_MODEL_CT,
  KI_WEAPON_DATA
}

enum _:skin_info_struct {
  SKIN_LEVEL_FROM,
  SKIN_LEVEL_TO,
  SKIN_WEAPON_NAME[32],
  SKIN_V_MODEL[256],
  SKIN_W_MODEL[256],
  SKIN_P_MODEL[256],
  SKIN_NAME[64]
}

enum _:plrmodel_info_struct {
  PLRSKIN_LEVEL_FROM,
  PLRSKIN_LEVEL_TO,
  PLRSKIN_NAME[32],
  PLRSKIN_MODEL_T[32],
  PLRSKIN_MODEL_CT[32]
}

new player_weapon_models[MAX_PLAYERS + 1][33];
new player_tt_models[MAX_PLAYERS + 1][32];
new player_ct_models[MAX_PLAYERS + 1][32];

new Array:weapon_skins;
new weapon_skins_length;

new Array:player_skins;
new player_skins_length;

new prm_menu;
new skn_menu_cb;
new plr_menu_cb;

public plugin_init() {
  register_dictionary("cms_level_skins.txt");
  register_forward(FM_SetModel, "Hook_SetModel");
  RegisterHookChain(RG_CBasePlayer_Spawn, "Hook_PlayerSpawn", true);

  register_clcmd("say /skin", "PrmMenu_Show");
  register_clcmd("say_team /skin", "PrmMenu_Show");
}

public plugin_precache() {
  register_plugin("CMS Level Skins", "1.0", "freeman");

  weapon_skins = ArrayCreate(skin_info_struct);
  player_skins = ArrayCreate(plrmodel_info_struct);

  prm_menu = menu_create(fmt("%l", "CMS_TITLE_MENU"), "PrmMenu_Handler");

  menu_additem(prm_menu, fmt("%l", "CMS_SKIN_WEAPON"), "1");
  menu_additem(prm_menu, fmt("%l", "CMS_SKIN_PLAYER"), "2");
  menu_additem(prm_menu, fmt("%l", "CMS_SKIN_BACK_WEAPON"), "3");
  menu_additem(prm_menu, fmt("%l", "CMS_SKIN_BACK_PLAYER"), "4");

  skn_menu_cb = menu_makecallback("SknMenu_Callback");
  plr_menu_cb = menu_makecallback("PlrMenu_Callback");

  menu_setprop(prm_menu, MPROP_EXITNAME, fmt("%l", "CMS_EXIT"));

  new f = fopen("addons/amxmodx/configs/gamecms/cms_level_skins.ini", "r");

  new Trie:is_hooked = TrieCreate();
  new read_buffer[1024],current_section = 0;

  while(!feof(f)) {
    fgets(f, read_buffer, charsmax(read_buffer));
    trim(read_buffer);

    if(!read_buffer[0] || read_buffer[0] == ';') {
      continue;
    }

    if(strcmp(read_buffer, "[WEAPON]") == 0) {
      current_section = 1;
      continue;
    } else if(strcmp(read_buffer, "[PLAYER]") == 0) {
      current_section = 2;
      continue;
    }

    switch(current_section) {
      case 1: {
        new s_level[21],  skin_info[skin_info_struct];

        parse(read_buffer,
          s_level, charsmax(s_level),
          skin_info[SKIN_WEAPON_NAME], charsmax(skin_info[SKIN_WEAPON_NAME]),
          skin_info[SKIN_V_MODEL], charsmax(skin_info[SKIN_V_MODEL]),
          skin_info[SKIN_W_MODEL], charsmax(skin_info[SKIN_W_MODEL]),
          skin_info[SKIN_P_MODEL], charsmax(skin_info[SKIN_P_MODEL]),
          skin_info[SKIN_NAME], charsmax(skin_info[SKIN_NAME])
        );
        
        new s_lvl_from[10], s_lvl_to[10];
        strtok(s_level, s_lvl_from, charsmax(s_lvl_from), s_lvl_to, charsmax(s_lvl_to), '-');
            
        skin_info[SKIN_LEVEL_FROM] = str_to_num(s_lvl_from);
        skin_info[SKIN_LEVEL_TO] = str_to_num(s_lvl_to);

        if(skin_info[SKIN_V_MODEL][0]) {
          if(file_exists(skin_info[SKIN_V_MODEL])) {
            precache_model(skin_info[SKIN_V_MODEL]);
          } else {
            log_amx("weapon model file ^"%s^" not found", skin_info[SKIN_V_MODEL]);
            skin_info[SKIN_V_MODEL][0] = 0;
          }
        }

        if(skin_info[SKIN_W_MODEL][0]) {
          if(file_exists(skin_info[SKIN_W_MODEL])) {
            precache_model(skin_info[SKIN_W_MODEL]);
          } else {
            log_amx("weapon model file ^"%s^" not found", skin_info[SKIN_W_MODEL]);
            skin_info[SKIN_W_MODEL][0] = 0;
          }
        }

        if(skin_info[SKIN_P_MODEL][0]) {
          if(file_exists(skin_info[SKIN_P_MODEL])) {
            precache_model(skin_info[SKIN_P_MODEL]);
          } else {
            log_amx("weapon model file ^"%s^" not found", skin_info[SKIN_P_MODEL]);
            skin_info[SKIN_P_MODEL][0] = 0;
          }
        }
        
        ArrayPushArray(weapon_skins, skin_info);
        weapon_skins_length ++;

        if(!TrieKeyExists(is_hooked, skin_info[SKIN_WEAPON_NAME])) {
          RegisterHam(Ham_Item_Deploy, skin_info[SKIN_WEAPON_NAME], "Hook_WeaponDeploy", true);
          RegisterHam(Ham_Item_AddToPlayer, skin_info[SKIN_WEAPON_NAME], "Hook_WeaponAddToPlayer", true);

          TrieSetCell(is_hooked, skin_info[SKIN_WEAPON_NAME], true);
        }
      }
      case 2: {
        new s_level[21], plr_skin_info[plrmodel_info_struct], mdl_path[256];
        parse(read_buffer, s_level, charsmax(s_level), plr_skin_info[PLRSKIN_MODEL_T], charsmax(plr_skin_info[PLRSKIN_MODEL_T]), plr_skin_info[PLRSKIN_MODEL_CT], charsmax(plr_skin_info[PLRSKIN_MODEL_CT]), plr_skin_info[PLRSKIN_NAME], charsmax(plr_skin_info[PLRSKIN_NAME]));

        new s_lvl_from[10], s_lvl_to[10];
        strtok(s_level, s_lvl_from, charsmax(s_lvl_from), s_lvl_to, charsmax(s_lvl_to), '-');
        
        plr_skin_info[PLRSKIN_LEVEL_FROM] = str_to_num(s_lvl_from);
        plr_skin_info[PLRSKIN_LEVEL_TO] = str_to_num(s_lvl_to);
        
        formatex(mdl_path, charsmax(mdl_path), "models/player/%s/%s.mdl", plr_skin_info[PLRSKIN_MODEL_T], plr_skin_info[PLRSKIN_MODEL_T]);

        if(file_exists(mdl_path)) {
          precache_model(mdl_path);

          formatex(mdl_path, charsmax(mdl_path), "models/player/%s/%sT.mdl", plr_skin_info[PLRSKIN_MODEL_T], plr_skin_info[PLRSKIN_MODEL_T]);

          if(file_exists(mdl_path)) {
            precache_model(mdl_path);
          }
        } else {
          log_amx("player  model file ^"%s^" not found", mdl_path);
          plr_skin_info[PLRSKIN_MODEL_T][0] = 0;
        }

        formatex(mdl_path, charsmax(mdl_path), "models/player/%s/%s.mdl", plr_skin_info[PLRSKIN_MODEL_CT], plr_skin_info[PLRSKIN_MODEL_CT]);

        if(file_exists(mdl_path)) {
          precache_model(mdl_path);

          formatex(mdl_path, charsmax(mdl_path), "models/player/%s/%sT.mdl", plr_skin_info[PLRSKIN_MODEL_CT], plr_skin_info[PLRSKIN_MODEL_CT]);

          if(file_exists(mdl_path)) {
            precache_model(mdl_path);
          }
        } else {
          log_amx("player  model file ^"%s^" not found", mdl_path);
          plr_skin_info[PLRSKIN_MODEL_CT][0] = 0;
        }

        ArrayPushArray(player_skins, plr_skin_info);
        player_skins_length ++;
      }
    }
  }

  TrieDestroy(is_hooked);

}

public client_putinserver(id) {
  arrayset(player_weapon_models[id][0], -1, sizeof player_weapon_models * sizeof player_weapon_models[]);
  SetSkinsByLevel(id);
}

public aes_player_levelup(id) {
  SetSkinsByLevel(id);
}

public aes_player_leveldown(id) {
  SetSkinsByLevel(id);
}

public SetSkinsByLevel(id) {
  if(!is_user_connected(id)) {
    return;
  }
 
  new player_level = cmsranks_get_user_level(id);
 
  if(player_level <= 0) {
    set_task(1.0, "SetSkinsByLevel", id);
    return;
  }
 
  new i, skin_info[skin_info_struct], plrmodel[plrmodel_info_struct];
 
  for(i = (weapon_skins_length - 1) ; i >= 0; i--) {
    ArrayGetArray(weapon_skins, i, skin_info);

    if((!skin_info[SKIN_LEVEL_TO] && player_level >= skin_info[SKIN_LEVEL_FROM]) || (skin_info[SKIN_LEVEL_TO] && (skin_info[SKIN_LEVEL_FROM] <= player_level <= skin_info[SKIN_LEVEL_TO]))) {
      new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME]);

      if(player_weapon_models[id][w_id] == -1) {
        player_weapon_models[id][w_id] = i;
      }
    }
  }
 
  for(i = (player_skins_length - 1) ; i >= 0 ; i--) {
    ArrayGetArray(player_skins, i, plrmodel);
    
    
    if((!plrmodel[PLRSKIN_LEVEL_TO] && player_level >= plrmodel[PLRSKIN_LEVEL_FROM]) ||
      (plrmodel[PLRSKIN_LEVEL_TO] && (plrmodel[PLRSKIN_LEVEL_FROM] <= player_level <= plrmodel[PLRSKIN_LEVEL_TO]))
    ) {
      if(!strlen(player_tt_models[id]) && !strlen(player_ct_models[id])) {
        copy(player_tt_models[id], charsmax(player_tt_models[]), plrmodel[PLRSKIN_MODEL_T]);
        copy(player_ct_models[id], charsmax(player_ct_models[]), plrmodel[PLRSKIN_MODEL_CT]);
      }
    }
  }
}

public Hook_SetModel(ent, const model[]) {
  if(contain(model, "models/w_") == 0) {
    new classname[32];
    get_entvar(ent, var_classname, classname, charsmax(classname));

    if(strcmp(classname, "weaponbox") == 0) {
      new wpn = WeaponBox_FindWpn(ent);

      if(wpn != -1) {
        new Float:si_vec[3];
        get_entvar(wpn, var_vuser4, si_vec);

        if(si_vec[0] == 2.0) {
          new si_id = floatround(si_vec[2]);

          new skin_info[skin_info_struct];
          ArrayGetArray(weapon_skins, si_id, skin_info);

          if(skin_info[SKIN_W_MODEL]) {
            engfunc(EngFunc_SetModel, ent, skin_info[SKIN_W_MODEL]);
            return FMRES_SUPERCEDE;
          }
        }
      }
    }
  }

  return FMRES_IGNORED;
}

public Hook_PlayerSpawn(id)
{
  if(strlen(player_tt_models[id]) || strlen(player_ct_models[id])) {
    new mdl[32], team = get_member(id, m_iTeam);
    get_user_info(id, "model", mdl, charsmax(mdl));

    switch(team) {
      case TEAM_TERRORIST: {
        if(strlen(player_tt_models[id]) && strcmp(mdl, player_tt_models[id]) != 0) {
          rg_set_user_model(id, player_tt_models[id]);
        }
      }
      case TEAM_CT: {
        if(strlen(player_ct_models[id]) && strcmp(mdl, player_ct_models[id]) != 0) {
          rg_set_user_model(id, player_ct_models[id]);
        }
      }
    }
  }
}

public PrmMenu_Show(id) {
  menu_display(id, prm_menu);
}

public PrmMenu_Handler(id, m, item) {
  if(item == MENU_EXIT) {
    return PLUGIN_CONTINUE;
  }

  new item_info[10], dummy[2];
  menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0]);

  switch(str_to_num(item_info)) {
    case 1: WpnMenu_Show(id);
    case 2: PlrMenu_Show(id);
    case 3: WpnSkn_Disable(id);
    case 4: PlrSkn_Disable(id);
  }

  return PLUGIN_CONTINUE;
}

public WpnSkn_Disable(id)
{
  arrayset(player_weapon_models[id][0], -1, sizeof player_weapon_models * sizeof player_weapon_models[]);
  client_print_color(id, print_team_default, "%l %l", "CMS_PREFIX", "CMS_SKIN_WEAPON_RESET");
}

public PlrSkn_Disable(id) {
  rg_reset_user_model(id);

  player_tt_models[id][0] = 0;
  player_ct_models[id][0] = 0;

  client_print_color(id, print_team_default, "%l %l", "CMS_PREFIX", "CMS_SKIN_PLAYER_RESET");
}


public WpnMenu_Show(id) {
  new skn_menu, player_level = cmsranks_get_user_level(id);
 
  for(new s_i, skin_info[skin_info_struct] ; s_i < weapon_skins_length ; s_i++) {
    ArrayGetArray(weapon_skins, s_i, skin_info);
    
    if(
      (!skin_info[SKIN_LEVEL_TO] && player_level >= skin_info[SKIN_LEVEL_FROM]) ||
      (skin_info[SKIN_LEVEL_TO] && (skin_info[SKIN_LEVEL_FROM] <= player_level <= skin_info[SKIN_LEVEL_TO]))
    ) {
      if(!skn_menu) {
        skn_menu = menu_create("[Скин оружия]", "SknMenu_Handler");
      }
      
      new s_i_str[10];
      num_to_str(s_i, s_i_str, charsmax(s_i_str));
      menu_additem(skn_menu, "placeholder", s_i_str, 0, skn_menu_cb);
    }
  }

  menu_setprop(skn_menu, MPROP_EXITNAME, fmt("%l", "CMS_BACK"));
 
  if(skn_menu) {
    menu_display(id, skn_menu);
  } else {
    client_print_color(id, print_team_default, "%l %l", "CMS_PREFIX", "CMS_SKIN_CHOOSE");
  }
}

public SknMenu_Handler(id, m, item) {
  if(item == MENU_EXIT) {
    menu_destroy(m);
    menu_display(id, prm_menu);
    
    return PLUGIN_CONTINUE;
  }

  new item_info[10], dummy[2];
  menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0]);
 
  new si_id = str_to_num(item_info);

  new skin_info[skin_info_struct];
  ArrayGetArray(weapon_skins, si_id, skin_info);

  new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME]);

  player_weapon_models[id][w_id] = si_id;

  client_print_color(id, print_team_default, "%l %l", "CMS_PREFIX", "CMS_SKIN_CHOOSE_WEAPON", skin_info[SKIN_NAME]);
  menu_display(id, m);
 
  return PLUGIN_CONTINUE;
}

public SknMenu_Callback(id, m, item) {
  new item_info[10], dummy[2];
  menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0]);

  new si_id = str_to_num(item_info);

  new skin_info[skin_info_struct];
  ArrayGetArray(weapon_skins, si_id, skin_info);

  new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME]);

  if(player_weapon_models[id][w_id] == si_id) {
    new item_name[64];
    formatex(item_name, charsmax(item_name), "\w%s \r+", skin_info[SKIN_NAME]);
    menu_item_setname(m, item, item_name);

    return ITEM_DISABLED;
  }  else {
    menu_item_setname(m, item, skin_info[SKIN_NAME]);
  }

  return ITEM_ENABLED;
}

public PlrMenu_Show(id) {
  new plr_menu = menu_create("[Скин игрока]", "PlrMenu_Handler");
  new player_level = cmsranks_get_user_level(id);
 
  for(new i, plrmodel[plrmodel_info_struct], item_info[10] ; i < player_skins_length ; i++) {
    ArrayGetArray(player_skins, i, plrmodel);
    
    if(
      (!plrmodel[PLRSKIN_LEVEL_TO] && player_level >= plrmodel[PLRSKIN_LEVEL_FROM]) ||
      (plrmodel[PLRSKIN_LEVEL_TO] && (plrmodel[PLRSKIN_LEVEL_FROM] <= player_level <= plrmodel[PLRSKIN_LEVEL_TO]))
    ){
      formatex(item_info, charsmax(item_info), "%d", i);
      menu_additem(plr_menu, plrmodel[PLRSKIN_NAME], item_info, 0, plr_menu_cb);
    }
  }
 
  menu_setprop(plr_menu, MPROP_EXITNAME, fmt("%l", "CMS_BACK"));
  menu_display(id, plr_menu);
}


public PlrMenu_Handler(id, m, item) {
  if(item == MENU_EXIT) {
    menu_destroy(m);
    menu_display(id, prm_menu);
    return PLUGIN_CONTINUE;
  }

  new item_info[10],  dummy[2];
  menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0]);

  new player_level = cmsranks_get_user_level(id);
  new si_id = str_to_num(item_info);
 
  new plrmodel[plrmodel_info_struct];
  ArrayGetArray(player_skins, si_id, plrmodel);

  if(
    (!plrmodel[PLRSKIN_LEVEL_TO] && player_level >= plrmodel[PLRSKIN_LEVEL_FROM]) ||
    (plrmodel[PLRSKIN_LEVEL_TO] && (plrmodel[PLRSKIN_LEVEL_FROM] <= player_level <= plrmodel[PLRSKIN_LEVEL_TO]))
  ) {
    copy(player_tt_models[id], charsmax(player_tt_models[]), plrmodel[PLRSKIN_MODEL_T]);
    copy(player_ct_models[id], charsmax(player_ct_models[]), plrmodel[PLRSKIN_MODEL_CT]);

    client_print_color(id, print_team_default, "%l %l", "CMS_PREFIX", "CMS_SKIN_CHOOSE_PLAYER", plrmodel[PLRSKIN_NAME]);

    menu_display(id, m);
    return PLUGIN_CONTINUE;
  }

  menu_destroy(m);
  return PLUGIN_CONTINUE;
}

public PlrMenu_Callback(id, m, item) {
  new item_info[10], dummy[2];
  menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0]);

  new si_id = str_to_num(item_info);
  new plrmodel[plrmodel_info_struct];
  ArrayGetArray(player_skins, si_id, plrmodel);

  if (strcmp(player_tt_models[id], plrmodel[PLRSKIN_MODEL_T]) == 0 && strcmp(player_ct_models[id], plrmodel[PLRSKIN_MODEL_CT]) == 0) {
    new item_name[64];
    formatex(item_name, charsmax(item_name), "\w%s \r+", plrmodel[PLRSKIN_NAME]);
    menu_item_setname(m, item, item_name);

    return ITEM_DISABLED;
  }  else {
    menu_item_setname(m, item, plrmodel[PLRSKIN_NAME]);
  }

  return ITEM_ENABLED;
}

public Hook_WeaponDeploy(ent) {
  new Float:si_vec[3];
  get_entvar(ent, var_vuser4, si_vec);

  if(si_vec[0] == 2.0) {
    new si_id = floatround(si_vec[2]);

    new skin_info[skin_info_struct];
    ArrayGetArray(weapon_skins, si_id, skin_info);

    if(skin_info[SKIN_V_MODEL] || skin_info[SKIN_P_MODEL]) {
      new id = get_member(ent, m_pPlayer);

      if(skin_info[SKIN_V_MODEL]) {
        set_entvar(id, var_viewmodel, skin_info[SKIN_V_MODEL]);
      }

      if(skin_info[SKIN_P_MODEL]) {
        set_entvar(id, var_weaponmodel, skin_info[SKIN_P_MODEL]);
      }
    }
  }
}

public Hook_WeaponAddToPlayer(ent) {
  new Float:si_vec[3];
  get_entvar(ent, var_vuser4, si_vec);

  if(si_vec[0] == 0.0) {
    new id = get_member(ent, m_pPlayer);
    new w_id = get_member(ent, m_iId);

    if(player_weapon_models[id][w_id] != -1) {
      si_vec[0] = 2.0;
      si_vec[2] = float(player_weapon_models[id][w_id]);
    } else {
      si_vec[0] = 1.0;
    }

    set_entvar(ent, var_vuser4, si_vec);
  }
}

stock WeaponBox_FindWpn(const ent) {
  for (new i = 1; i < MAX_ITEM_TYPES; ++i) {
    new pPackEntity = get_member(ent, m_WeaponBox_rgpPlayerItems, i);
    if (pPackEntity != -1) {
      return pPackEntity;
    }
  }

  return -1;
}
Захотел избавиться от моделей игроков, поетому решил убрать часть кода. Получилось вот так
Код:
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>

#pragma semicolon 1

#define is_str_empty(%1) (%1[0] == EOS)

native cmsranks_get_user_level(id, string[] = "", len = 0);
native cmsapi_get_user_setting(iClient, szSettingName[], value[] = "", value_length = 0);
native bool:cmsapi_set_user_setting(iClient, szSettingName[], value[], bool:delete = false);

enum _:skin_info_struct {
  SKIN_LEVEL_FROM,
  SKIN_LEVEL_TO,
  SKIN_WEAPON_NAME[32],
  SKIN_V_MODEL[256],
  SKIN_W_MODEL[256],
  SKIN_P_MODEL[256],
  SKIN_NAME[64]
}

new player_weapon_models[MAX_PLAYERS + 1][33];

new Array:weapon_skins;
new weapon_skins_length;

new prm_menu;
new skn_menu_cb;

public plugin_init() {
  register_dictionary("cms_level_skins.txt");
  register_forward(FM_SetModel, "Hook_SetModel");

  register_clcmd("say /skin", "PrmMenu_Show");
  register_clcmd("say_team /skin", "PrmMenu_Show");
}

public plugin_precache() {
  register_plugin("CMS Level Skins", "1.0", "freeman");

  weapon_skins = ArrayCreate(skin_info_struct);

  prm_menu = menu_create(fmt("%l", "CMS_TITLE_MENU"), "PrmMenu_Handler");

  menu_additem(prm_menu, fmt("%l", "CMS_SKIN_WEAPON"), "1");
  menu_additem(prm_menu, fmt("%l", "CMS_SKIN_BACK_WEAPON"), "2");

  skn_menu_cb = menu_makecallback("SknMenu_Callback");
  menu_setprop(prm_menu, MPROP_EXITNAME, fmt("%l", "CMS_EXIT"));
  new f = fopen("addons/amxmodx/configs/gamecms/cms_level_skins.ini", "r");

  new Trie:is_hooked = TrieCreate();
  new read_buffer[1024],current_section = 0;

  while(!feof(f)) {
    fgets(f, read_buffer, charsmax(read_buffer));
    trim(read_buffer);

    if(!read_buffer[0] || read_buffer[0] == ';') {
      continue;
    }

    if(strcmp(read_buffer, "[WEAPON]") == 0) {
      current_section = 1;
      continue;
    }

    switch(current_section) {
      case 1: {
        new s_level[21],  skin_info[skin_info_struct];

        parse(read_buffer,
          s_level, charsmax(s_level),
          skin_info[SKIN_WEAPON_NAME], charsmax(skin_info[SKIN_WEAPON_NAME]),
          skin_info[SKIN_V_MODEL], charsmax(skin_info[SKIN_V_MODEL]),
          skin_info[SKIN_W_MODEL], charsmax(skin_info[SKIN_W_MODEL]),
          skin_info[SKIN_P_MODEL], charsmax(skin_info[SKIN_P_MODEL]),
          skin_info[SKIN_NAME], charsmax(skin_info[SKIN_NAME])
        );
        
        new s_lvl_from[10], s_lvl_to[10];
        strtok(s_level, s_lvl_from, charsmax(s_lvl_from), s_lvl_to, charsmax(s_lvl_to), '-');
            
        skin_info[SKIN_LEVEL_FROM] = str_to_num(s_lvl_from);
        skin_info[SKIN_LEVEL_TO] = str_to_num(s_lvl_to);

        if(skin_info[SKIN_V_MODEL][0]) {
          if(file_exists(skin_info[SKIN_V_MODEL])) {
            precache_model(skin_info[SKIN_V_MODEL]);
          } else {
            log_amx("weapon model file ^"%s^" not found", skin_info[SKIN_V_MODEL]);
            skin_info[SKIN_V_MODEL][0] = 0;
          }
        }

        if(skin_info[SKIN_W_MODEL][0]) {
          if(file_exists(skin_info[SKIN_W_MODEL])) {
            precache_model(skin_info[SKIN_W_MODEL]);
          } else {
            log_amx("weapon model file ^"%s^" not found", skin_info[SKIN_W_MODEL]);
            skin_info[SKIN_W_MODEL][0] = 0;
          }
        }

        if(skin_info[SKIN_P_MODEL][0]) {
          if(file_exists(skin_info[SKIN_P_MODEL])) {
            precache_model(skin_info[SKIN_P_MODEL]);
          } else {
            log_amx("weapon model file ^"%s^" not found", skin_info[SKIN_P_MODEL]);
            skin_info[SKIN_P_MODEL][0] = 0;
          }
        }
        
        ArrayPushArray(weapon_skins, skin_info);
        weapon_skins_length ++;

        if(!TrieKeyExists(is_hooked, skin_info[SKIN_WEAPON_NAME])) {
          RegisterHam(Ham_Item_Deploy, skin_info[SKIN_WEAPON_NAME], "Hook_WeaponDeploy", true);
          RegisterHam(Ham_Item_AddToPlayer, skin_info[SKIN_WEAPON_NAME], "Hook_WeaponAddToPlayer", true);

          TrieSetCell(is_hooked, skin_info[SKIN_WEAPON_NAME], true);
        }
      }
    }
  }

  TrieDestroy(is_hooked);

}

public client_putinserver(id) {
  arrayset(player_weapon_models[id][0], -1, sizeof player_weapon_models * sizeof player_weapon_models[]);
  SetSkinsByLevel(id);
}

public aes_player_levelup(id) {
  SetSkinsByLevel(id);
}

public aes_player_leveldown(id) {
  SetSkinsByLevel(id);
}

public SetSkinsByLevel(id) {
  if(!is_user_connected(id)) {
    return;
  }
 
  new player_level = cmsranks_get_user_level(id);
 
  if(player_level <= 0) {
    set_task(1.0, "SetSkinsByLevel", id);
    return;
  }
 
  new i, skin_info[skin_info_struct];
 
  for(i = (weapon_skins_length - 1) ; i >= 0; i--) {
    ArrayGetArray(weapon_skins, i, skin_info);

    if((!skin_info[SKIN_LEVEL_TO] && player_level >= skin_info[SKIN_LEVEL_FROM]) || (skin_info[SKIN_LEVEL_TO] && (skin_info[SKIN_LEVEL_FROM] <= player_level <= skin_info[SKIN_LEVEL_TO]))) {
      new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME]);

      if(player_weapon_models[id][w_id] == -1) {
        player_weapon_models[id][w_id] = i;
      }
    }
  }
}

public Hook_SetModel(ent, const model[]) {
  if(contain(model, "models/w_") == 0) {
    new classname[32];
    get_entvar(ent, var_classname, classname, charsmax(classname));

    if(strcmp(classname, "weaponbox") == 0) {
      new wpn = WeaponBox_FindWpn(ent);

      if(wpn != -1) {
        new Float:si_vec[3];
        get_entvar(wpn, var_vuser4, si_vec);

        if(si_vec[0] == 2.0) {
          new si_id = floatround(si_vec[2]);

          new skin_info[skin_info_struct];
          ArrayGetArray(weapon_skins, si_id, skin_info);

          if(skin_info[SKIN_W_MODEL]) {
            engfunc(EngFunc_SetModel, ent, skin_info[SKIN_W_MODEL]);
            return FMRES_SUPERCEDE;
          }
        }
      }
    }
  }

  return FMRES_IGNORED;
}

public PrmMenu_Show(id) {
  menu_display(id, prm_menu);
}

public PrmMenu_Handler(id, m, item) {
  if(item == MENU_EXIT) {
    return PLUGIN_CONTINUE;
  }

  new item_info[10], dummy[2];
  menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0]);

  switch(str_to_num(item_info)) {
    case 1: WpnMenu_Show(id);
    case 2: WpnSkn_Disable(id);
  }

  return PLUGIN_CONTINUE;
}

public WpnSkn_Disable(id)
{
  arrayset(player_weapon_models[id][0], -1, sizeof player_weapon_models * sizeof player_weapon_models[]);
  client_print_color(id, print_team_default, "%l %l", "CMS_PREFIX", "CMS_SKIN_WEAPON_RESET");
}

public WpnMenu_Show(id) {
  new skn_menu, player_level = cmsranks_get_user_level(id);
 
  for(new s_i, skin_info[skin_info_struct] ; s_i < weapon_skins_length ; s_i++) {
    ArrayGetArray(weapon_skins, s_i, skin_info);
    
    if(
      (!skin_info[SKIN_LEVEL_TO] && player_level >= skin_info[SKIN_LEVEL_FROM]) ||
      (skin_info[SKIN_LEVEL_TO] && (skin_info[SKIN_LEVEL_FROM] <= player_level <= skin_info[SKIN_LEVEL_TO]))
    ) {
      if(!skn_menu) {
        skn_menu = menu_create("[Скин оружия]", "SknMenu_Handler");
      }
      
      new s_i_str[10];
      num_to_str(s_i, s_i_str, charsmax(s_i_str));
      menu_additem(skn_menu, "placeholder", s_i_str, 0, skn_menu_cb);
    }
  }

  menu_setprop(skn_menu, MPROP_EXITNAME, fmt("%l", "CMS_BACK"));
 
  if(skn_menu) {
    menu_display(id, skn_menu);
  } else {
    client_print_color(id, print_team_default, "%l %l", "CMS_PREFIX", "CMS_SKIN_CHOOSE");
  }
}

public SknMenu_Handler(id, m, item) {
  if(item == MENU_EXIT) {
    menu_destroy(m);
    menu_display(id, prm_menu);
    
    return PLUGIN_CONTINUE;
  }

  new item_info[10], dummy[2];
  menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0]);
 
  new si_id = str_to_num(item_info);

  new skin_info[skin_info_struct];
  ArrayGetArray(weapon_skins, si_id, skin_info);

  new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME]);

  player_weapon_models[id][w_id] = si_id;

  client_print_color(id, print_team_default, "%l %l", "CMS_PREFIX", "CMS_SKIN_CHOOSE_WEAPON", skin_info[SKIN_NAME]);
  menu_display(id, m);
 
  return PLUGIN_CONTINUE;
}

public SknMenu_Callback(id, m, item) {
  new item_info[10], dummy[2];
  menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0]);

  new si_id = str_to_num(item_info);

  new skin_info[skin_info_struct];
  ArrayGetArray(weapon_skins, si_id, skin_info);

  new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME]);

  if(player_weapon_models[id][w_id] == si_id) {
    new item_name[64];
    formatex(item_name, charsmax(item_name), "\w%s \r+", skin_info[SKIN_NAME]);
    menu_item_setname(m, item, item_name);

    return ITEM_DISABLED;
  }  else {
    menu_item_setname(m, item, skin_info[SKIN_NAME]);
  }

  return ITEM_ENABLED;
}

public Hook_WeaponDeploy(ent) {
  new Float:si_vec[3];
  get_entvar(ent, var_vuser4, si_vec);

  if(si_vec[0] == 2.0) {
    new si_id = floatround(si_vec[2]);

    new skin_info[skin_info_struct];
    ArrayGetArray(weapon_skins, si_id, skin_info);

    if(skin_info[SKIN_V_MODEL] || skin_info[SKIN_P_MODEL]) {
      new id = get_member(ent, m_pPlayer);

      if(skin_info[SKIN_V_MODEL]) {
        set_entvar(id, var_viewmodel, skin_info[SKIN_V_MODEL]);
      }

      if(skin_info[SKIN_P_MODEL]) {
        set_entvar(id, var_weaponmodel, skin_info[SKIN_P_MODEL]);
      }
    }
  }
}

public Hook_WeaponAddToPlayer(ent) {
  new Float:si_vec[3];
  get_entvar(ent, var_vuser4, si_vec);

  if(si_vec[0] == 0.0) {
    new id = get_member(ent, m_pPlayer);
    new w_id = get_member(ent, m_iId);

    if(player_weapon_models[id][w_id] != -1) {
      si_vec[0] = 2.0;
      si_vec[2] = float(player_weapon_models[id][w_id]);
    } else {
      si_vec[0] = 1.0;
    }

    set_entvar(ent, var_vuser4, si_vec);
  }
}

stock WeaponBox_FindWpn(const ent) {
  for (new i = 1; i < MAX_ITEM_TYPES; ++i) {
    new pPackEntity = get_member(ent, m_WeaponBox_rgpPlayerItems, i);
    if (pPackEntity != -1) {
      return pPackEntity;
    }
  }

  return -1;
}
В итоге плагин скомпилировался без ошибок. Но при попитке визвать меню командой, получаю ошибку
Код:
L 12/15/2019 - 06:16:06: Invalid menu id -1(13)
L 12/15/2019 - 06:16:06: [AMXX] Displaying debug trace (plugin "cms_level_skins.amxx", version "1.0")
L 12/15/2019 - 06:16:06: [AMXX] Run time error 10: native error (native "menu_display")
L 12/15/2019 - 06:16:06: [AMXX]    [0] cms_level_skins.sma::PrmMenu_Show (line 204)
Кто может подсказать где я упустил что то...
 
Сообщения
143
Реакции
68
Помог
1 раз(а)
Schokk, тоже подумал, но так не сработало
 
Сообщения
143
Реакции
68
Помог
1 раз(а)
Schokk, если так
Код:
public PrmMenu_Show(id) {
menu_display(id, prm_menu, 0);
return;
}
Тоже самое.... хммм
 
Сообщения
271
Реакции
348
Помог
15 раз(а)
лучше сразу кидать ссылку на diffchecker со своими изменениями
 
Сообщения
143
Реакции
68
Помог
1 раз(а)
И так перелопатил еще раз все с начало, и вуаля, все работает. Вернул некоторые дефолтные значения.
Вот привожу рабочий вариант.

Код:
#include <amxmodx>
#include <reapi>
#include <fakemeta>
#include <hamsandwich>

native cmsranks_get_user_level(id, string[] = "", len = 0);

enum _:skin_info_struct {
    SKIN_LEVEL_FROM,
    SKIN_LEVEL_TO,
    SKIN_WEAPON_NAME[32],
    SKIN_V_MODEL[256],
    SKIN_W_MODEL[256],
    SKIN_P_MODEL[256],
    SKIN_NAME[64]
}

enum _:weapon_models_struct {
    bool:SKIN_ON,
    SKIN_ID
}

new player_weapon_models[MAX_PLAYERS + 1][33][weapon_models_struct]
new Array:weapon_skins
new weapon_skins_length
new prm_menu
new skn_menu_cb

public plugin_precache() {
    register_plugin("SF Level Skins", "0.1", "serfreeman1337")

    weapon_skins = ArrayCreate(skin_info_struct)

    prm_menu = menu_create("\w========== ^n\rSKINS MENU ^n\w==========", "PrmMenu_Handler")
    
    menu_additem(prm_menu, "Скін: \y[\rЗброї\y]", "1")
    menu_additem(prm_menu, "\yСкинути: \w[\rскін Зброї\w]", "2")
    
    skn_menu_cb = menu_makecallback("SknMenu_Callback")
    menu_setprop(prm_menu, MPROP_EXITNAME, "Вихід")
    new f = fopen("addons/amxmodx/configs/gamecms/cms_level_skins.ini", "r")

    new Trie:is_hooked = TrieCreate()
    new read_buffer[1024],current_section = 0

    while(!feof(f)) {
        fgets(f, read_buffer, charsmax(read_buffer))
        trim(read_buffer)

        if(!read_buffer[0] || read_buffer[0] == ';') {
            continue
        }

        if(strcmp(read_buffer, "[WEAPON]") == 0) {
            current_section = 1
            continue
        }

        switch(current_section) {
            case 1: {
                new s_level[21],  skin_info[skin_info_struct]

                parse(read_buffer,
                    s_level, charsmax(s_level),
                    skin_info[SKIN_WEAPON_NAME], charsmax(skin_info[SKIN_WEAPON_NAME]),
                    skin_info[SKIN_V_MODEL], charsmax(skin_info[SKIN_V_MODEL]),
                    skin_info[SKIN_W_MODEL], charsmax(skin_info[SKIN_W_MODEL]),
                    skin_info[SKIN_P_MODEL], charsmax(skin_info[SKIN_P_MODEL]),
                    skin_info[SKIN_NAME], charsmax(skin_info[SKIN_NAME])
                )
                
                new s_lvl_from[10], s_lvl_to[10]
                strtok(s_level, s_lvl_from, charsmax(s_lvl_from), s_lvl_to, charsmax(s_lvl_to), '-')
                        
                skin_info[SKIN_LEVEL_FROM] = str_to_num(s_lvl_from)
                skin_info[SKIN_LEVEL_TO] = str_to_num(s_lvl_to)

                if(skin_info[SKIN_V_MODEL][0]) {
                    if(file_exists(skin_info[SKIN_V_MODEL])) {
                        precache_model(skin_info[SKIN_V_MODEL])
                    } else {
                        log_amx("weapon model file ^"%s^" not found",
                            skin_info[SKIN_V_MODEL])
                        skin_info[SKIN_V_MODEL][0] = 0
                    }
                }

                if(skin_info[SKIN_W_MODEL][0]) {
                    if(file_exists(skin_info[SKIN_W_MODEL])) {
                        precache_model(skin_info[SKIN_W_MODEL])
                    } else {
                        log_amx("weapon model file ^"%s^" not found",
                            skin_info[SKIN_W_MODEL])
                        skin_info[SKIN_W_MODEL][0] = 0
                    }
                }

                if(skin_info[SKIN_P_MODEL][0]) {
                    if(file_exists(skin_info[SKIN_P_MODEL])) {
                        precache_model(skin_info[SKIN_P_MODEL])
                    } else {
                        log_amx("weapon model file ^"%s^" not found",
                            skin_info[SKIN_P_MODEL])
                        skin_info[SKIN_P_MODEL][0] = 0
                    }
                }
                
                ArrayPushArray(weapon_skins, skin_info)
                weapon_skins_length ++

                if(!TrieKeyExists(is_hooked, skin_info[SKIN_WEAPON_NAME])) {
                    RegisterHam(Ham_Item_Deploy, skin_info[SKIN_WEAPON_NAME], "Hook_WeaponDeploy", true)
                    RegisterHam(Ham_Item_AddToPlayer, skin_info[SKIN_WEAPON_NAME], "Hook_WeaponAddToPlayer", true)

                    TrieSetCell(is_hooked, skin_info[SKIN_WEAPON_NAME], true)
                }
            }
        }
    }

    TrieDestroy(is_hooked)
}

public client_putinserver(id) {
    SetSkinsByLevel(id)
}

public aes_player_levelup(id) {
    SetSkinsByLevel(id)
}

public aes_player_leveldown(id) {
    SetSkinsByLevel(id)
}

public SetSkinsByLevel(id) {
    if(!is_user_connected(id)) {
        return
    }
    
    new player_level = cmsranks_get_user_level(id)
    
    if(player_level <= 0) {
        set_task(1.0, "SetSkinsByLevel", id)
        return
    }
    
    new i, skin_info[skin_info_struct]
    
    for(i = (weapon_skins_length - 1) ; i >= 0; i--) {
        ArrayGetArray(weapon_skins, i, skin_info)

        if(
            (!skin_info[SKIN_LEVEL_TO] && player_level >= skin_info[SKIN_LEVEL_FROM]) ||
            (skin_info[SKIN_LEVEL_TO] && (skin_info[SKIN_LEVEL_FROM] <= player_level <= skin_info[SKIN_LEVEL_TO]))
        ) {
            new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME])

            if(!player_weapon_models[id][w_id][SKIN_ON]) {
                player_weapon_models[id][w_id][SKIN_ON] = true
                player_weapon_models[id][w_id][SKIN_ID] = i
            }
        }
    }
}

public Hook_SetModel(ent, const model[]) {
    if(contain(model, "models/w_") == 0) {
        new classname[32]
        get_entvar(ent, var_classname, classname, charsmax(classname))

        if(strcmp(classname, "weaponbox") == 0) {
            new wpn = WeaponBox_FindWpn(ent)

            if(wpn != -1) {
                new Float:si_vec[3]
                get_entvar(wpn, var_vuser4, si_vec)

                if(si_vec[0] == 2.0) {
                    new si_id = floatround(si_vec[2])

                    new skin_info[skin_info_struct]
                    ArrayGetArray(weapon_skins, si_id, skin_info)

                    if(skin_info[SKIN_W_MODEL]) {
                        engfunc(EngFunc_SetModel, ent, skin_info[SKIN_W_MODEL])
                        return FMRES_SUPERCEDE
                    }
                }
            }
        }
    }

    return FMRES_IGNORED
}

public plugin_init() {
    register_forward(FM_SetModel, "Hook_SetModel")

    register_clcmd("say /skins", "PrmMenu_Show")
    register_clcmd("say_team /skins", "PrmMenu_Show")
}

public PrmMenu_Show(id) {
    menu_display(id, prm_menu)
}

public PrmMenu_Handler(id, m, item) {
    if(item == MENU_EXIT) {
        return PLUGIN_CONTINUE
    }

    new item_info[10], dummy[2]
    menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0])

    switch(str_to_num(item_info)) {
        case 1: WpnMenu_Show(id)
        case 2: WpnSkn_Disable(id)
    }

    return PLUGIN_CONTINUE
}

public WpnSkn_Disable(id) {
    for(new i ; i < 33 ; i++) {
        arrayset(player_weapon_models[id][i], 0, weapon_models_struct)
    }

    client_print_color(id, print_team_blue, "^1[^3SKINS^1] ^1Скіни Зброї скинуті!")
}

public WpnMenu_Show(id) {
    new skn_menu, player_level = cmsranks_get_user_level(id)
    
    for(new s_i, skin_info[skin_info_struct] ; s_i < weapon_skins_length ; s_i++) {
        ArrayGetArray(weapon_skins, s_i, skin_info)
        
        if(
            (!skin_info[SKIN_LEVEL_TO] && player_level >= skin_info[SKIN_LEVEL_FROM]) ||
            (skin_info[SKIN_LEVEL_TO] && (skin_info[SKIN_LEVEL_FROM] <= player_level <= skin_info[SKIN_LEVEL_TO]))
        ) {
            if(!skn_menu) {
                skn_menu = menu_create("[СКІНИ ЗБРОЇ]", "SknMenu_Handler")
            }
            
            new s_i_str[10]
            num_to_str(s_i, s_i_str, charsmax(s_i_str))
            menu_additem(skn_menu, "placeholder", s_i_str, 0, skn_menu_cb)
        }
    }

    menu_setprop(skn_menu, MPROP_EXITNAME, "Назад")
    
    if(skn_menu) {
        menu_display(id, skn_menu)
    } else {
        client_print_color(id, print_team_red, "^1[^3SKINS^1] Скін зброї вибрано^1. ^4Активація: ^1після дропу!")
    }
}

public SknMenu_Handler(id, m, item) {
    if(item == MENU_EXIT) {
        menu_destroy(m)
        menu_display(id, prm_menu)
        
        return PLUGIN_CONTINUE
    }

    new item_info[10], dummy[2]
    menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0])

    new si_id = str_to_num(item_info)

    new skin_info[skin_info_struct]
    ArrayGetArray(weapon_skins, si_id, skin_info)

    new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME])

    player_weapon_models[id][w_id][SKIN_ON] = true
    player_weapon_models[id][w_id][SKIN_ID] = si_id

    client_print_color(id, print_team_blue, "^1[^3SKINS^1] Скін зброї вибрано^1. ^4Активація: ^1після дропу!", skin_info[SKIN_NAME])
    menu_display(id, m)
    
    return PLUGIN_CONTINUE
}

public SknMenu_Callback(id, m, item) {
    new item_info[10], dummy[2]
    menu_item_getinfo(m, item, dummy[0], item_info, charsmax(item_info), dummy, charsmax(dummy), dummy[0])

    new si_id = str_to_num(item_info)

    new skin_info[skin_info_struct]
    ArrayGetArray(weapon_skins, si_id, skin_info)

    new w_id = get_weaponid(skin_info[SKIN_WEAPON_NAME])

    if(player_weapon_models[id][w_id][SKIN_ON] && player_weapon_models[id][w_id][SKIN_ID] == si_id) {
        new item_name[64]
        formatex(item_name, charsmax(item_name), "\w%s \r*", skin_info[SKIN_NAME])
        menu_item_setname(m, item, item_name)

        return ITEM_DISABLED
    }  else {
        menu_item_setname(m, item, skin_info[SKIN_NAME])
    }

    return ITEM_ENABLED
}

public Hook_WeaponDeploy(ent) {
    new Float:si_vec[3]
    get_entvar(ent, var_vuser4, si_vec)

    if(si_vec[0] == 2.0) {
        new si_id = floatround(si_vec[2])

        new skin_info[skin_info_struct]
        ArrayGetArray(weapon_skins, si_id, skin_info)

        if(skin_info[SKIN_V_MODEL] || skin_info[SKIN_P_MODEL]) {
            new id = get_member(ent, m_pPlayer)

            if(skin_info[SKIN_V_MODEL]) {
                set_entvar(id, var_viewmodel, skin_info[SKIN_V_MODEL])
            }

            if(skin_info[SKIN_P_MODEL]) {
                set_entvar(id, var_weaponmodel, skin_info[SKIN_P_MODEL])
            }
        }
    }
}

public Hook_WeaponAddToPlayer(ent) {
    new Float:si_vec[3]
    get_entvar(ent, var_vuser4, si_vec)

    if(si_vec[0] == 0.0) {
        new id = get_member(ent, m_pPlayer)
        new w_id = get_member(ent, m_iId)

        if(player_weapon_models[id][w_id][SKIN_ON]) {
            si_vec[0] = 2.0
            si_vec[2] = float(player_weapon_models[id][w_id][SKIN_ID])
        } else {
            si_vec[0] = 1.0
        }

        set_entvar(ent, var_vuser4, si_vec)
    }
}

stock WeaponBox_FindWpn(const ent) {
    for (new i = 1; i < MAX_ITEM_TYPES; ++i) {
        new pPackEntity = get_member(ent, m_WeaponBox_rgpPlayerItems, i)
        if (pPackEntity != -1) {
            return pPackEntity
        }
    }

    return -1
}
Выдача скинов (только оружие), по рангу.
Тему можно закрывать.
 

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

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