XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
Не работают условия и как оптимизировать/исправить
Вот в чем проблема есть 7 областей.
Есть юнит который может войти в каждую из них, при условии, что сейчас ночь.
Но проблема в том, что входя в 1, 2 и 5 области, условия срабатывают, а входя в другие нет!

Код:
function Trig_Mobs_Enter_J_Conditions takes nothing returns boolean
    return IsUnitType(GetEnteringUnit(), UNIT_TYPE_HERO) == true and (GetTimeOfDay() >= 18.00 or GetTimeOfDay() < 6.00)
endfunction

function Trig_Mobs_Enter_J_Actions takes nothing returns nothing
    local unit un=GetEnteringUnit()
    local location pon=GetUnitLoc(un)
    local location pon2
    local real x
    local real y
    
    if RectContainsLoc(gg_rct_Enter_mob_1, pon) == true then
        set x=2224.2
        set y=-850.4
        call UnitAddAbilityBJ( 'A00C', un )
    else
        if RectContainsLoc(gg_rct_Enter_mob_2, pon) == true and GetHeroLevel(un) >=3 then
            set x=2194.7
            set y=-1409.0
            call UnitAddAbilityBJ( 'A00C', un )
        else
            if RectContainsLoc(gg_rct_Enter_mob_3, pon) == true and GetHeroLevel(un) >=5 then
                set x=2151.3
                set y=-2823.4
                call UnitAddAbilityBJ( 'AHtc', un )
            else
                if RectContainsLoc(gg_rct_Enter_mob_4, pon) == true and GetHeroLevel(un) >=30 then
                    set x=3000.3
                    set y=-2823.4
                else
                    if RectContainsLoc(gg_rct_Enter_mob_5, pon) == true and GetHeroLevel(un) >=50 then
                        set x=4000.3
                        set y=-2823.4
                    else
                        if RectContainsLoc(gg_rct_Enter_mob_6, pon) == true and GetHeroLevel(un) >=500 then
                            set x=1000.3
                            set y=-2823.4
                        else
                            if RectContainsLoc(gg_rct_Enter_mob_7, pon) == true and GetHeroLevel(un) >=1000 then
                                set x=2151.3
                                set y=-3000.4
                            else
                            endif
                        endif
                    endif
                endif
            endif
        endif
    endif
    call SetUnitX(un, x)
    call SetUnitY(un, y)
    
    set pon=null
    set pon2=null
    set un=null
endfunction

//===========================================================================
function InitTrig_Mobs_Enter_J takes nothing returns nothing
    set gg_trg_Mobs_Enter_J = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_1 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_2 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_3 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_4 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_5 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_6 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_7 )
    call TriggerAddCondition( gg_trg_Mobs_Enter_J, Condition( function Trig_Mobs_Enter_J_Conditions ) )
    call TriggerAddAction( gg_trg_Mobs_Enter_J, function Trig_Mobs_Enter_J_Actions )
endfunction


И если ваши слова:
Какой ужасный код, тут много утечек, неудивительно...
То прошу укажите на место утечки и ее "замены". Я уже читал пару статей про оптимизацию, но про это там нислова! И да если вы знаете как сделать код лучше напишите.
Насчет того: А ты проверь, где эта область, то отвечу проверил все области на месте и юнитом захожу именно туда... И проверял все области любым уровнем!

Отредактировано Nerevar, 22.07.2012 в 21:13.
Старый 22.07.2012, 20:45
Hate
конь вакуумный
offline
Опыт: 43,117
Активность:
call UnitAddAbilityBJ( 'A00C', un )
ужастно
call UnitAddAbility(un ,  'A00C')
IsUnitType(GetEnteringUnit(), UNIT_TYPE_HERO) == true
сравнивать один боолеан с другим попахивает идиотизмом
IsUnitType(GetEnteringUnit(), UNIT_TYPE_HERO)
not IsUnitType(GetEnteringUnit(), UNIT_TYPE_HERO)
лучше делается так
real r_x = GetLocationX(pon)
real r_y = GetLocationY(pon)
int lvl = GetHeroLevel(un)

