CustomGames.ru - Dota 2 пользовательские игры

Зацикливание

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн den4iccc

  • Продвинутый
  • 400
  • Мощь: 7
Зацикливание
« : 07-03-2017, 11:20:45 »
Хоть и тупой вопрос, но я не понимаю почему у меня идёт зацикливание у меня есть проверка for i = 0,1 do еcли FindAbilityByName значит RemoveAbility, пробовал через break и GetAbilityByIndex(i) всё равно цикл не заканчивается, без цикла у меня просто не заносится ничего в панель абилок, (как мне сделать проверку без зацикливания ?) + это у меня не способность где нужно прожать кастер
« Последнее редактирование: 07-03-2017, 11:22:48 от den4iccc »

Оффлайн Илья

  • Супермодератор
  • 2142
  • Мощь: 21
Re: Зацикливание
« Ответ #1 : 07-03-2017, 12:12:59 »
Код скинь

Оффлайн den4iccc

  • Продвинутый
  • 400
  • Мощь: 7
Re: Зацикливание
« Ответ #2 : 07-03-2017, 12:18:04 »
Я вписал это в систему постройки то есть когда постройка возведена он делает проверку если есть абилка то он её удаляет, но получается так что он проверяет это с бесконечностью
Код
	local player = event.caster:GetPlayerOwner()
local pID = player:GetPlayerID()
    local hero = player:GetAssignedHero()
local caster = event.caster
local ability = event.ability

 for i=0,1 do 
if hero:FindAbilityByName("ability_2") then
caster:RemoveAbility("ability_1")
end
end
я бы не назвал это кодом) это скорее всего быдлокод
« Последнее редактирование: 07-03-2017, 12:22:56 от den4iccc »

Оффлайн Илья

  • Супермодератор
  • 2142
  • Мощь: 21
Re: Зацикливание
« Ответ #3 : 07-03-2017, 12:35:52 »
Ты уверен, что зацикливание именно в этом куске?
Проверь принтами, где происходит зацикливание:

Код
print("one")
 for i=0,1 do
        print("second")
if hero:FindAbilityByName("ability_2") then
caster:RemoveAbility("ability_1")
end
end

Оффлайн den4iccc

  • Продвинутый
  • 400
  • Мощь: 7
Re: Зацикливание
« Ответ #4 : 07-03-2017, 12:38:59 »
Мне нужно прописать время для обработки запроса как я понял ? консоль выдает [Developer]: RemoveAbility - Unit does not have ability ability_1.
Сам процесс с принтом [   VScript       ]: one
[   VScript       ]: second
[   Developer     ]: RemoveAbility - Unit does not have ability ability_1.
[   VScript       ]: second
[   Developer     ]: RemoveAbility - Unit does not have ability ability_1.
[   VScript       ]: one
[   VScript       ]: second
[   Developer     ]: RemoveAbility - Unit does not have ability ability_1.
[   VScript       ]: second
[   Developer     ]: RemoveAbility - Unit does not have ability ability_1.
[   VScript       ]: one
[   VScript       ]: second
« Последнее редактирование: 07-03-2017, 12:40:48 от den4iccc »

Оффлайн Илья

  • Супермодератор
  • 2142
  • Мощь: 21
Re: Зацикливание
« Ответ #5 : 07-03-2017, 12:44:23 »
У тебя зацикливание происходит не в цикле for.
А в том коде, в котором этот for лежит.

Скинь полный кусок.

Оффлайн den4iccc

  • Продвинутый
  • 400
  • Мощь: 7
Re: Зацикливание
« Ответ #6 : 07-03-2017, 12:49:37 »
Спойлер
Код
	local player = event.caster:GetPlayerOwner()
local pID = player:GetPlayerID()
    local hero = player:GetAssignedHero()
local caster = event.caster
local ability = event.ability

if not IsChanneling( caster ) then
-- Remake
ability.queue = {}

for itemSlot=0,5 do
local item = caster:GetItemInSlot(itemSlot)
if item ~= nil then

table.insert(ability.queue, item:GetEntityIndex())

local item_name = tostring(item:GetAbilityName())
if not IsChanneling( caster ) and string.find(item_name, "train") then

local train_ability_name = string.gsub(item_name, "item_", "")

local ability_to_channel = caster:FindAbilityByName(train_ability_name)

ability_to_channel:SetChanneling(true)
if Debug_Queue then
print(ability_to_channel:GetAbilityName()," started channel")
end

