Создание функции отключения парашюта

Тема в разделе "Программирование / Скриптинг", создана пользователем Kruzi, 25 янв 2015.

  1. Kruzi

    Kruzi

    Сообщения:
    160
    Симпатии:
    2
    /*******************************************************************************
    Парашют 2.5.1
    Cvars:
    sm_parachute_enabled "1" - 0: disables the plugin - 1: enables the plugi
    sm_parachute_fallspeed "100" - speed of the fall when you use the parachute
    sm_parachute_linear "1" - 0: disables linear fallspeed - 1: enables it
    sm_parachute_msgtype "1" - 0: disables Information - 1: Chat - 2: Panel - 3: BottomCenter
    sm_parachute_cost "0" - cost of the parachute (CS ONLY) (If cost = 0 then free for everyone
    sm_parachute_payback "75" - how many percent of the parachute cost you get when you sell your parachute (ie. 75% of 1000 = 750$)
    sm_parachute_welcome "1" - 0: disables Welcome Message - 1: enables it
    sm_parachute_roundmsg "1" - 0: disables Round Message - 1: enables it
    sm_parachute_model "1" - 0: dont use the model - 1: display the Model
    sm_parachute_decrease "50" - 0: dont use Realistic velocity-decrease - x: sets the velocity-decrease.
    sm_parachute_button "1" - 1: uses button +USE for parachute usage. - 2: uses button +JUMP.
    *******************************************************************************/

    #include <sourcemod>
    #include <sdktools>
    #include <csgo_colors>

    #define PARACHUTE_VERSION "2.5.1"

    //Parachute Model
    #define PARACHUTE_MODEL "parachute_blue"

    //Parachute Textures
    #define PARACHUTE_PACK "pack_carbon"
    #define PARACHUTE_TEXTURE "parachute_blue"

    new g_iVelocity = -1;
    new g_iMoney = -1;
    new g_maxplayers = -1;

    new String:g_game[30];
    new String:path_model[256];
    new String:path_pack[256];
    new String:path_texture[256];

    new Handle:g_fallspeed = INVALID_HANDLE;
    new Handle:g_enabled = INVALID_HANDLE;
    new Handle:g_linear = INVALID_HANDLE;
    new Handle:g_msgtype = INVALID_HANDLE;
    new Handle:g_cost = INVALID_HANDLE;
    new Handle:g_payback = INVALID_HANDLE;
    new Handle:g_welcome = INVALID_HANDLE;
    new Handle:g_roundmsg = INVALID_HANDLE;
    new Handle:g_version = INVALID_HANDLE;
    new Handle:g_model = INVALID_HANDLE;
    new Handle:g_decrease = INVALID_HANDLE;
    new Handle:g_button = INVALID_HANDLE;

    new x;
    new cl_flags;
    new cl_buttons;
    new Float:speed[3];
    new bool:isfallspeed;

    new USE_BUTTON;
    new String:ButtonText[265];

    new bool:inUse[MAXPLAYERS+1];
    new bool:hasPara[MAXPLAYERS+1];
    new bool:hasModel[MAXPLAYERS+1];
    new Parachute_Ent[MAXPLAYERS+1];

    public Plugin:myinfo =
    {
    name = "SM Parachute",
    author = "SWAT_88",
    description = "To use your parachute press and hold your E(+use) button while falling.",
    version = PARACHUTE_VERSION,
    url = "http://www.sourcemod.net/"
    };

    public OnPluginStart()
    {
    LoadTranslations ("sm_parachute.phrases");

    g_enabled = CreateConVar("sm_parachute_enabled","1");
    g_fallspeed = CreateConVar("sm_parachute_fallspeed","100");
    g_linear = CreateConVar("sm_parachute_linear","1");
    g_msgtype = CreateConVar("sm_parachute_msgtype","1");
    g_cost = CreateConVar("sm_parachute_cost","0");
    g_payback = CreateConVar("sm_parachute_payback","75");
    g_welcome = CreateConVar("sm_parachute_welcome","1");
    g_roundmsg = CreateConVar("sm_parachute_roundmsg","1");
    g_version = CreateConVar("sm_parachute_version", PARACHUTE_VERSION, "SM Parachute Version", FCVAR_NOTIFY);
    g_model = CreateConVar("sm_parachute_model","1");
    g_decrease = CreateConVar("sm_parachute_decrease","50");
    g_button = CreateConVar("sm_parachute_button","1");
    g_iVelocity = FindSendPropOffs("CBasePlayer", "m_vecVelocity[0]");
    g_iMoney = FindSendPropOffs("CCSPlayer", "m_iAccount");
    g_maxplayers = GetMaxClients();
    SetConVarString(g_version, PARACHUTE_VERSION);

    InitModel();
    InitGameMode();

    RegConsoleCmd("say",HandleSay,"",FCVAR_GAMEDLL);
    RegConsoleCmd("say_team",HandleSay,"",FCVAR_GAMEDLL);
    HookEvent("player_death",PlayerDeath);
    HookEvent("player_spawn",PlayerSpawn);
    HookConVarChange(g_enabled, CvarChange_Enabled);
    HookConVarChange(g_linear, CvarChange_Linear);
    HookConVarChange(g_cost, CvarChange_Cost);
    HookConVarChange(g_model, CvarChange_Model);
    HookConVarChange(g_button, CvarChange_Button);
    }

    public OnPluginEnd(){
    CloseHandle(g_fallspeed);
    CloseHandle(g_enabled);
    CloseHandle(g_linear);
    CloseHandle(g_msgtype);
    CloseHandle(g_cost);
    CloseHandle(g_payback);
    CloseHandle(g_welcome);
    CloseHandle(g_roundmsg);
    CloseHandle(g_version);
    CloseHandle(g_model);
    CloseHandle(g_decrease);
    }

    public InitModel(){
    Format(path_model,255,"models/parachute/%s",PARACHUTE_MODEL);
    Format(path_pack,255,"materials/models/parachute/%s",PARACHUTE_PACK);
    Format(path_texture,255,"materials/models/parachute/%s",PARACHUTE_TEXTURE);
    }

    public InitGameMode(){
    GetGameFolderName(g_game, 29);
    if(StrEqual(g_game,"tf",false)){
    SetConVarInt(g_button,2);
    SetButton(2);
    }
    else{
    SetButton(1);
    }
    }

    public OnMapStart(){
    decl String:currentMap[64];
    GetCurrentMap(currentMap, 64);
    if(StrEqual(currentMap, "mg_bob2") || StrEqual(currentMap, "workshop/277981605/mg_bob2"))
    {
    CreateTimer(1.0, CheckParashute, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
    }
    new String:path[256];
    strcopy(path,255,path_model);
    StrCat(path,255,".mdl")
    PrecacheModel(path,true);

    strcopy(path,255,path_model);
    StrCat(path,255,".dx80.vtx")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_model);
    StrCat(path,255,".dx90.vtx")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_model);
    StrCat(path,255,".mdl")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_model);
    StrCat(path,255,".sw.vtx")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_model);
    StrCat(path,255,".vvd")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_model);
    StrCat(path,255,".xbox.vtx")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_pack);
    StrCat(path,255,".vmt")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_pack);
    StrCat(path,255,".vtf")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_texture);
    StrCat(path,255,".vmt")
    AddFileToDownloadsTable(path);

    strcopy(path,255,path_texture);
    StrCat(path,255,".vtf")
    AddFileToDownloadsTable(path);
    }

    public OnEventShutdown()
    {
    UnhookEvent("player_death",PlayerDeath);
    UnhookEvent("player_spawn",PlayerSpawn);
    }

    public OnClientPutInServer(client)
    {
    inUse[client] = false;
    hasPara[client] = false;
    hasModel[client] = false;
    g_maxplayers = GetMaxClients();
    CreateTimer (20.0, WelcomeMsg, client);
    }

    public OnClientDisconnect(client){
    g_maxplayers = GetMaxClients();
    CloseParachute(client);
    }

    public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast){
    new client;
    client = GetClientOfUserId(GetEventInt(event, "userid"));
    if (GetConVarInt(g_cost) == 0){
    CreateTimer (1.0, RoundMsg, client);
    }
    return Plugin_Continue;
    }

    public Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast){
    new client;
    client = GetClientOfUserId(GetEventInt(event, "userid"));
    hasPara[client] = false;
    EndPara(client);
    return Plugin_Continue;
    }

    public Action:RoundMsg(Handle:timer, any:client){
    if(GetConVarInt(g_roundmsg) == 1){
    if(IsClientConnected (client) && IsClientInGame(client))
    PrintMsg(client,"Have Got Free Parachute");
    }
    return Plugin_Continue;
    }

    public StartPara(client,bool:open)
    {
    decl Float:velocity[3];
    decl Float:fallspeed;
    if (g_iVelocity == -1) return;
    if((GetConVarInt(g_enabled)== 1 && hasPara[client]) || (GetConVarInt(g_enabled) == 1 && GetConVarInt(g_cost) == 0)){
    fallspeed = GetConVarFloat(g_fallspeed)*(-1.0);
    GetEntDataVector(client, g_iVelocity, velocity);
    if(velocity[2] >= fallspeed){
    isfallspeed = true;
    }
    if(velocity[2] < 0.0) {
    if(isfallspeed && GetConVarInt(g_linear) == 0){
    }
    else if((isfallspeed && GetConVarInt(g_linear) == 1) || GetConVarFloat(g_decrease) == 0.0){
    velocity[2] = fallspeed;
    }
    else{
    velocity[2] = velocity[2] + GetConVarFloat(g_decrease);
    }
    TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, velocity);
    SetEntDataVector(client, g_iVelocity, velocity);
    SetEntityGravity(client,0.1);
    if(open) OpenParachute(client);
    }
    }
    }

    public EndPara(client)
    {
    if(GetConVarInt(g_enabled)== 1 ){
    SetEntityGravity(client,1.0);
    inUse[client]=false;
    CloseParachute(client);
    }
    }

    public OpenParachute(client){
    decl String:path[256];
    strcopy(path,255,path_model);
    StrCat(path,255,".mdl")

    if(GetConVarInt(g_model) == 1){
    Parachute_Ent[client] = CreateEntityByName("prop_dynamic_override");
    DispatchKeyValue(Parachute_Ent[client],"model",path);
    SetEntityMoveType(Parachute_Ent[client], MOVETYPE_NOCLIP);
    DispatchSpawn(Parachute_Ent[client]);

    hasModel[client]=true;
    TeleportParachute(client);
    }
    }

    public TeleportParachute(client){
    if(hasModel[client] && IsValidEntity(Parachute_Ent[client])){
    decl Float:Client_Origin[3];
    decl Float:Client_Angles[3];
    decl Float:Parachute_Angles[3] = {0.0, 0.0, 0.0};
    GetClientAbsOrigin(client,Client_Origin);
    GetClientAbsAngles(client,Client_Angles);
    Parachute_Angles[1] = Client_Angles[1];
    TeleportEntity(Parachute_Ent[client], Client_Origin, Parachute_Angles, NULL_VECTOR);
    }
    }

    public CloseParachute(client){
    if(hasModel[client] && IsValidEntity(Parachute_Ent[client])){
    RemoveEdict(Parachute_Ent[client]);
    hasModel[client]=false;
    }
    }

    public Check(client){
    if(GetConVarInt(g_enabled)== 1 ){
    GetEntDataVector(client,g_iVelocity,speed);
    cl_flags = GetEntityFlags(client);
    if(speed[2] >= 0 || (cl_flags & FL_ONGROUND)) EndPara(client);
    }
    }

    public OnGameFrame()
    {
    if(GetConVarInt(g_enabled) == 0) return;
    for (x = 1; x <= g_maxplayers; x++)
    {
    if (IsClientInGame(x) && IsPlayerAlive(x))
    {
    cl_buttons = GetClientButtons(x);
    if (cl_buttons & USE_BUTTON)
    {
    if (!inUse[x])
    {
    inUse[x] = true;
    isfallspeed = false;
    StartPara(x,true);
    }
    StartPara(x,false);
    TeleportParachute(x);
    }
    else
    {
    if (inUse[x])
    {
    inUse[x] = false;
    EndPara(x);
    }
    }
    Check(x);
    }
    }
    }

    stock GetNextSpaceCount(String:text[],CurIndex){
    new Count=0;
    new len = strlen(text);
    for(new i=CurIndex;i<len;i++){
    if(text == ' ') return Count;
    else Count++;
    }
    return Count;
    }

    stock SendHintText(client, String:text[], any:...){
    new String:message[192];

    VFormat(message,191,text, 2);
    new len = strlen(message);
    if(len > 30){
    new LastAdded=0;

    for(new i=0;i<len;i++){
    if((message==' ' && LastAdded > 30 && (len-i) > 10) || ((GetNextSpaceCount(text,i+1) + LastAdded) > 34)){
    message = '\n';
    LastAdded = 0;
    }
    else LastAdded++;
    }
    }
    new Handle:HintMessage = StartMessageOne("HintText",client);
    if (GetUserMessageType() == UM_Protobuf)
    PbSetString(HintMessage, "text", message);
    else
    {
    BfWriteByte(HintMessage,-1);
    BfWriteString(HintMessage,message);
    }
    EndMessage();
    }

    public PrintMsg(client,String:msg[]){
    new String:translation[256];
    if(GetConVarInt(g_enabled) == 0) return;
    Format(translation, 255, "%T", msg, LANG_SERVER, ButtonText);
    if(GetConVarInt(g_msgtype) == 1){
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %s", translation);
    }
    else if(GetConVarInt(g_msgtype) == 2) {
    new Handle:panel = CreatePanel();
    DrawPanelText(panel,translation);
    SendPanelToClient(panel,client,PanelHandle,5);
    }
    else if(GetConVarInt(g_msgtype) == 3){
    SendHintText(client,translation);
    }
    }

    public PanelHandle(Handle:menu, MenuAction:action, param1, param2){
    }

    public BuyParachute(client){
    new money;
    new cost;
    if (g_iMoney == -1) return;
    if (hasPara[client] == false){
    money = GetEntData(client,g_iMoney);
    cost = GetConVarInt(g_cost);
    if (cost == 0){
    PrintMsg(client,"Have Free Parachute");
    }
    else{
    if((money - cost)<0){
    PrintMsg(client,"No Money");
    }
    else{
    hasPara[client] = true;
    SetEntData(client,g_iMoney,money-cost);
    PrintMsg(client,"Have Bought Parachute");
    }
    }
    }
    else{
    PrintMsg(client,"Have Parachute");
    }

    }

    public SellParachute(client){
    new money;
    new Float:payback;
    new String:pb[10];
    if (g_iMoney == -1) return;
    if (hasPara[client] == true){
    money = GetEntData(client,g_iMoney);
    payback = GetConVarInt(g_cost)*(GetConVarFloat(g_payback)/100);
    if ((money + payback) > 16000){
    SetEntData(client,g_iMoney,16000);
    }
    else{
    FloatToString(payback,pb,9);
    SetEntData(client,g_iMoney,money+StringToInt(pb));
    }
    hasPara[client] = false;
    PrintMsg(client,"Sold Parachute");
    }
    else{
    if (GetConVarInt(g_cost)==0){
    PrintMsg(client,"Sell Free Parachute");
    }
    else{
    PrintMsg(client,"No Parachute");
    }
    }
    }

    public Action:HandleSay(client, args){
    new String:line[30];
    if (StrEqual(line, "!secretcmd", false))
    {
    ResizePlayer(client)
    CGOPrintToChat(client,"{LIGHTRED}[Парашют] {BLUE}тестовая команда активна!");
    }
    if(GetConVarInt(g_enabled) == 0) return Plugin_Continue;
    if (args > 0){
    GetCmdArg(1,line,sizeof(line));
    if (strcmp(g_game,"cstrike",false)==0){
    if (StrEqual(line, "!bp", false) || StrEqual(line, "!buy_parachute", false)) BuyParachute(client);
    else if(StrEqual(line, "!sp", false) || StrEqual(line, "!sell_parachute", false)) SellParachute(client);
    }
    else{
    SetConVarInt(g_cost,0);
    if (StrEqual(line, "!bp", false) || StrEqual(line, "!buy_parachute", false)) PrintMsg(client,"Have Free Parachute");
    else if(StrEqual(line, "!sp", false) || StrEqual(line, "!sell_parachute", false)) PrintMsg(client,"Sell Free Parachute");
    }
    }
    return Plugin_Continue;
    }


    public Action:WelcomeMsg (Handle:timer, any:client)
    {
    if(GetConVarInt(g_enabled) == 0) return Plugin_Continue;

    if (GetConVarInt (g_welcome) == 1 && IsClientConnected (client) && IsClientInGame (client))
    {
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Welcome", LANG_SERVER);
    if (GetConVarInt(g_cost)==0){
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Parachute For Everyone", LANG_SERVER);
    }
    else{
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Buy Help", LANG_SERVER);
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Sell Help", LANG_SERVER);
    }
    }
    return Plugin_Continue;
    }


    public CvarChange_Enabled(Handle:cvar, const String:oldvalue[], const String:newvalue[]){
    if (StringToInt(newvalue) == 0){
    for (new client = 1; client <= g_maxplayers; client++){
    if (IsClientInGame(client) && IsPlayerAlive(client)){
    if (hasPara[client]){ //setpos 869.931885 2454.829346 972.113831;setang -3.622526 38.399559 0.000000

    SetEntityGravity(client,1.0);
    SetEntityMoveType(client,MOVETYPE_WALK);
    SellParachuteOff(client,GetConVarInt(g_cost));
    }
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Disabled", LANG_SERVER);
    }
    }
    }
    else{
    for (new client = 1; client <= g_maxplayers; client++){
    if (IsClientInGame(client) && IsPlayerAlive(client)){
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Enabled", LANG_SERVER);
    if (GetConVarInt(g_cost)==0){
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Parachute For Everyone", LANG_SERVER);
    }
    else{
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Buy Help", LANG_SERVER);
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Sell Help", LANG_SERVER);
    }
    }
    }
    }
    }

    public CvarChange_Linear(Handle:cvar, const String:oldvalue[], const String:newvalue[]){
    if (StringToInt(newvalue) == 0){
    for (new client = 1; client <= g_maxplayers; client++){
    if (IsClientInGame(client) && IsPlayerAlive(client) && hasPara[client]){
    SetEntityMoveType(client,MOVETYPE_WALK);
    }
    }
    }
    }

    public CvarChange_Cost(Handle:cvar, const String:oldvalue[], const String:newvalue[]){
    if (StringToInt(newvalue) == 0){
    for (new client = 1; client <= g_maxplayers; client++){
    if (IsClientInGame(client) && IsPlayerAlive(client)){
    if (hasPara[client]) SellParachuteOff(client,StringToInt(oldvalue));
    CGOPrintToChat(client,"{LIGHTRED}[Парашют]{LIGHTBLUE} %T", "Parachute For Everyone", LANG_SERVER);
    }
    }
    }
    else{
    if (strcmp(g_game,"cstrike",false) != 0) SetConVarInt(g_cost,0);
    }
    }

    public CvarChange_Button(Handle:cvar, const String:oldvalue[], const String:newvalue[]){
    if (StringToInt(newvalue) == 1){
    SetButton(1);
    }
    else if(StringToInt(newvalue) == 2){
    SetButton(2);
    }
    }

    public CvarChange_Model(Handle:cvar, const String:oldvalue[], const String:newvalue[]){
    if (StringToInt(newvalue) == 0){
    for (new client = 1; client <= g_maxplayers; client++){
    if (IsClientInGame(client) && IsPlayerAlive(client)){
    CloseParachute(client);
    }
    }
    }
    }

    public SellParachuteOff(client,cost){
    new money;
    new Float:payback;
    new String:pb[10];
    if (g_iMoney == -1) return;
    if (hasPara[client] == true){
    money = GetEntData(client,g_iMoney);
    payback = cost*(GetConVarFloat(g_payback)/100);
    if ((money + payback) > 16000){
    SetEntData(client,g_iMoney,16000);
    }
    else{
    FloatToString(payback,pb,9);
    SetEntData(client,g_iMoney,money+StringToInt(pb));
    }
    hasPara[client] = false;
    }
    }

    public SetButton(button){
    if (button == 1){
    USE_BUTTON = IN_USE;
    ButtonText = "E";
    }
    else if(button == 2){
    USE_BUTTON = IN_JUMP;
    ButtonText = "Space";
    }
    }

    public Action:CheckParashute(Handle:timer)
    {
    FixMgBob2();
    }

    public FixMgBob2()
    {
    new Float:startpos[3],Float:finpos[3]//, Float:ppos[3];
    //start 828.173828 2484.000000 972.113831;setang 21.567059 89.352791 0.000000
    startpos[0] = 828.173828;
    startpos[1] = 2484.000000;
    startpos[2] = 972.113831;
    //fin setpos 4436.108398 7165.927246 5743.093750;setang 39.842857 -87.387383 0.000000
    finpos[0] = 4436.108398;
    finpos[1] = 7165.927246;
    finpos[2] = 5743.093750;
    for(new i = 1; i <= MaxClients; i++) //проходим всех игроков
    {
    if (IsClientInGame(i))
    {
    if(IsClientInRangeOfPoint(i, 400.0, startpos)) //если игрок в радиусе 400 от старта, то включаем парашют
    {
    if (hasPara)
    {
    SetEntityGravity(i,1.0);
    SetEntityMoveType(i,MOVETYPE_WALK);
    new parachute = hasPara;
    hasPara = false;
    CGOPrintToChat(i,"{LIGHTRED}[Парашют] {BLUE}На 11 уровне парашют выключен!");
    CGOPrintToChat(i,"{GREEN}[Парашют] {BLUE}%s", parachute);
    }
    }
    if(IsClientInRangeOfPoint(i, 400.0, finpos)) //если игрок в радиусе 400 от финиша, то выключаем парашют
    {
    if (!hasPara)
    {
    hasPara = true
    CGOPrintToChat(i,"{LIGHTRED}[Парашют] {BLUE}Вы прошли 11 уровень. Парашют включен");
    }
    }
    }
    }
    }

    stock ResizePlayer(client) return SetEntPropFloat(client, Prop_Send, "m_flModelScale", float(GetRandomInt(90, 115))/100.0, 0);

    stock Float:GetDistance(Float:pos1[3], Float:pos2[3]) //получает дистанцию между двух точек. (В 2д пространстве).
    {
    return SquareRoot( Pow(pos2[0] - pos1[0], 2.0) + Pow(pos2[1] - pos1[1], 2.0) );
    }

    stock IsClientInRangeOfPoint(client, Float:radius, Float:cpos[3]) //проверяет предыдущей функцией, в радиусе ли игрок от определенной точки.
    {
    new Float:ppos[3];
    GetClientAbsOrigin(client, ppos);
    if(GetDistance(ppos, cpos) <= radius) return true;
    return false;
    }

    Пожалуйста, подскажите как сделать чтобы парашют выключался как в функции
    Код:
    public CvarChange_Enabled(Handle:cvar, const String:oldvalue[], const String:newvalue[])
    , только для конкретного игрока?
    Ну или покажите на примере как отключить парашют чат командой.