if RectContainsCoords(gg_rct_Enter_mob_1,,r_x,r_y) then
        set x=2224.2
        set y=-850.4
        call UnitAddAbility(un, 'A00C')
elseif RectContainsCoords(gg_rct_Enter_mob_2,r_x,r_y) and lvl >=3 then
        set x=2194.7
        set y=-1409.0
        call UnitAddAbility(un, 'A00C')
...
поиск по функциям для слабых да?
з.ы. вообще не используй локации. Они занимают больше места чем 2 переменных которые содержат х и у, локации нужно удалять и обнулять, они медленнее координат, по сути локации нужны лишь для определения высоты рельефа, я лично не знаю больше им применения.
з.ыы. такое ты наврятли читал xgm.ru/forum/showthread.php?t=18742

Отредактировано Hatsume_Hate, 22.07.2012 в 21:27.
Старый 22.07.2012, 21:15
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
Исправив все равно, работают только 1,2 и 5 зоны а остальные вообще в пролете...
Код:
function Trig_Mobs_Enter_J_Conditions takes nothing returns boolean
    return IsUnitType(GetEnteringUnit(), UNIT_TYPE_HERO) and (GetTimeOfDay() >= 18.00 or GetTimeOfDay() < 6.00)
endfunction

function Trig_Mobs_Enter_J_Actions takes nothing returns nothing
    local unit un=GetEnteringUnit()
    local real r_x = GetUnitX(un)
    local real r_y = GetUnitY(un)
    local integer lvl = GetHeroLevel(un)
    call DisplayTextToForce( GetPlayersAll(), "Ща проверю зоны"+GetUnitName(un) )
    
    if RectContainsCoords(gg_rct_Enter_mob_1,r_x,r_y) then
        call SetUnitX(un, 2224.2)
        call SetUnitY(un, -850.4)
        call UnitAddAbility(un, 'A00C')
        call DisplayTextToForce( GetPlayersAll(), GetUnitName(un) )
        set un=null
        return
    else
        if RectContainsCoords(gg_rct_Enter_mob_2,r_x,r_y) and lvl >=3 then
            call SetUnitX(un, 2194.7)
            call SetUnitY(un, -1409.0)
            call UnitAddAbility(un, 'A00C')
            call DisplayTextToForce( GetPlayersAll(), GetUnitName(un) )
            set un=null
            return
        else
            if RectContainsCoords(gg_rct_Enter_mob_3,r_x,r_y) and lvl >=5 then
                call SetUnitX(un, 2151.3)
                call SetUnitY(un, -2823.4)
                call UnitAddAbility(un, 'AHtc')
                call DisplayTextToForce( GetPlayersAll(), GetUnitName(un) )
                set un=null
                return
            else
                if RectContainsCoords(gg_rct_Enter_mob_4,r_x,r_y) and lvl >=30 then
                    call SetUnitX(un, 3000.3)
                    call SetUnitY(un, -2823.4)
                    call DisplayTextToForce( GetPlayersAll(), GetUnitName(un) )
                    set un=null
                    return
                else
                    if RectContainsCoords(gg_rct_Enter_mob_5,r_x,r_y) and lvl >=50 then
                        call SetUnitX(un, 4000.3)
                        call SetUnitY(un, -2823.4)
                        call DisplayTextToForce( GetPlayersAll(), GetUnitName(un) )
                        set un=null
                        return
                    else
                        if RectContainsCoords(gg_rct_Enter_mob_6,r_x,r_y) and lvl >=500 then
                            call SetUnitX(un, 1000.3)
                            call SetUnitY(un, -2823.4)
                            call DisplayTextToForce( GetPlayersAll(), GetUnitName(un) )
                            set un=null
                            return
                        else
                            if RectContainsCoords(gg_rct_Enter_mob_7,r_x,r_y) and lvl >=1000 then
                                call SetUnitX(un, 2151.3)
                                call SetUnitY(un, -3000.4)
                                call DisplayTextToForce( GetPlayersAll(), GetUnitName(un) )
                                set un=null
                                return
                            else
                            endif
                        endif
                    endif
                endif
            endif
        endif
    endif