Timers:CreateTimer(ability_to_channel:GetChannelTime(),
function()
if Debug_Queue then
print("table")
DeepPrintTable(ability_to_channel.queue)
end
if IsValidEntity(item) then
ability_to_channel:EndChannel(false)
ReorderItems(caster, ability_to_channel.queue)
if Debug_Queue then
print("finis building")
end
else
if Debug_Queue then
print("aborted")
end
end
end)
end
end
end
end
-- print("one")
-- for i=0,1 do 
-- print("second")
-- if hero:FindAbilityByName("ability_2") then
-- caster:RemoveAbility(""ability_1")
-- end
  -- end
[свернуть]

Оффлайн Илья

  • Супермодератор
  • 2142
  • Мощь: 21
Re: Зацикливание
« Ответ #7 : 07-03-2017, 12:55:51 »
Это весь кусок? Чет я не вижу его начала, не вижу слов "function".


Оффлайн den4iccc

  • Продвинутый
  • 400
  • Мощь: 7
Re: Зацикливание
« Ответ #8 : 07-03-2017, 12:58:44 »
да это вся функция Система билдинга от Noya, function AdvanceQueue( event ) .... end

Оффлайн Илья

  • Супермодератор
  • 2142
  • Мощь: 21
Re: Зацикливание
« Ответ #9 : 07-03-2017, 13:02:02 »
Я без понятия, какая там у него система. Скинь код целиком. Скорее всего, у тебя вся эта функция где-то вызывается в бесконечном цикле, а не сама функция устраивает зацикливание.

Можешь прям это проверить, написав принт сразу после слов function().

Оффлайн den4iccc

  • Продвинутый
  • 400
  • Мощь: 7
Re: Зацикливание
« Ответ #10 : 07-03-2017, 13:05:51 »
Спойлер
Код
Debug_Queue = false
function EnqueueUnit( event, food )
local player = event.caster:GetPlayerOwner()
local pID = player:GetPlayerID()
    local hero = player:GetAssignedHero()
local caster = event.caster
local ability = event.ability
local player = caster:GetPlayerOwner():GetPlayerID()
local gold_cost = ability:GetGoldCost( ability:GetLevel() - 1 )

if CheckFood(caster:GetPlayerOwner(), tonumber(event.food),true)== false then
PlayerResource:ModifyGold(caster:GetPlayerOwnerID(), gold_cost, false, 0)
return
else
SpendFood(caster:GetPlayerOwner(), tonumber(event.food))
end

-- Initialize queue
if not ability.queue then
ability.queue = {}
end



-- Queue up to 6 units max
if #ability.queue < 6 then

local ability_name = ability:GetAbilityName()
local item_name = "item_"..ability_name
local item = CreateItem(item_name, caster, caster)
caster:AddItem(item)

-- RemakeQueue
ability.queue = {}
for itemSlot = 0, 5, 1 do
local item = caster:GetItemInSlot( itemSlot )
if item ~= nil then
table.insert(ability.queue, item:GetEntityIndex())
end
end
else
-- Refund with message
  PlayerResource:ModifyGold(player, gold_cost, false, 0)
FireGameEvent( 'custom_error_show', { player_ID = player, _error = "Queue is full" } )
end
end

function SetOwner( event )
local caster = event.caster
local target = event.target

print(tonumber(event.food))

target.foodSpent = tonumber(event.food)
target:SetOwner(caster:GetOwner())
end

-- Destroys an item on the buildings inventory, refunding full cost of purchasing and reordering the queue
-- If its the first slot, the channeling ability is also set to not channel, refunding the full price.
function DequeueUnit( event )
local caster = event.caster
local item = event.ability
local player = caster:GetPlayerOwner():GetPlayerID()

local item_ability = EntIndexToHScript(item:GetEntityIndex())
local item_ability_name = item_ability:GetAbilityName()

-- Get tied ability
local train_ability_name = string.gsub(item_ability_name, "item_", "")
local train_ability = caster:FindAbilityByName(train_ability_name)
local gold_cost = train_ability:GetGoldCost( train_ability:GetLevel() - 1 )

if Debug_Queue then
print("Start dequeue")
end

for itemSlot = 0, 5, 1 do
        local item = caster:GetItemInSlot( itemSlot )
        if item ~= nil then
        local current_item = EntIndexToHScript(item:GetEntityIndex())

        if current_item == item_ability then
        if Debug_Queue then
        print("Q")
        DeepPrintTable(train_ability.queue)
        end
        local queue_element = getIndex(train_ability.queue, item:GetEntityIndex())
        if Debug_Queue then
        print(item:GetEntityIndex().." in queue at "..queue_element)
        end
            table.remove(train_ability.queue, queue_element)

            caster:RemoveItem(item)
           
            -- Refund ability cost
            PlayerResource:ModifyGold(player, gold_cost, false, 0)

            local foodToReturn = train_ability:GetLevelSpecialValueFor("food_cost", 1)
            caster:GetPlayerOwner().food = caster:GetPlayerOwner().food - foodToReturn

            if Debug_Queue then
print("Refund ",gold_cost)
end

-- Set not channeling if the cancelled item was the first **current** slot
if itemSlot == 0 then
train_ability:SetChanneling(false)
train_ability:EndChannel(true)
if Debug_Queue then
print("Cancel current channel")
end
ReorderItems(caster,train_ability.queue)
else
if Debug_Queue then
print("Removed unit in queue slot",itemSlot)
end
end
break
end
        end
    end
end

-- Auxiliar function, takes all items and puts them 1 slot back
function ReorderItems( caster, queue )
queue = {}
for itemSlot = 0, 5, 1 do
local item = caster:GetItemInSlot( itemSlot )
        if item ~= nil then
        if Debug_Queue then
        print("========>REMOVING",item:GetEntityIndex())   
        end
    local new_item = CreateItem(item:GetName(), caster, caster)
        caster:RemoveItem(item)
table.insert(queue, new_item:GetEntityIndex())
if Debug_Queue then
print("========>ADDED",new_item:GetEntityIndex())   
end
        caster:AddItem(new_item)
        end
    end
end


-- Moves on to the next element of the queue
function NextQueue( event )
local caster = event.caster
local ability = event.ability
ability:SetChanneling(false)
--print("Move next!")

-- Dequeue
--DeepPrintTable(event)
local hAbility = EntIndexToHScript(ability:GetEntityIndex())

for itemSlot = 0, 5, 1 do
        local item = caster:GetItemInSlot( itemSlot )
        if item ~= nil then
        local item_name = tostring(item:GetAbilityName())

        -- Remove the "item_" to compare
        local train_ability_name = string.gsub(item_name, "item_", "")

        if train_ability_name == hAbility:GetAbilityName() then

        local train_ability = caster:FindAbilityByName(train_ability_name)

        if Debug_Queue then
        print("Q")
        DeepPrintTable(train_ability.queue)
        end
        local queue_element = getIndex(train_ability.queue, item:GetEntityIndex())
        if IsValidEntity(item) then
        if Debug_Queue then
        print(item:GetEntityIndex().." in queue at "..queue_element)
        end
            table.remove(train_ability.queue, queue_element)
            caster:RemoveItem(item)
            end

            break
            elseif item then
        --print(item_name,hAbility:GetAbilityName())
        end
        end
    end
end

function AdvanceQueue( event )
local player = event.caster:GetPlayerOwner()
local pID = player:GetPlayerID()
    local hero = player:GetAssignedHero()
local caster = event.caster
local ability = event.ability

if not IsChanneling( caster ) then
-- Remake
ability.queue = {}

for itemSlot=0,5 do
local item = caster:GetItemInSlot(itemSlot)
if item ~= nil then

table.insert(ability.queue, item:GetEntityIndex())

local item_name = tostring(item:GetAbilityName())
if not IsChanneling( caster ) and string.find(item_name, "train") then

local train_ability_name = string.gsub(item_name, "item_", "")

local ability_to_channel = caster:FindAbilityByName(train_ability_name)

ability_to_channel:SetChanneling(true)
if Debug_Queue then
print(ability_to_channel:GetAbilityName()," started channel")
end

Timers:CreateTimer(ability_to_channel:GetChannelTime(),
function()
if Debug_Queue then
print("table")
DeepPrintTable(ability_to_channel.queue)
end
if IsValidEntity(item) then
ability_to_channel:EndChannel(false)
ReorderItems(caster, ability_to_channel.queue)
if Debug_Queue then
print("finis building")
end
else
if Debug_Queue then
print("aborted")
end
end
end)
end
end
end
end
-- print("one")
-- for i=0,1 do 
-- print("second")
-- if hero:FindAbilityByName("ability_2") then
-- caster:RemoveAbility(""ability_1")
-- end
  -- end
end


-- Auxiliar table function
function tableContains(list, element)
    if list == nil then return false end
    for i=1,#list do
        if list[i] == element then
            return true
        end
    end
    return false
end

function getIndex(list, element)
    if list == nil then return false end
    for i=1,#list do
        if list[i] == element then
            return i
        end
    end
    return -1
end

function getUnitIndex(list, unitName)
    --print("Given Table")
    --DeepPrintTable(list)
    if list == nil then return false end
    for k,v in pairs(list) do
        for key,value in pairs(list[k]) do
        if Debug_Queue then
            print(key,value)
          end
            if value == unitName then
                return key
            end
        end       
    end
    return -1
end

-- Auxiliar function that goes through every ability and item, checking for any ability being channelled
function IsChanneling ( unit )

for abilitySlot=0,15 do
local ability = unit:GetAbilityByIndex(abilitySlot)
if ability ~= nil and ability:IsChanneling() then
return true
end
end

for itemSlot=0,5 do
local item = unit:GetItemInSlot(itemSlot)
if item ~= nil and item:IsChanneling() then
return true
end
end

return false
end

function BuildHero( event )
local caster = event.caster
local player = caster:GetPlayerOwner()
local hero = player:GetAssignedHero()
local playerID = player:GetPlayerID()
local unit_name = event.Hero
local origin = event.caster:GetAbsOrigin() + RandomVector(250)

-- Get a random position to create the illusion in
local origin = caster:GetAbsOrigin() + RandomVector(150)

-- handle_UnitOwner needs to be nil, else it will crash the game.
local illusion = CreateUnitByName(unit_name, origin, true, hero, nil, hero:GetTeamNumber())
illusion:SetPlayerID(playerID)
illusion:SetControllableByPlayer(playerID, true)

end
[свернуть]

Оффлайн Илья

  • Супермодератор
  • 2142
  • Мощь: 21
Re: Зацикливание
« Ответ #11 : 07-03-2017, 13:09:18 »
Посел function AdvanceQueue( event ) пропиши print("ok").

Если будет в консоли постоянно писаться ok, то ищи место, где ты вызываешь эту функцию AdvanceQueue().

Оффлайн den4iccc

  • Продвинутый
  • 400
  • Мощь: 7
Re: Зацикливание
« Ответ #12 : 07-03-2017, 13:14:25 »
Ахахах дичь у меня OnIntervalThink стоит пассивка которая и вызывает функцию AdvanceQueue я вчера с этим геморойничел прописал для npc OnIntervalThink который бы чекал с опред таймером, можно ли как нибудь записать если это действие произошло иначе типо прерывает интервал
« Последнее редактирование: 07-03-2017, 13:17:24 от den4iccc »

Оффлайн Илья

  • Супермодератор
  • 2142
  • Мощь: 21
Re: Зацикливание
« Ответ #13 : 07-03-2017, 13:16:22 »
Поздравляю с открытием :)

Оффлайн den4iccc

  • Продвинутый
  • 400
  • Мощь: 7
Re: Зацикливание
« Ответ #14 : 07-03-2017, 13:30:36 »
Кароч я перенёс это в другой файл там сделал эту проверку и прописал новую абилку, и вопрос можно ли как то работать из lua с ThinkInterval или придётся прописывать
типо вот этого local cooldown = ability:GetLevelSpecialValueFor( "cooldown" , ability:GetLevel() - 1  ) и занести "cooldown" в AbilitySpecial
Спойлер
Код
	"chek"
{
  "BaseClass"           "ability_datadriven"
  "MaxLevel"            "1"
  "AbilityBehavior"       "DOTA_ABILITY_BEHAVIOR_PASSIVE"

  "Modifiers"
  {
    "modifier_cheking"
    {
      "Passive"     "1"
      "IsHidden"      "1"
 
      "ThinkInterval"  "0.03"
      "OnIntervalThink"
      {
        "RunScript"
        {
          "ScriptFile"  "chek.lua"
          "Function"    "cheking"
        }
      }
    }

    "modifier_cheking_passive"
    {
      "Passive"     "1"
      "IsHidden"      "1"
 
      "States"
      {
        "MODIFIER_STATE_ROOTED"   "MODIFIER_STATE_VALUE_ENABLED"
      }
    }
  }
}

[свернуть]

lua
Спойлер
Код
function cheking(keys)
local player = keys.caster:GetPlayerOwner()
    local pID = player:GetPlayerID()
    local hero = player:GetAssignedHero()
    local caster = keys.caster

local target = keys.target
local ability = keys.ability


for i=0,1 do 
if hero:FindAbilityByName("ability_2") then
caster:RemoveAbility("ability_1")
end
end

end
[свернуть]
« Последнее редактирование: 07-03-2017, 13:33:26 от den4iccc »