Перейти к содержанию

Сообщения от Скрипты

Аватар пользователя
4 года назад
Здравствуйте
Пара вопросов по скрипту вашему: на поле боя не может быть существа с именем "Priest", равно как и Osillian (если это переменная, в которой хранится верное имя, тогда норм, а если вы забыли кавычки, то читайте дальше)
Все существа имеют составное скриптовое имя вида "координаты+айди+число", и это имя сохраняется в первый аргумент хука. В вашем случае — переменную unit. А "Priest" и "Osillian" на поле боя нет

Напишите хук хода защищающегося героя, внутри сделайте проверку:
for n, creature in GetDefenderCreatures() do
local id = GetCreatureType(creature)
if id == CREATURE_ARCHER then
local targets = GetAttackerCreatures()
chosen_target = targets[random(length(targets)+1]
-- действия со стрелком creature и целью chosen_target
end
end

Функцию random нужно написать заново, так как стандартная не работает. Рандомайзер можно взять из Эха Пустоты от RedHeavenHero, если он не против, или написать самому.
В ответ пользователю }{0TT@6bI4
Аватар пользователя
4 года назад

Спасибо большое за ответ. Да, Osillian - это переменная( "Osillian = GetDefenderHero ()" ), а 'Priest' - имя вызванного скриптом AddCreature стека. Функция random присутствует. Остается только странность с отказом героя кастовать Небесный щит на существо. В приложенном ниже скриншоте показываю ошибку, которую выдает консоль, при попытке его скастовать на существо. 

Еще возникла проблема с предложенным Вами скриптом. Собственно, ошибка, связанная с этим, тоже присутствует на скриншоте. Вот моя функция random:

Заголовокlocal default_state = {
    {1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0},
    {1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0},
    {1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1},
}
function GetPRNGSeed(state)
    local col, row = 1, 4
    local seed = {0, 0, 0, 0, 0, 0}
    for i=1,6 do
        local p2 = 1
        for j=1,23 do
            seed= seed+ p2 * (%default_state[row][col] ~= state[row][col] or 0)
            p2 = p2 * 2
            row = row - 1
            if row < 1 then row, col = 4, col + 1 end
            if col > 32 then break end
        end
        if col > 32 then break end
    end
    return seed
end

function SetPRNGSeed(state, seeds)
    state = state or {}
    seeds = seeds or {}
    for i=1,4 do
        if not statethen
            state= {}
        end
        for j=1,32 do
            state[j] = %default_state[j]
        end
    end
    local col, row = 1, 4
    local si
    for i=1,6 do
        si = seedsor si
        if not si then break end
        local si = si
        for j=1,23 do
            local bit = mod(si, 2)
            si = (si - bit) / 2
            state[row][col] = state[row][col] ~= bit or 0
            row = row - 1
            if row < 1 then row, col = 4, col + 1 end
            if col > 32 then break end
        end
        if col > 32 then break end
    end
    return state
end

function NewPRNG(seeds)
    local state = SetPRNGSeed({}, seeds)
    local random = function(n, m)
        local state = %state
        local s
        local t = state[4]
        for i=1,21 do  -- t = t xor (t << 11)
            t= t~= t[i+11] or 0
        end
        for i=9,32 do  -- t = t xor (t >> 8)
            t= t~= t[i-8] or 0
        end
        state[4] = state[3]
        state[3] = state[2]
        s = state[1]
        state[2] = s
        for i=1,32 do  -- t = t xor s
            t= t~= sor 0
        end
        for i=20,32 do  -- t = t xor (s >> 19)
            t= t~= s[i-19] or 0
        end
        state[1] = t
        local r = 0
        local p = 1
        for i=24,1,-1 do
            r = r + p * t
            p = p * 2
        end
        r = r / 16777216
        if n then
            if not m then
                n, m = 1, n
            end
            return n + floor(r * (m - n + 1))
        else
            return r
        end
    end
    return random, state
end

function InitRandom()
    local seed_t = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    local seed = {}
    local shift = 0
    for side = 0, 1 do
        for j, unit in GetCreatures(side) do
            local type = GetCreatureType(unit)
            local num = GetCreatureNumber(unit)
            local x, y = pos(unit)
            local n = mod(type, 180) + 180 * (x + 14 * (y + 14 * mod(num, 200)))
            shift = shift + 7
            for i=1,24 do
                local bit = mod(n, 2)
                n = (n - bit) / 2
                local index = mod(shift + i, 24) + 1
                seed_t[index] = seed_t[index] ~= bit or 0
            end
        end
        local x = 0
        local p = 1
        for i=1,24 do
            x = x + p * seed_t
            p = p * 2
        end
        for i=1,12 do
            seed_t, seed_t[25 - i] = seed_t[25 - i], seed_t
        end
        seed[side+1] = x
        seed[side+3] = x
        seed[side+5] = x
    end
    print('PRNG seed = ' .. seed[1] .. ':' .. seed[2])
    random = NewPRNG(seed)
end

А вот скрипт, в котором я его использую: 

Заголовокfunction DefenderHeroMove (unit)
Timer = Timer+1
  for n, creature in GetDefenderCreatures() do
    local id = GetCreatureType(creature)
    if id == CREATURE_ARCHER then
     local targets = GetAttackerCreatures()
     chosen_target = targets[random(length(targets)+1)]
    end
  end
commandShot (creature, chosen_target, nil)

}{0TT@6bI4
Здравствуйте
Пара вопросов по скрипту вашему: на поле боя не может быть существа с именем "Priest", равно как и Osillian (если это переменная, в которой хранится верное имя, тогда норм, а если вы забыли кавычки, то читайте дальше)
Все существа имеют составное скриптовое имя вида "координаты+айди+число", и это имя сохраняется в первый аргумент хука. В вашем случае — переменную unit. А "Priest" и "Osillian" на поле боя нет

Напишите хук хода защищающегося героя, внутри сделайте проверку:
for n, creature in GetDefenderCreatures() do
local id = GetCreatureType(creature)
if id == CREATURE_ARCHER then
local targets = GetAttackerCreatures()
chosen_target = targets[random(length(targets)+1]
-- действия со стрелком creature и целью chosen_target
end
end

Функцию random нужно написать заново, так как стандартная не работает. Рандомайзер можно взять из Эха Пустоты от RedHeavenHero, если он не против, или написать самому.
Вложения 1
1 файл • Общий размер: 230,3 KB
Аватар пользователя
4 года назад
Так в рандомайзере от RedHeavenHero функция рандома создаётся только по инициализации рандомайзера, т.е. по вызове функции InitRandom(), вам нужно добавить эту строчку в начало скрипта

Возможно, для каста небесного щита необходим навык призыва?
Я сталкивался с тем, что не могу скастовать масскарайку без магии света
В ответ пользователю }{0TT@6bI4
Аватар пользователя
4 года назад

Да, действительно, с экспертным призывом небесный щит начал накладываться. И random тоже начал выдавать числа. Но теперь возникла вот такая проблема: скрипт ругается на второй аргумент Вашей функции, т.е. на переменную chosen_target (скриншот прилагается). Может, я ее как-то неправильно понял и, соответственно, неправильно пишу?

P.S. Все разрешилось, просто надо было sleep написать, чтобы все корректно отработало. Спасибо большое.

Сама функция: 

Заголовокfunction DefenderHeroMove (unit)
InitRandom()
  for n, creature in GetDefenderCreatures() do
    local id = GetCreatureType(creature)
     if id == CREATURE_ARCHER then
     local targets = GetAttackerCreatures()
     local chosen_target = targets[random(length(targets)+1)]
     commandShot (creature, chosen_target, nil)
     end
  end

}{0TT@6bI4
Так в рандомайзере от RedHeavenHero функция рандома создаётся только по инициализации рандомайзера, т.е. по вызове функции InitRandom(), вам нужно добавить эту строчку в начало скрипта

Возможно, для каста небесного щита необходим навык призыва?
Я сталкивался с тем, что не могу скастовать масскарайку без магии света
Вложения 1
1 файл • Общий размер: 224,5 KB
В ответ пользователю Min_Carolin
Аватар пользователя
4 года назад

Все ж-таки проблемки остались. Во время хода героя лучник, вместо того, чтобы выполнить действие один раз, почему-то начинает стрелять огромное количество раз без остановки, пока не закончатся боеприпасы. Не могу понять, как это остановить.

Опять же, вот скрипт:

Заголовокfunction DefenderHeroMove (unit)
InitRandom()
    for n, creature in GetDefenderCreatures() do
    local id = GetCreatureType(creature)
      if id == CREATURE_ARCHER then
      local targets = GetAttackerCreatures()
      chosen_target = targets[random(length(targets)+1)]
      sleep (50)
      commandShot (creature, chosen_target, not nil)
      sleep (1)
      end
  end

 

Min_Carolin

Да, действительно, с экспертным призывом небесный щит начал накладываться. И random тоже начал выдавать числа. Но теперь возникла вот такая проблема: скрипт ругается на второй аргумент Вашей функции, т.е. на переменную chosen_target (скриншот прилагается). Может, я ее как-то неправильно понял и, соответственно, неправильно пишу?

P.S. Все разрешилось, просто надо было sleep написать, чтобы все корректно отработало. Спасибо большое.

Сама функция: 

Заголовокfunction DefenderHeroMove (unit)
InitRandom()
  for n, creature in GetDefenderCreatures() do
    local id = GetCreatureType(creature)
     if id == CREATURE_ARCHER then
     local targets = GetAttackerCreatures()
     local chosen_target = targets[random(length(targets)+1)]
     commandShot (creature, chosen_target, nil)
     end
  end

Аватар пользователя
3 года назад
Здравствуйте. У меня такая задумка: герой входит в регион(их несколько, как и героев), ему задаётся вопрос, согласившись на который запускаются какие-то действия на этом регионе(например, он блокируется пока что-то не произойдёт). Собирался составлять списки таких "активированных" регионов, как и активировавших их героев, заполняя их в массивы и потом очищая внесённых из списков(чтобы потом можно было опять их активировать этим же, или другим героем) когда действия в регионе закончатся, но к сожалению не знаю как бы это прописать.
Аватар пользователя
3 года назад

При инициализации каждого региона в списке для него на месте создаётся функция, которую будет вызывать триггер. Для функции при помощи upvalues в локальную переменную записывается имя региона. После можно производить любые действия с именем региона (и, соотвественно, его свойствами) и героем hero.

regions = {
list = {
["Region123"] = {active=nil, activator=nil},
...
},

init = function()
for region, props in regions.list do
regions.list[region].enter = function(hero)
local reg = %region
regions.list[reg].active = 1
regions.list[reg].activator = hero
-- Действия с регионом, доступ к свойствам которого можно найти по локальному имени reg
end
Trigger(REGION_ENTER_AND_STOP_TRIGGER, region, "regions.list['"..region.."'].enter")
end
end,
}

regions.init()
В ответ пользователю }{0TT@6bI4
Аватар пользователя
3 года назад
Моя проблема следующая. Есть код, суть которого выдавать приоритет на захват жилищ для ИИ через поток. Всё работает прекрасно, кроме одного. Если 1 из героев ИИ засаживается в замке, то поток крашится. Частоту краша можно сократить раз в 100 если добавить чек IsHeroInTown, но все равно на 2-3 неделе краш случится, когда чек успешно пройден, а в этот момент герой садится в замок. Ещё этот чек утяжеляет поток, из-за чего ищу другие варианты. Можно ли как-то отследить краш и запустить поток заново? Есть ли более интересные идеи?
--global_creature_arrays--------------------------------------------------------
CnogradeID = {};--non-upgrade_creature_IDs_(tier_1-7)
CnogradeID[0] = { 1, 3, 5, 7, 9, 11, 13};--haven
CnogradeID[1] = { 43, 45, 47, 49, 51, 53, 55};--sylvan
CnogradeID[2] = { 57, 59, 61, 63, 65, 67, 69};--academy
CnogradeID[3] = { 71, 73, 75, 77, 79, 81, 83};--dungeon
CnogradeID[4] = { 29, 31, 33, 35, 37, 39, 41};--necropolis
CnogradeID[5] = { 15, 17, 19, 21, 23, 25, 27};--inferno
CnogradeID[6] = { 92, 94, 96, 98,100,102,104};--fortress
CnogradeID[7] = {117,119,121,123,125,127,129};--stronghold
--
Cgrade1ID = {};--first_upgrade_creature_IDs_(tier_1-7)
Cgrade1ID[0] = { 2, 4, 6, 8, 10, 12, 14};--haven
Cgrade1ID[1] = { 44, 46, 48, 50, 52, 54, 56};--sylvan
Cgrade1ID[2] = { 58, 60, 62, 64, 66, 68, 70};--academy
Cgrade1ID[3] = { 72, 74, 76, 78, 80, 82, 84};--dungeon
Cgrade1ID[4] = { 30, 32, 34, 36, 38, 40, 42};--necropolis
Cgrade1ID[5] = { 16, 18, 20, 22, 24, 26, 28};--inferno
Cgrade1ID[6] = { 93, 95, 97, 99,101,103,105};--fortress
Cgrade1ID[7] = {118,120,122,124,126,128,130};--stronghold
--
Cgrade2ID = {};--second_upgrade_creature_IDs_(tier_1-7)
Cgrade2ID[0] = {106,107,108,109,110,111,112};--haven
Cgrade2ID[1] = {145,146,147,148,149,150,151};--sylvan
Cgrade2ID[2] = {159,160,161,162,163,164,165};--academy
Cgrade2ID[3] = {138,139,140,141,142,143,144};--dungeon
Cgrade2ID[4] = {152,153,154,155,156,157,158};--necropolis
Cgrade2ID[5] = {131,132,133,134,135,136,137};--inferno
Cgrade2ID[6] = {166,167,168,169,170,171,172};--fortress
Cgrade2ID[7] = {173,174,175,176,177,178,179};--stronghold
--
Cgrowth = {};--creature_weekly_growth_modifier_(1_weekly_growth+( special_building_growth)/2))
Cgrowth[0] = { 24, 12, 10, 5, 3, 2, 1};--haven
Cgrowth[1] = { 12, 9, 7, 4, 3,2.5, 1};--sylvan
Cgrowth[2] = { 20, 14, 9, 5, 4, 2, 1};--academy
Cgrowth[3] = { 8, 6, 6, 4, 3, 2, 1};--dungeon
Cgrowth[4] = { 23, 15, 9, 5, 3, 2,1.5};--necropolis
Cgrowth[5] = { 16, 16, 8, 5,3.5, 2, 1};--inferno
Cgrowth[6] = { 18, 14, 7, 8,3.5, 2, 1};--fortress
Cgrowth[7] = { 28, 13, 11, 5, 5, 2, 1};--stronghold
--
Cpower = {};--average_power_of_1_weekly_growth_of_units_from_tie r_1_to_tier_7
Cpower[1] = {1100,1700,2000,2600,3300,4300,4850};--non-upgraded
Cpower[2] = {1800,2400,2900,3500,4500,5000,6000};--upgraded
Cpower[3] = {1800,2400,2900,3500,4500,5000,6000};--upgraded
--
Cgradetype = {CnogradeID,Cgrade1ID,Cgrade2ID};--upgrade_type_identifier
--
function GetArmyPower(OBJ)
local VALUE = 0;
for i = 1,3 do--creature_upgrade_type
for j = 0,7 do--creature_race
for k = 1,7 do--creature_tier
if GetObjectCreatures(OBJ,Cgradetype[j][k]) > 0 then
VALUE = VALUE + ceil(GetObjectCreatures(OBJ,Cgradetype[j][k])/Cgrowth[j][k]*Cpower[k]);
end;
end;
end;
end;
return VALUE;
end;
--dwelling_AI_attraction--------------------------------------------------------
function AIAttractionLoop(PLAYER)
if GetPlayerRace(1) == GetPlayerRace(2) then--if_players'_race_is_the_same
while 1 do
for i = 1,2 do--dwelling_side
for j = 1,4 do--dwelling_levels
if GetObjectOwner("Dwel"..j.."P"..i) ~= PLAYER then
SetAIPlayerAttractor("Dwel"..j.."P"..i,PLAYER,1);--set_dwelling_attractor
else
SetAIPlayerAttractor("Dwel"..j.."P"..i,PLAYER,-1);--attractor_cancel
end;
end;
end;
sleep(5);
end;
else--if_players'_race_isn't_the_same
while 1 do
local AIheroes = GetPlayerHeroes(PLAYER);
local ln = length(AIheroes);
for i = 0,ln-1 do--quantity_of_AI_heroes
for j = 1,2 do--dwelling_side
for k = 1,4 do--dwelling_levels
if GetObjectOwner("Dwel"..k.."P"..j) ~= PLAYER then
if GetArmyPower(AIheroes) > GetArmyPower("Dwel"..k.."P"..j.."Gar")*2 then
SetAIHeroAttractor("Dwel"..k.."P"..j,AIheroes,1);--set_dwelling_attractor
end;
else
SetAIHeroAttractor("Dwel"..k.."P"..j,AIheroes,0);--attractor_cancel
end;
end;
end;
end;
sleep(5);
end;
end;
end;
--
if IsAIPlayer(1) == 1 then
startThread(AIAttractionLoop,1);
elseif IsAIPlayer(2) == 1 then
startThread(AIAttractionLoop,2);
end;
Вложения 1
1 файл • Общий размер: 4,9 KB
В ответ пользователю Долгий
Аватар пользователя
3 года назад
Cделал. Нужно было просто запустить отдельный поток, который запускает функцию AIAttractionLoop, в которой удалил while'ы. Даже есле функция крашится, из-за героя, засевшего в городе, новый поток продолжает запускает её.
3 года назад
Добрый вечер, сделал функцию на повышение уровня и не могу понять, что можно такого прописать в level up hero, чтобы он повышал левел именно того героя, который дотронулся до объекта.Тут все работает, кроме уже сказанного level up hero.

function OPIT()
    number = GetCurrentPlayer()
    Gold = GetPlayerResource(number,6)
    if Gold >= 6000 then
       QuestionBoxForPlayers(number,"Maps/Multiplayer/JoyPatriot/Teks/Vopros.txt", "yes", "no")
    else MessageBoxForPlayers(number,"Maps/Multiplayer/JoyPatriot/Teks/OP.txt", nil)
end
end

function yes()
         number = GetCurrentPlayer()
         SetPlayerResource(number,6,Gold-6000)
         LevelUpHero(hero)
end

SetObjectEnabled("OP",nil);
Trigger(OBJECT_TOUCH_TRIGGER,"OP","OPIT");
Аватар пользователя
3 года назад
Небольшой экскурс. hero  — это переменная. Чтобы в неё было что-то записано, нужно туда что-то записать! Это делается ручным объявлением переменной или же игра своими действиями запишет в локальную что-то. Для этого в подтриггерную функцию указываются аргументы (список указан в мануале разработчиков у функции Trigger). То есть
function Test(hero)
if hero == "..." then

end
end
Trigger(OBJECT_TOUCH_TRIGGER, ...).

В вашем случае код нужно поменять так:
function OPIT(hero)
number = GetCurrentPlayer() --Рекомендую заменить на number=GetObjectOwner(hero)
local Gold = GetPlayerResource(number,6) --Переменную лучше держать локальную
if Gold >= 6000 then
QuestionBoxForPlayers(number,"Maps/Multiplayer/JoyPatriot/Teks/Vopros.txt", "yes([["..hero.."]])", "no")
else MessageBoxForPlayers(number,"Maps/Multiplayer/JoyPatriot/Teks/OP.txt", nil)
end
end

function yes(hero)
number = GetCurrentPlayer() --То же самое. Лучше number=GetObjectOwner(hero)
local Gold = GetPlayerResource(number) --Ничего страшного в повторении операции нет, хотя можно и лучше сделать; но главное — исключена ошибка с перезаписью чего-то в переменную Gold
SetPlayerResource(number,6,Gold-6000)
LevelUpHero(hero)
return parse '' --Убираем машинную ошибку, которая ни на что не влияет. Иначе в консоль будет спамиться предупреждение
end

SetObjectEnabled("OP",nil);
Trigger(OBJECT_TOUCH_TRIGGER,"OP","OPIT");

P.s. Переменным рекомендую давать осмысленный названия. И объектам тоже. Например, "ExperienceStone" и "ExperienceStoneTouch", соответственно...

3 года назад

Спасибо, теперь понял. 

Но теперь почему-то сообщения перестали выводится для одного из 4-х игроков, а только для красного или синего игрока. Тобишь раньше у меня скрипт выводил сообщение лишь тому игроку, который дотрагивается до объекта, а теперь только красному или синему, а если дотронется зеленый или оранжевый игрок, то сообщение одновременно идет и красному и синему.

Аватар пользователя
3 года назад
Добавьте print(number, ", ", hero, ", ", GetObjectOwner(hero)) перед сообщениями и скажите, что выводит при касаниях...
В ответ пользователю }{0TT@6bI4
3 года назад
}{0TT@6bI4
Добавьте print(number, ", ", hero, ", ", GetObjectOwner(hero)) перед сообщениями и скажите, что выводит при касаниях...


Оно пишет:

для первого - 1, Calid, 1

для второго - 2, Sarge, 2

для третьего - 3, Mardigo, 3
Ну и для 4 игрока соотвественно

Аватар пользователя
3 года назад
Мне кажется, дело в том, что зеленый и оранжевый игроки — компьютерные. И, предположу, в моём случае всё работает правильно и просто по механике MessageBoxForPlayers сообщения для компов перенаправляется игрокам. А в вашем случае... а вот и узнаем. Оставьте принт, но в number верните формулу подсчета номера игрока свою, старую

Статистика

Приветствуем новейшего участника: recijeb