endfunction

//===========================================================================
function InitTrig_Mobs_Enter_J takes nothing returns nothing
    set gg_trg_Mobs_Enter_J = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_1 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_2 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_3 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_4 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_5 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_6 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_7 )
    call TriggerAddCondition( gg_trg_Mobs_Enter_J, Condition( function Trig_Mobs_Enter_J_Conditions ) )
    call TriggerAddAction( gg_trg_Mobs_Enter_J, function Trig_Mobs_Enter_J_Actions )
endfunction
Старый 22.07.2012, 22:12
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Блин, почему не пользуемся отладочными сообщениями?
Старый 22.07.2012, 22:21
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
Цитата:
Сообщение от Faion
Блин, почему не пользуемся отладочными сообщениями?

Может еще раз взглянуть на последнее сообщение? И я ими пользовался изначально, но стер, чтобы не мешали, людям видеть истинную ошибку.

Насчет сообщений:
В областях 1,2 и 5 писали: UnitName
В других областях ничего не писали, просто считали, что этот юнит НЕ входит в данную область хоть и главное условие срабатывает! (главное, это то что запускает триггер)
Старый 22.07.2012, 22:27
Hate
конь вакуумный
offline
Опыт: 43,117
Активность:
if
elseif
elseif
endif
почему не попробовал?
Старый 22.07.2012, 22:33
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
Одно и тоже ничего не изменилось...
Старый 22.07.2012, 22:37
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Xipxop,
else if и elseif разные вещи. Исправленный код в студию
Faion добавил:
А лучше сделай по такому принципу:
» тык
library TeleportSys initializer Init uses QuestNative
{
    
    private hashtable ht = InitHashtable();    
    private bool array OnTeleport;
    private int rectCount = 0;
    
    
    private float array rectA_min_x;
    private float array rectA_max_x;
    private float array rectA_min_y;
    private float array rectA_max_y;
    private float array rectA_tp_x;
    private float array rectA_tp_y;
    
    private float array rectB_min_x;
    private float array rectB_max_x;
    private float array rectB_min_y;
    private float array rectB_max_y;
    private float array rectB_tp_x;
    private float array rectB_tp_y;
    
    private void Uncheck()
    {
        timer t = GetExpiredTimer();
        int h = GetHandleId(t);
        OnTeleport[LoadInteger(ht,h,0)] = false;
        FlushChildHashtable(ht,h)
        PauseTimer(t)
        DestroyTimer(t)
        t = null;
    }
    
    private void SaveRectCoords(rect r, bool isA)
    {
        if (isA)
        {
            rectA_min_x[rectCount] = GetRectMinX(r) - 100.0
            rectA_max_x[rectCount] = GetRectMaxX(r) + 100.0
            rectA_min_y[rectCount] = GetRectMinY(r) - 100.0
            rectA_max_y[rectCount] = GetRectMaxY(r) + 100.0
        }
        else
        {
            rectB_min_x[rectCount] = GetRectMinX(r) - 100.0
            rectB_max_x[rectCount] = GetRectMaxX(r) + 100.0
            rectB_min_y[rectCount] = GetRectMinY(r) - 100.0
            rectB_max_y[rectCount] = GetRectMaxY(r) + 100.0
        }
    }
    
    private void SaveTpCoords(rect r, bool isA)
    {
        if(isA)
        {
            rectA_tp_x[rectCount] = GetRectCenterX(r);
            rectA_tp_y[rectCount] = GetRectCenterY(r);
        }
        else
        {
            rectB_tp_x[rectCount] = GetRectCenterX(r);
            rectB_tp_y[rectCount] = GetRectCenterY(r);
        }
    }
    
    private int GetRectId(float x, float y, bool isA)
    {
        if (isA)
        {
            for(int i = 0; i < rectCount; i++)
            {
                if((rectA_min_x[i] <= x) && (x <= rectA_max_x[i]) && (rectA_min_y[i] <= y) && (y <= rectA_max_y[i]))
                {
                    return i;
                }
            }
        }
        for(int i = 0; i < rectCount; i++)
        {
            if((rectB_min_x[i] <= x) && (x <= rectB_max_x[i]) && (rectB_min_y[i] <= y) && (y <= rectB_max_y[i]))
            {
                return i;
            }
        }
        return 0;
    }
    
    private void Teleport(bool isA)
    {
        unit u = GetEnteringUnit();
        int pId = GetPlayerId(GetOwningPlayer(u));
        int i = 0;
        float x = 0.0, y = 0.0;
        timer t = null;
        if (pId < 12 && !OnTeleport[pId])
        {
            x = GetUnitX(u); y = GetUnitY(u);
            i = GetRectId(x, y,isA);
            OnTeleport[pId] = true;
            if (isA)
            {
                SetUnitPosition(u,rectA_tp_x[i],rectA_tp_y[i])
                if (GetLocalPlayer() == Player(pId))
                {
                    SetCameraPosition(rectA_tp_x[i],rectA_tp_y[i])
                }
            }
            else
            {
                SetUnitPosition(u,rectB_tp_x[i],rectB_tp_y[i])
                if (GetLocalPlayer() == Player(pId))
                {
                    SetCameraPosition(rectB_tp_x[i],rectB_tp_y[i])
                }
            }
            t = CreateTimer();
            SaveInteger(ht, GetHandleId(t),0, pId);
            TimerStart(t,2.0, false, function Uncheck);
        }
        elseif(pId == 15 && !OnTeleport[pId])
        {
            x = GetUnitX(u); y = GetUnitY(u);
            i = GetRectId(x,y,isA);
            OnTeleport[pId] = true;
            if (isA)
            {
                SetUnitPosition(u,rectA_tp_x[i],rectA_tp_y[i])
            }
            else
            {
                SetUnitPosition(u,rectB_tp_x[i],rectB_tp_y[i])
            }
            
            t = CreateTimer();
            SaveInteger(ht, GetHandleId(t),0, pId);
            TimerStart(t,2.0, false, function Uncheck);
        }
        t = null;
        u = null;
    }
    
    private void TeleportFromAToB()
    {
        Teleport(true);
    }
    
    private void TeleportFromBToA()
    {
        Teleport(false);
    }
    
    void AddTeleport(rect rectA, rect rectB, string rectATitle, string rectBTitle)
    {
        // создаем эвент, цепляем нужное нам условие, и действие
        trigger trig = CreateTrigger();
        region rectRegion = CreateRegion();
        RegionAddRect(rectRegion, rectA);
        TriggerRegisterEnterRegion(trig, rectRegion, null);
        TriggerAddAction(trig, function TeleportFromAToB)
        // для проверки позиции
        SaveRectCoords(rectA,true);
        SaveTpCoords(rectB,true);
        
        trigger trig2 = CreateTrigger();
        region rectRegion2 = CreateRegion();
        RegionAddRect(rectRegion2, rectB);
        TriggerRegisterEnterRegion(trig2, rectRegion2, null);
        TriggerAddAction(trig2, function TeleportFromBToA)
        // для проверки позиции
        SaveRectCoords(rectB,false);
        SaveTpCoords(rectA,false);

        rectCount++;
        trig = null;
        rectRegion = null;
        trig2 = null;
        rectRegion2 = null;
    }
    
    private void Init()
    {
        #if Debug 
            LogAdd("ProtectZoneSystem - Init")
        #endif
        TriggerSleepAction(1.0);
        AddTeleport(gg_rct_Enter5, gg_rct_Leave5, "Пещера", "Окрестности пограничного города")
        
        #if Debug 
            LogAdd("ProtectZoneSystem - EndInit")
        #endif
    }
}
Старый 22.07.2012, 22:54
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
Даже переписав этот код все равно данные области просто НЕ хотят работать!
И даже после того как я их заново пересоздал!
» раскрыть
Код:
function Trig_Mobs_Enter_J_Conditions takes nothing returns boolean
    return IsUnitType(GetEnteringUnit(), UNIT_TYPE_HERO) and (GetTimeOfDay() >= 18.00 or GetTimeOfDay() < 6.00)
