OnPlayerText
#1

Здравствуйте,хотел бы узнать правильно ли написал код? можете подправить если требуется?

плюс в конце return true; выдает варнинг

PHP код:
public OnPlayerText(playeridtext[])
{             
    if(
PlayerLogin[playerid] == false) return true;
    {
                new 
string[128];
        if(
GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && !PlayerCuffed{playerid})
        {
            if(
IsAGang(playerid))
            {
                switch(
random(7))
                {
                    case 
0ApplyAnimation(playerid,"GHANDS","gsign2",4.0,0,1,1,1,1,1);
                    case 
1ApplyAnimation(playerid,"GHANDS","gsign4LH",4.0,0,1,1,1,1,1);
                    case 
2ApplyAnimation(playerid,"GHANDS","gsign3LH",4.0,0,1,1,1,1,1);
                    case 
3ApplyAnimation(playerid,"GHANDS","gsign4",4.0,0,1,1,1,1,1);
                    case 
4ApplyAnimation(playerid,"GHANDS","gsign2LH",4.0,0,1,1,1,1,1);
                    case 
5ApplyAnimation(playerid,"GHANDS","gsign5",4.0,0,1,1,1,1,1);
                    case 
6ApplyAnimation(playerid,"GHANDS","gsign5LH",4.0,0,1,1,1,1,1);
                }
            }
            else 
ApplyAnimation(playerid,"PED","IDLE_CHAT",4.0,0,1,1,1,1,1);
            
SetTimerEx("ClearAnim",2000,false,"i",playerid);
        }
        foreach(new 
iPlayer)
        {
            new 
Float:rdist,c;
            
rdist GetPlayerDistanceToPlayer(playerid,i);
            if (
rdist 14.0 || GetPlayerVirtualWorld(playerid) != GetPlayerVirtualWorld(i)) continue;
            switch(
floatround(rdist))
            {
                case 
0..40xFFFFFFFF;
                case 
5..80xCCCCCCFF;
                case 
9..140xAAAAAAFF;
                default: 
0x888888FF;
            }
            if(
FormaFrac[playerid] == 0)
            {
                
format(string,sizeof(string),"- %s (%s)[%d]",text,PlayerInfo[playerid][pNamePlayer],playerid);
            }
            else
            {
                
format(string,sizeof(string),"- %s {%s}(%s)[%d]",text,GetFractionColor[PlayerInfo[playerid][pMember]],PlayerInfo[playerid][pNamePlayer],playerid);
            }
            
SendClientMessage(i,c,string);
        }
        
SetPlayerChatBubble(playeridtextCOLOR_WHITE20.010000);
        return 
false;
    }
    return 
true;

Reply
#2

Код вроде бы ничего, но навскидку сказать не просто сразу.
Quote:

плюс в конце return true; выдает варнинг

Какой варнинг? Нужно же кидать код варнинга. Может из-за true/false, которые следует заменить просто на 1/0.
Reply
#3

Это не правильно:
Код:
if(PlayerLogin[playerid] == false) return true; 
{
// Код...
}
Нужно так:
Код:
if(PlayerLogin[playerid] == false) return true;
// Код...
или так:
Код:
if(PlayerLogin[playerid] == true)
{
// Код
}
Reply
#4

Quote:
Originally Posted by Kolstin
Посмотреть сообщение
Код:
if(PlayerLogin[playerid] == true)
{
// Код
}
Варнинг ушел,спасибо. есть еще варианты для оптимизации ?
Reply
#5

А сам то как считаешь? У тебя:
1) объявления в циклах.
2) ты обращаешься к функции взятия виртуального мира одного и того же игрока столько же раз, сколько и игроков на сервере.
3) расстояние между игроками у тебя то через float... функции сравнивается, то преобразовывается до целочисленного (не думал сразу возвращать целочисленный рез-тат, чтобы исключить floatcmp?
4) Не думал, что в форматах у тебя выполняется лишняя работа по генерации одного и того же текста ровно ( количество игроков онлайн -1) раз?
5) зачем тебе "default: c = 0x888888FF;" - у тебя по rdist уже стоит ограничение исключающее этот случай.

