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

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

Ответ
 
tgonta
Pixelated Sora Coder
offline
Опыт: 3,160
Активность:
Помогите фикснуть эту системку...
У меня снова проблема с моей системой.
» Тут код системы.
function SimError takes player ForPlayer, string msg returns nothing
    local sound s = CreateSoundFromLabel("InterfaceError",false,false,false,10,10)
    
    if GetLocalPlayer() == ForPlayer then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(ForPlayer,.52,-1.,2.,"|cffffcc00"+msg+"|r")
        call StartSound(s)
        call KillSoundWhenDone(s)
    endif
    
    set s = null
endfunction

function GetUnitItemSlot takes unit u, integer itemID returns integer
    local integer i = 0
    local item it
    loop
        exitwhen i > 5
        set it = UnitItemInSlot(u,i)
        if GetItemTypeId(it) == itemID then
            return i
        endif
        set it = null
        set i = i + 1
    endloop
    return -1
endfunction

function UnitHasEmptySlot takes unit u returns boolean
    local integer i = 0
    local item it
    loop
        exitwhen i > 5
        set it = UnitItemInSlot(u,i)
        if it == null then
            set it = null
            return true
        endif
        set it = null
        set i = i + 1
    endloop
    return false 
endfunction

function GetUnitItemOfType takes unit u, integer iid returns item
    local integer index = GetUnitItemSlot(u,iid)
    
    if index == -1 then
        return null
    else
        return UnitItemInSlot(u,index)
    endif
endfunction

function CombineItemCharges takes item i1, item i2 returns nothing
    call SetItemCharges(i1,GetItemCharges(i1) + GetItemCharges(i2))
endfunction

function NormToRune takes integer niid returns integer
    local integer i = 0 
    loop
        exitwhen i > udg_TotalItems
        if niid == udg_NormalItem[i] then
            return udg_RuneItem[i]
        endif
        set i = i + 1
    endloop
    return -1
endfunction

function RuneToNorm takes integer riid returns integer
    local integer i = 0 
    loop
        exitwhen i > udg_TotalItems
        if riid == udg_RuneItem[i] then
            return udg_NormalItem[i]
        endif
        set i = i + 1
    endloop
    return -1
endfunction

function GetItemIndex takes integer iid returns integer
    local integer i = 0 
    loop
        exitwhen i > udg_TotalItems
        if iid == udg_RuneItem[i] or iid == udg_NormalItem[i] then
            return i
        endif
        set i = i + 1
    endloop
    return -1
endfunction

function GiveItemToUnit takes item ri, unit u returns boolean
    local integer riid = GetItemTypeId(ri)
    local integer niid = RuneToNorm(riid)
    local item uiis
    if UnitHasEmptySlot(u) then
        call UnitAddItemById(u,niid)
        return true   
    else
        set uiis = GetUnitItemOfType(u,niid)
        if uiis != null and GetItemCharges(uiis) > 0 then
            call CombineItemCharges(uiis,ri)
            set uiis = null
            return true
        endif             
        set uiis = null
    endif
    return false 
endfunction
Триггер, который отвечает за операции с предметами.
function Trig_OperateItems_DropTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local item i = LoadItemHandle(udg_ItemHash,GetHandleId(t),0)
    local integer riid = NormToRune(GetItemTypeId(i))
    local item newi = CreateItem(riid,GetWidgetX(i),GetWidgetY(i))
    
    call SetItemCharges(newi,GetItemCharges(i))
    call RemoveItem(i)
    
    call FlushChildHashtable(udg_ItemHash,GetHandleId(t))
    call DestroyTimer(t)
    set t = null
endfunction

