[CSS] Неверно откидывает(геометрия)

Тема в разделе "Программирование / Скриптинг", создана пользователем horr0rjkee, 16 сен 2013.

  1. horr0rjkee

    horr0rjkee

    Сообщения:
    5
    Симпатии:
    0
    Вообщем делал откидывание, при взрыве гранаты.
    PHP:
    #include <sourcemod>
    new VelocityOffset[3],BaseVelocityOffset;
    public 
    OnPluginStart()
    {
        
    HookEvent("hegrenade_detonate"OnBounce);
        
    VelocityOffset[0]=FindSendPropOffs("CBasePlayer","m_vecVelocity[0]");
        
    VelocityOffset[1]=FindSendPropOffs("CBasePlayer","m_vecVelocity[1]");
        
    VelocityOffset[2]=FindSendPropOffs("CBasePlayer","m_vecVelocity[2]");
        
    BaseVelocityOffset=FindSendPropOffs("CBasePlayer","m_vecBaseVelocity");
    }

    public 
    OnBounce(Handle:event, const String:name[], bool:dontBroadcast
    {    
        new 
    Float:finalvec[3], Float:angleFloat:gpos[3], Float:plpos[3];
        
    gpos[0] = GetEventFloat(event"x");
        
    gpos[1] = GetEventFloat(event"y");
        
    gpos[2] = GetEventFloat(event"z");
        for(new 
    1<= MaxClientsi++)
        {
            if(!
    IsClientInGame(i)) continue;
            if(
    IsClientInRangeOfPoint(i400.0gpos))
            {
                
    GetClientAbsOrigin(iplpos);
                
    angle ArcTangent2(gpos[0]-plpos[0], gpos[1]-plpos[1]);
                
    PrintToChat(i"atan2(%0.1f-%0.1f, %0.1f-%0.1f): %f"gpos[0],plpos[0],gpos[1],plpos[1],RadToDeg(angle));
                
    finalvec[0]=GetEntDataFloat(i,VelocityOffset[0]) + Cosine(angle+DegToRad(180.0))*250.0;
                
    finalvec[1]=GetEntDataFloat(i,VelocityOffset[1]) + Sine(angle+DegToRad(180.0))*250.0;
                
    finalvec[2]=GetEntDataFloat(i,VelocityOffset[2]) + 50.0;
                
    SetEntDataVector(i,BaseVelocityOffset,finalvec,true);
            }
        }
        
    }

    stock IsClientInRangeOfPoint(clientFloat:radiusFloat:cpos[3]) //by horr0r
    {
        if(!
    IsClientInGame(client)) return false;
        new 
    Float:ppos[3];
        
    GetClientAbsOrigin(clientppos);
        if(
    GetDistance(pposcpos) <= radius) return true;
        return 
    false;
    }
    stock Float:GetDistance(Float:pos1[3], Float:pos2[3]) //by horr0r
    {
        return 
    SquareRootPow(pos2[0] - pos1[0], 2.0) + Pow(pos2[1] - pos1[1], 2.0) + Pow(pos2[2]-pos1[2], 2.0) );
    }
    .
    Но я не понимаю, почему тут не работает? Вроде все просто.
    1) Получаем позицию игрока и гранаты.
    2) Находим угол для ускорения по векторам. Используя atan2(поз.гранаты - поз.игрока).
    3) К вектору велосити X прибавляем косинус полученного угла.
    4) К вектору велосити Y прибавляем синус полученного угла.
    Основная ошибка в том, что откидывает в неправильный угол, проблема не в atan2(проверял).
    Прошу, помогите. В другой игре, все это работает!
    P.S. Последние две функции (из моего инклюда вырезал, просто лень весь инклюд сюда закидывать):
    IsClientInRangeOfPoint - проверяет, в радиусе ли игрок от определенной точки.
    GetDistance - возвращает дистанцию между двумя точками.
     
    Последнее редактирование: 17 сен 2013
  2. horr0rjkee

    horr0rjkee

    Сообщения:
    5
    Симпатии:
    0
    UP! Помогите пожалуйста!
     
  3. NagarD

    NagarD

    Сообщения:
    412
    Симпатии:
    170
    в зм посмотри.
     
  4. horr0rjkee

    horr0rjkee

    Сообщения:
    5
    Симпатии:
    0
    Каком зм? Этих зм модов очень много.
     
  5. (admiral)

    (admiral)

    Сообщения:
    69
    Симпатии:
    8
    Zombie Reloaded
     
  6. vanbka9

    vanbka9

    Сообщения:
    14
    Симпатии:
    13
    Как-то так...:) взял с ZombieReloaded
    PHP:
    new offsBaseVelocity,
        
    Float:knockback 4.0// сила отброса

    public OnPluginStart()
    {
        
    offsBaseVelocity FindSendPropInfo("CBasePlayer""m_vecBaseVelocity");
        if (
    offsBaseVelocity == -1)
        {
            
    SetFailState("Couldn't find \"m_vecBaseVelocity\"!");
        }
        
    HookEvent("player_hurt"PlayerHurt);
    }

    public 
    Action:PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
    {
        new 
    index GetClientOfUserId(GetEventInt(event"userid"));
        new 
    attacker GetClientOfUserId(GetEventInt(event"attacker"));
        new 
    dmg GetEventInt(event"dmg_health");
        
    decl String:weapon[32];
        
    GetEventString(event"weapon"weaponsizeof(weapon));
        if (
    attacker != 0)
        {
            new 
    Float:clientloc[3];
            
    GetClientAbsOrigin(indexclientloc);
            if (
    StrEqual(weapon"hegrenade"))
            {
                new 
    Float:heLoc[3];
                
    FindExplodingGrenade(heLoc);
                
    KnockBack(indexclientlocheLocknockbackdmgtrue);
            }
        }
    }

    KnockBack(client, const Float:clientloc[3], const Float:attackerloc[3], Float:powerdmgbool:boost)
    {
        new 
    Float:vector[3];
        
    MakeVectorFromPoints(attackerlocclientlocvector);
        
    NormalizeVector(vectorvector);
        
    vector[0] *= power * (float(dmg) * 1.5);
        
    vector[1] *= power * (float(dmg) * 1.5);
        
    vector[2] *= power * (float(dmg) * 1.5);
        if (
    boost)
        {
            for (new 
    03i++)
            {
                if (
    vector[i] > 250.0)
                {
                    
    vector[i] = 250.0;
                }        
                else if (
    vector[i] < -250.0)
                {
                    
    vector[i] = -250.0;
                }
            }
            
    ScaleVector(vector4.0);
        }
        
    SetEntDataVector(clientoffsBaseVelocityvectortrue);
    }

    FindExplodingGrenade(Float:heLoc[3])
    {
        
    decl String:classname[64];
        new 
    maxentities GetMaxEntities();
        for (new 
    GetMaxClients(); <= maxentitiesx++)
        {
            if (
    IsValidEdict(x))
            {
                
    GetEdictClassname(xclassnamesizeof(classname));
                if (
    StrEqual(classname"hegrenade_projectile"))
                {
                    new 
    takedamage GetEntProp(xProp_Data"m_takedamage");
                    if (
    takedamage == 0)
                    {
                        
    GetEntPropVector(xProp_Send"m_vecOrigin"heLoc);
                        return 
    x;
                    }
                }
            }
        }
        return -
    1;
    }
    P.S. Добавил цикл проверки вектора во избежание такой ошибки, если значение больше 1000 => "DataTable warning: (class player): Out-of-range value (-1015.915162) in SendProp Float 'm_vecBaseVelocity', clamping".
     

    Вложения:

    • KnockBack.sp
      Размер файла:
      2 КБ
      Просмотров:
      5
    Последнее редактирование: 21 сен 2013
    horr0rjkee нравится это.
  7. horr0rjkee

    horr0rjkee

    Сообщения:
    5
    Симпатии:
    0
    Эти функции скинь пожалуйста:
    MakeVectorFromPoints,
    NormalizeVector,
    ScaleVector.

    Скорее всего вся соль, в функции "MakeVectorFromPoints". Она угол возвращает. Между двумя позициями. Как и
    PHP:
    ArcTangent2(пИx-пГxпИy-пГy);
    Код:
    пИx - позиция игрока X
    пИy - позиция игрока Y
    пГx - позиция гранаты X
    пГy - позиция гранаты Y
    
     
    Последнее редактирование: 21 сен 2013
  8. vanbka9

    vanbka9

    Сообщения:
    14
    Симпатии:
    13
    Нет. Всё гораздо проще. Всё это есть в API

    MakeVectorFromPoints
    PHP:
    stock MakeVectorFromPoints(const Float:pt1[3], const Float:pt2[3], Float:output[3])
    {
        
    output[0] = pt2[0] - pt1[0];
        
    output[1] = pt2[1] - pt1[1];
        
    output[2] = pt2[2] - pt1[2];
    }
    NormalizeVector ПРИМЕР
    PHP:
    Syntax:
    native Float:NormalizeVector(const Float:vec[3], Float:result[3]);

    Usage:
     
    vec        Vector.
     
    result    Resultant vector.
    Notes:
    Normalizes a vectorThe input array can be the same as the output array.

    Return:
    Vector length.
    ScaleVector
    PHP:
    stock ScaleVector(Float:vec[3], Float:scale)
    {
        
    vec[0] *= scale;
        
    vec[1] *= scale;
        
    vec[2] *= scale;
    }
     
  9. wanted241

    wanted241 Real-Gamer.Ru

    Сообщения:
    783
    Симпатии:
    355
    1. http://docs.sourcemod.net/api/index.php?fastload=show&id=558&
    2. http://docs.sourcemod.net/api/index.php?fastload=show&id=550&
    3. http://docs.sourcemod.net/api/index.php?fastload=show&id=556&