Мне тут делать особо нечего, поэтому напишу на свой лад:
PHP код:
public OnPlayerText(playeridtext[])
{             
    if(
PlayerLogin[playerid] == true)
    {
        if(
GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && !PlayerCuffed{playerid})
        {
            if(
IsAGang(playerid))
            {
                switch(
random(7))
                {
                    case 
0ApplyAnimation(playerid,"GHANDS","gsign2",4.0,0,1,1,1,1,1);
                    case 
1ApplyAnimation(playerid,"GHANDS","gsign4LH",4.0,0,1,1,1,1,1);
                    case 
2ApplyAnimation(playerid,"GHANDS","gsign3LH",4.0,0,1,1,1,1,1);
                    case 
3ApplyAnimation(playerid,"GHANDS","gsign4",4.0,0,1,1,1,1,1);
                    case 
4ApplyAnimation(playerid,"GHANDS","gsign2LH",4.0,0,1,1,1,1,1);
                    case 
5ApplyAnimation(playerid,"GHANDS","gsign5",4.0,0,1,1,1,1,1);
                    case 
6ApplyAnimation(playerid,"GHANDS","gsign5LH",4.0,0,1,1,1,1,1);
                }
            }
            else 
ApplyAnimation(playerid,"PED","IDLE_CHAT",4.0,0,1,1,1,1,1);
            
SetTimerEx("ClearAnim",2000,false,"i",playerid);
        }
        new 
string[144], rdistcmyWorld GetPlayerVirtualWorld(playerid);// 144 - смотри предел клиента на вывод в чат строки.
        
if(FormaFrac[playerid] == 0) {
            
format(string,sizeof(string),"- %s (%s)[%d]",text,PlayerInfo[playerid][pNamePlayer],playerid);
        } else {
            
format(string,sizeof(string),"- %s {%s}(%s)[%d]",text,GetFractionColor[PlayerInfo[playerid][pMember]],PlayerInfo[playerid][pNamePlayer],playerid);
        }
        foreach(new 
iPlayer) {
            if (
myWorld  != GetPlayerVirtualWorld(i)) continue;// не нужно считать расстояние, если в другом мире
            
rdist floatround(GetPlayerDistanceToPlayer(playerid,i));
            if (
rdist 14.0) continue;//
            
            
if(rdist 80xAAAAAAFF;
            else if(
rdist 40xCCCCCCFF;
            else 
0xFFFFFFFF;            
            
SendClientMessage(i,c,string);
        }
        
SetPlayerChatBubble(playeridtextCOLOR_WHITE20.010000);
        return 
false;
    }
    return 
true;

Reply
#6

Quote:
Originally Posted by Mutha_X
Посмотреть сообщение
А сам то как считаешь? У тебя:
1) объявления в циклах.
2) ты обращаешься к функции взятия виртуального мира одного и того же игрока столько же раз, сколько и игроков на сервере.
3) расстояние между игроками у тебя то через float... функции сравнивается, то преобразовывается до целочисленного (не думал сразу возвращать целочисленный рез-тат, чтобы исключить floatcmp?
4) Не думал, что в форматах у тебя выполняется лишняя работа по генерации одного и того же текста ровно ( количество игроков онлайн -1) раз?
5) зачем тебе "default: c = 0x888888FF;" - у тебя по rdist уже стоит ограничение исключающее этот случай.
Спасибо за советы
Reply
#7

pawn Код:
public OnPlayerText(playerid, text[])
{
    if(!PlayerLogin[playerid]) return 0;
    if(GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && !PlayerCuffed{playerid})
    {
        if(!IsAGang(playerid)) ApplyAnimation(playerid, "PED", "IDLE_CHAT", 4.0, 0, 1, 1, 1, 1, 1);
        else
        {
            new gsign[7][9] = {"gsign2", "gsign4LH", "gsign3LH", "gsign4", "gsign2LH", "gsign5", "gsign5LH"};
            ApplyAnimation(playerid, "GHANDS", gsign[random(7)], 4.0, 0, 1, 1, 1, 1, 1);
        }
        SetTimerEx("ClearAnim", 2000, 0, "i", playerid);
    }
    new string[144], rdist, c = 0xFFFFFFFF, myWorld = GetPlayerVirtualWorld(playerid);
    if(!FormaFrac[playerid]) format(string, sizeof(string), "- %s (%s)[%d]", text, PlayerInfo[playerid][pNamePlayer], playerid);
    else format(string, sizeof(string), "- %s {%s}(%s)[%d]", text, GetFractionColor[PlayerInfo[playerid][pMember]], PlayerInfo[playerid][pNamePlayer], playerid);
    foreach(new i: Player)
    {
        if(myWorld  != GetPlayerVirtualWorld(i)) continue;
        rdist = floatround(GetPlayerDistanceToPlayer(playerid, i));
        if(rdist > 14.0) continue;
        if(rdist > 8.0) c = 0xAAAAAAFF;
        else if(rdist > 4.0) c = 0xCCCCCCFF;
        SendClientMessage(i, c, string);
    }
    SetPlayerChatBubble(playerid, text, COLOR_WHITE, 20.0, 10000);
    return 0;
}
Reply
#8

Для отправки сообщения ближайшим игрокам предлагаю воспользоваться моей версией функции ProxDetector, которая довольно эффективно выполняет свою функцию высчитывая цвет автоматически в зависимости от расстояния.