endfunction

function Trig_Mobs_Enter_J_Actions takes nothing returns nothing
    local unit un=GetEnteringUnit()
    local real r_x = GetUnitX(un)
    local real r_y = GetUnitY(un)
    local integer lvl = GetHeroLevel(un)
    local integer A=1
    local real array Xa
    local real array Ya
    local integer array magic
    local integer array level
    local rect array area
    
    set Xa[1]=2224.2
    set Xa[2]=2194.7
    set Xa[3]=2151.3
    set Xa[4]=3000.3
    set Xa[5]=4000.0
    set Xa[6]=3000.3
    set Xa[7]=3000.3
    set Ya[1]=-850.4
    set Ya[2]=-1409.0
    set Ya[3]=-2823.4
    set Ya[4]=-2000.4
    set Ya[5]=-2000.4
    set Ya[6]=-2000.4
    set Ya[7]=-2000.4
    set magic[1]='A00C'
    set magic[2]='A00C'
    set magic[3]='AHtc'
    set level[1]=1
    set level[2]=3
    set level[3]=5
    set level[4]=10
    set level[5]=100
    set level[6]=200
    set level[7]=999
    set area[1]=gg_rct_Enter_mob_1
    set area[2]=gg_rct_Enter_mob_2
    set area[3]=gg_rct_Enter_mob_3
    set area[4]=gg_rct_Enter_mob_4
    set area[5]=gg_rct_Enter_mob_5
    set area[6]=gg_rct_Enter_mob_6
    set area[7]=gg_rct_Enter_mob_7
    
    loop
    if RectContainsCoords(area[A],r_x,r_y) and lvl>=level[A] then
        call SetUnitX(un, Xa[A])
        call SetUnitY(un, Ya[A])
        call UnitAddAbility(un, magic[A])
        set un=null
        return
    else
    endif
    set A=A+1
    exitwhen A>6
    endloop