function Trig_OperateItems_Actions takes nothing returns nothing
    local unit u
    local item i
    local timer t
    local integer ittype
    
    if GetTriggerEventId() == EVENT_PLAYER_UNIT_PICKUP_ITEM then
        set u = GetManipulatingUnit()
        set i = GetManipulatedItem()
        set t = CreateTimer()
        set ittype = RuneToNorm(GetItemTypeId(i))
        
        if LoadBoolean(udg_ItemHash,GetHandleId(i),0) == false or LoadBoolean(udg_ItemHash,GetHandleId(i),0) == null then
        
            if GiveItemToUnit(i,u) == false then
                call SimError(GetOwningPlayer(u),"Íåêóäà ïîìåñòèòü ïðåäìåò.")
                call SetPlayerState(GetOwningPlayer(u),PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(GetOwningPlayer(u),PLAYE​R_STATE_RESOURCE_GOLD) + udg_ItemCost[GetItemIndex(GetItemTypeId(i))])
                call SetItemVisible(i,false)
                call SaveItemHandle(udg_ItemHash,GetHandleId(t),0,i)
                call TimerStart(t,.01,false,function Trig_OperateItems_DropTimer)
            endif
            call SaveBoolean(udg_ItemHash,GetHandleId(i),0,true)
        else
            call SaveBoolean(udg_ItemHash,GetHandleId(i),0,false)
        endif
        
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_SELL_ITEM then
        set u = GetBuyingUnit()
        set i = GetSoldItem()
        
        if LoadBoolean(udg_ItemHash,GetHandleId(i),0) == false or LoadBoolean(udg_ItemHash,GetHandleId(i),0) == null then
            if GiveItemToUnit(i,u) == false then
                call SimError(GetOwningPlayer(u),"Íåêóäà ïîìåñòèòü ïðåäìåò.")
                call SetPlayerState(GetOwningPlayer(u),PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(GetOwningPlayer(u),PLAYE​R_STATE_RESOURCE_GOLD) + udg_ItemCost[GetItemIndex(GetItemTypeId(i))])
            endif
            call SaveBoolean(udg_ItemHash,GetHandleId(i),0,true)
        else
            call SaveBoolean(udg_ItemHash,GetHandleId(i),0,false)
        endif
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_DROP_ITEM then
        set u = GetManipulatingUnit()
        set i = GetManipulatedItem()
        set t = CreateTimer()
        set ittype = RuneToNorm(GetItemTypeId(i))
        
        if ittype != -1 then
            call SetItemVisible(i,false)
            call SaveItemHandle(udg_ItemHash,GetHandleId(t),0,i)
            call TimerStart(t,.01,false,function Trig_OperateItems_DropTimer)
        endif
    endif
    
    set t = null
    set u = null
    set i = null
endfunction

//===========================================================================
function InitTrig_OperateItems takes nothing returns nothing
    set gg_trg_OperateItems = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OperateItems,EVENT_PLAYER_UNIT_PICKUP_ITEM)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OperateItems,EVENT_PLAYER_UNIT_SELL_ITEM)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_OperateItems,EVENT_PLAYER_UNIT_DROP_ITEM)
    call TriggerAddAction(gg_trg_OperateItems,function Trig_OperateItems_Actions)
endfunction
От системы я хотел следующего:
udg_RuneItem[индекс] - мгновенно юзающийся итем, продаётся в магазинах и лежит на земле.
udg_NormalItem[индекс] - нормальный итем, лежит в инвентаре.
udg_ItemCost[индекс] - стоимость итема (покупка и продажа).
Для каждого предмета свой номер, по которому можно получить из RuneItem NormalItem, а также ItemCost.
Задача была такая: Сделать систему, такую, чтобы предметы скрещивались с полным инвентарём и проверяли следующие условия:
  1. Пуст (есть ли хоть один свободный слот) или полон инвентарь поднимающего предмет героя.
  2. Если инвентарь пуст, тогда просто меняем RuneItem на NormalItem.
  3. Если инвентарь героя полон, проверить:
  • Есть ли рецепт для текущего предмета и куплены ли все компоненты для него (Покупаемый предмет должен быть последним компонентом). Если да, то не выводить ошибку и скомбинировать предметы в целевой рецепт.
  • Имеет ли предмет заряды. Если да, то проверить, имеется ли среди предметов героя предмет такого же типа (имеется в виду проверка NormalItem[индекс] == UnitItemInSlot(hero,slot)). Если да, то не выводить ошибку и сложить заряды одного предмета с зарядами другого.
Во всех остальных случаях вывести ошибку и вернуть деньги через переменную ItemCost[индекс] (если предмет покупается).
» Сама проблема с этим кодом.
Когда заполнены 5 слотов инвентаря из 6, оно пишет, что инвентарь полон... По какой-то причине создаётся именно не мгновенно использующийся, а нормальный предмет на земле.
И вот как это решить?
Старый 05.12.2010, 00:48
JassMan
свободен
offline
Опыт: 4,193
Активность:
Делай на основе книг (они покупаются даже если слоты заняты)
Старый 05.12.2010, 02:01
tgonta
Pixelated Sora Coder
offline
Опыт: 3,160
Активность:
JassMan:
Делай на основе книг (они покупаются даже если слоты заняты)
Все RuneItem сделаны на основе книг, в этом сама фишка.
Старый 05.12.2010, 12:29
Sebra

offline
Опыт: 5,603
Активность:
Код пока не смотрел, но два вопроса:
Почему не хочешь покупку юнитов вместо рун?
Почему возвращать деньги, а не класть на землю?
Кинь карту поэкспериментировать... можешь всё остальное из неё выкинуть.

Отредактировано Sebra, 06.12.2010 в 19:15.
Старый 06.12.2010, 00:30
Ответ

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

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

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

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



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