PHP код:
stock ProxDetector(playeridFloat:max_rangecolorstring[], Float:max_ratio 1.6)
{
    new
        
Float:pos_x,
        
Float:pos_y,
        
Float:pos_z,
        
Float:range,
        
Float:range_ratio,
        
Float:range_with_ratio,
        
clr_rclr_gclr_b,
        
Float:color_rFloat:color_gFloat:color_b;
    if (!
GetPlayerPos(playeridpos_xpos_ypos_z)) {
        return 
0;
    }
    
color_r float(color >> 24 0xFF);
    
color_g float(color >> 16 0xFF);
    
color_b float(color >> 0xFF);
    
range_with_ratio max_range max_ratio;
#if defined foreach
    
foreach (new Player) {
#else
    
for (new GetPlayerPoolSize(); != -1i--) {
#endif
        
if (!IsPlayerStreamedIn(iplayerid)) {
            continue;
        }
        
range GetPlayerDistanceFromPoint(ipos_xpos_ypos_z);
        if (
range max_range) {
            continue;
        }
        
range_ratio = (range_with_ratio range) / range_with_ratio;
        
clr_r floatround(range_ratio color_r);
        
clr_g floatround(range_ratio color_g);
        
clr_b floatround(range_ratio color_b);
        
SendClientMessage(i, (color 0xFF) | (clr_b << 8) | (clr_g << 16) | (clr_r << 24), string);
    }
    
SendClientMessage(playeridcolorstring);
    return 
1;

Reply
#9

На PI Thule написал ещё так:
pawn Код:
SendClientMessage(playerid, floatround(4294967295 - 89829376*(dist/(range/6))), text);
Кстати, сделай замер скорости с:
pawn Код:
stock ProxDetector_OK(Float:radius = 30.0, playerid, text[], col1 = 0xFFFFFFFF, col2 = 0xCCCCCCFF, col3 = 0x999999FF, col4 = 0x666666FF, col5 = 0x333333FF)
{
//  SetPlayerChatBubble(playerid, text, col1, radius, 5 * 1000);
    new Float:x, Float:y, Float:z;
    GetPlayerPos(playerid, x, y, z);
    for(new i = GetPlayerPoolSize(), Float:dist, virtualworld = GetPlayerVirtualWorld(playerid), interior = GetPlayerInterior(playerid); i != -1; i--)
    {
        if(!IsPlayerConnected(i) || IsPlayerNPC(i) || virtualworld != GetPlayerVirtualWorld(i) || interior != GetPlayerInterior(i)) continue;
        dist = GetPlayerDistanceFromPoint(i, x, y, z);
        if(dist < radius / 16) SendClientMessage(i, col1, text);
        else if(dist < radius / 8) SendClientMessage(i, col2, text);
        else if(dist < radius / 4) SendClientMessage(i, col3, text);
        else if(dist < radius / 2) SendClientMessage(i, col4, text);
        else if(dist < radius) SendClientMessage(i, col5, text);
    }
    return 1;
}
Reply
#10

Раз уж тема зашла о замерах...
Quote:
Originally Posted by OKStyle
Посмотреть сообщение
[pawn]
Кстати, сделай замер скорости с:
pawn Код:
if(dist < radius / 16) SendClientMessage(i, col1, text);
else if(dist < radius / 8) SendClientMessage(i, col2, text);
else if(dist < radius / 4) SendClientMessage(i, col3, text);
else if(dist < radius / 2) SendClientMessage(i, col4, text);
else if(dist < radius) SendClientMessage(i, col5, text);
Повторяющиеся вычисления лучше вынести за цикл (заранее вычислить радиусы).

Quote:
Originally Posted by ZiGGi
Посмотреть сообщение
PHP код:
IsPlayerStreamedIn(playeridi
А если твоя реализация функции будет использоваться на больших расстояниях?
Плюс её (IsPlayerStreamedIn) аргументы следует поменять местами: справедливо ли утверждение о том, что если у первого игрока застримен второй, у второго первый игрок будет всегда взаимно застримен?
Об этом кстати говорится на вики: https://sampwiki.blast.hk/wiki/IsPlayerStreamedIn что может произойти, что игроку i игрок playerid не будет подгружен, хотя обратное - верно.
Reply
#11

Радиус заранее известен, а дистанцию всё равно получать для каждого игрока.
Reply
#12

Quote:
Originally Posted by OKStyle
View Post
Радиус заранее известен, а дистанцию всё равно получать для каждого игрока.
Так, ты чё? С компилятором спорить собрался?
Особенно при этом забыв о <float> функциях.
Reply
#13

Quote:
Originally Posted by Mutha_X
View Post
А если твоя реализация функции будет использоваться на больших расстояниях?
Для этого функция не предназначена, кому надо - переделают.

Quote:
Originally Posted by Mutha_X
View Post
Плюс её (IsPlayerStreamedIn) аргументы следует поменять местами: справедливо ли утверждение о том, что если у первого игрока застримен второй, у второго первый игрок будет всегда взаимно застримен?
Думаю да, но аргументы поменять стоит, согласен.

Quote:
Originally Posted by Mutha_X
View Post
Об этом кстати говорится на вики: https://sampwiki.blast.hk/wiki/IsPlayerStreamedIn что может произойти, что игроку i игрок playerid не будет подгружен, хотя обратное - верно.
Там говорится о другом, а именно о том, что игрок не застримлен для самого себя.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)