endfunction

//===========================================================================
function InitTrig_Mobs_Enter_J takes nothing returns nothing
    set gg_trg_Mobs_Enter_J = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_1 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_2 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_3 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_4 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_5 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_6 )
    call TriggerRegisterEnterRectSimple( gg_trg_Mobs_Enter_J, gg_rct_Enter_mob_7 )
    call TriggerAddCondition( gg_trg_Mobs_Enter_J, Condition( function Trig_Mobs_Enter_J_Conditions ) )
    call TriggerAddAction( gg_trg_Mobs_Enter_J, function Trig_Mobs_Enter_J_Actions )
endfunction


Xipxop добавил:
И вот еще один факт
Создав новый триггер на GUI с событием входа в область 7, то сразу телепорт перса в центр карты

То войдя в эту зону, то все сработало!

Я незнаю почему, но игра или триггер НЕ хочет признавать, что юнит в области!

Xipxop добавил:
Да и вообще, что лучше сделать:
1) На каждую область по триггеру.
2) Одним триггером, где проверяются в какой области юнит.

Как практичнее?? И как лучше скажется на производительности? И добавлением аш 7 глобальных триггеров, не скажется на памяти?
Старый 22.07.2012, 23:14
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Xipxop:
аш 7 глобальных триггеров
o\ Да хоть тысяча. Вообще пофиг. Эра калькуляторов давно подошла к концу.
Xipxop:
Как практичнее??
Выше пример тебе скинул.
Старый 22.07.2012, 23:20
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
Понять бы что он делает =) ну и как пользоваться...
Да и не слишком ли код массивен, для выполнения данной операции?
Старый 22.07.2012, 23:23
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Там тп из точки А в точку Б и использованием ректов. Большая часть кода для бд. Да и тебе там не все над, я просто взял систему которая имеет то что может помочь ответить на твой вопрос.
Xipxop:
ну и как пользоваться...
AddTeleport(gg_rct_Enter5, gg_rct_Leave5, "Пещера", "Окрестности пограничного города")
Старый 23.07.2012, 01:33
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
Ну, думаю тема закрыта.

Faion, а ваша наработка для "моего" вара не работает...
Старый 23.07.2012, 07:12
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 01:54.