Zahanc #1 - 8 часов назад 0

» Осквернитель / Главная страница

Выставляю первую главу на проверку. Смотрите главную страницу.
прикреплены файлы
Zahanc #2 - 1 день назад 0

» Осквернитель / Главная страница

Не сумел довести до ума в прошлую неделю. Однако работал довольно много над кампанией. В этом месяце точно первую главу выпущу. Уже вообщем можно и поиграть. Создаю копию здесь, на всякий.
прикреплены файлы
Zahanc #3 - 3 дня назад 0

» WarCraft 3 / Заклинания на заказ

Обновил заклинание Кокон до версии 3 для 1.26а.
прикреплены файлы
Zahanc #4 - 4 дня назад 0

» WarCraft 3 / Pollar

Мне бы библиотеку для работы с векторами. Представленные функции я могу и сам написать ничего не импортируя.
Zahanc #5 - 5 дней назад (отредактировано ) 1

» WarCraft 3 / Заклинания на заказ

// globals
//    integer array udg_cocoonSpawnUnitTypeId
//    integer array udg_cocoonSpawnsQuantity
//    integer array udg_cocoonUnitTypeId
//    integer cocoonsQuantity = 0
//    player array udg_cocoonOwner
//    real array udg_cocoonHatchDelay
//    real array udg_cocoonOriginX
//    real array udg_cocoonOriginY
//    real array udg_cocoonTargetY
//    real array udg_cocoonTragetX
//    real array udg_cocoonVectorX
//    real array udg_cocoonVectorY
//    unit array udg_cocoon
//    unit array udg_cocoonMissile
//    timer udg_cocoonsTimer
// endglobals

function CocoonTimerCallback takes nothing returns nothing
    local integer i = 0
    local integer j = 0
    local player owner = null
    local real distanceCovered = 0.0
    local real distanceTotal = 0.0
    local real distanceRemaining = 0.0
    local timer t = GetExpiredTimer()
    local real timeout = TimerGetTimeout(t)
    local real x = 0.0
    local real x0 = 0.0
    local real x1 = 0.0
    local real y = 0.0
    local real y0 = 0.0
    local real y1 = 0.0
    local unit missile = null
    local unit spawn = null
    local unit u = null
    local real z = 0.0

    if udg_cocoonsQuantity <= 0 then
        set t = null
	call DestroyTimer(t)
    endif

    loop
        exitwhen i >= udg_cocoonsQuantity
	if IsUnitDeadBJ(udg_cocoon[i]) and null == udg_cocoonMissile[i] then
	    set udg_cocoonsQuantity = udg_cocoonsQuantity - 1

            set udg_cocoonSpawnUnitTypeId[i] = udg_cocoonSpawnUnitTypeId[udg_cocoonsQuantity] 
	    set udg_cocoonSpawnsQuantity[i] = udg_cocoonSpawnsQuantity[i]
            set udg_cocoonUnitTypeId[i] = udg_cocoonUnitTypeId[udg_cocoonsQuantity] 
            set udg_cocoonOwner[i] = udg_cocoonOwner[udg_cocoonsQuantity] 
            set udg_cocoonHatchDelay[i] = udg_cocoonHatchDelay[udg_cocoonsQuantity] 
            set udg_cocoonOriginX[i] = udg_cocoonOriginX[udg_cocoonsQuantity] 
            set udg_cocoonOriginY[i] = udg_cocoonOriginY[udg_cocoonsQuantity] 
            set udg_cocoonTargetX[i] = udg_cocoonTargetX[udg_cocoonsQuantity] 
            set udg_cocoonTargetY[i] = udg_cocoonTargetY[udg_cocoonsQuantity] 
            set udg_cocoonVectorX[i] = udg_cocoonVectorX[udg_cocoonsQuantity] 
            set udg_cocoonVectorY[i] = udg_cocoonVectorY[udg_cocoonsQuantity] 
	    set udg_cocoon[i] = udg_cocoon[udg_cocoonsQuantity] 
            set udg_cocoonMissile[i] = udg_cocoonMissile[udg_cocoonsQuantity] 
 
            set udg_cocoonSpawnUnitTypeId[udg_cocoonsQuantity] = 0 
	    set udg_cocoonSpawnsQuantity[udg_cocoonsQuantity] = 0
            set udg_cocoonUnitTypeId[udg_cocoonsQuantity] = 0 
            set udg_cocoonOwner[udg_cocoonsQuantity] = null 
            set udg_cocoonHatchDelay[udg_cocoonsQuantity] = 0.0 
            set udg_cocoonOriginX[udg_cocoonsQuantity] = 0.0 
            set udg_cocoonOriginY[udg_cocoonsQuantity] = 0.0 
            set udg_cocoonTargetX[udg_cocoonsQuantity] = 0.0 
            set udg_cocoonTargetY[udg_cocoonsQuantity] = 0.0 
            set udg_cocoonVectorX[udg_cocoonsQuantity] = 0.0 
            set udg_cocoonVectorY[udg_cocoonsQuantity] = 0.0 
	    set udg_cocoon[udg_cocoonsQuantity] = null 
            set udg_cocoonMissile[udg_cocoonsQuantity] = null 
	endif 

        set u = udg_cocoon[i]
	set missile = udg_cocoonMissile[i]
	if missile != null then
	    set x0 = udg_cocoonOriginX[i]
	    set y0 = udg_cocoonOriginY[i]
	    set x1 = udg_cocoonTargetX[i]
	    set y1 = udg_cocoonTargetY[i]

	    call SetUnitPosition(missile, GetUnitX(missile) + udg_cocoonVectorX[i]*timeout, GetUnitY(missile) + udg_cocoonVectorY[i]*timeout)
	    set x = GetUnitX(missile)
	    set y = GetUnitY(missile)
	    set distanceTotal = SquareRoot((x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0))
	    set distanceRemaining = SquareRoot((x1 - x)*(x1 - x) + (y1 - y)*(y1 - y)) 
            set distanceCovered = SquareRoot((x - x0)*(x - x0) + (y - y0)*(y - y0))
	    set z = 4*128.0/distanceTotal*distanceRemaining*(distanceCovered/distanceTotal)
	    call SetUnitFlyHeight(missile, z, 0.0)
	    if distanceRemaining <= 64.0 then
	        call RemoveUnit(missile)
		set udg_cocoon[i] = CreateUnit(udg_cocoonOwner[i], udg_cocoonUnitTypeId[i], x1, y1, 225.0)
		set u = udg_cocoon[i]
		call SetUnitUseFood(u, false)
                call UnitAddType(u, UNIT_TYPE_SUMMONED)
                call SetUnitExploded(u, true)
		call PauseUnit(u, true)
	    endif
	endif
       
	if u != null then
            set udg_cocoonHatchDelay[i] = udg_cocoonHatchDelay[i] - timeout
	endif
	if udg_cocoonHatchDelay[i] <= 0.0 and IsUnitAliveBJ(u) then
            set x1 = udg_cocoonTargetX[i]
	    set y1 = udg_cocoonTargetY[i] 
	    call KillUnit(u)
	    set j = 0
	    loop
	        exitwhen j >= udg_cocoonSpawnsQuantity[i]
		set spawn = CreateUnit(udg_cocoonOwner[i], udg_cocoonSpawnUnitTypeId[i], x1, y1, 225.0)
		call SetUnitUseFood(spawn, false)
                call UnitAddType(spawn, UNIT_TYPE_SUMMONED)
                call SetUnitExploded(spawn, true)
		set j = j + 1
            endloop
	endif
	set i = i + 1
    endloop

    set owner = null
    set t = null
    set missile = null
    set spawn = null
    set u = null
endfunction

function CreateSpellEffectCocoon takes unit c, integer cocoon, integer cq, integer spiderling, integer sq, real delay, real x1, real y1, real r returns nothing
    local integer cocoonsQuantity = IMinBJ(IMaxBJ(cq, 1), IMinBJ(128, JASS_MAX_ARRAY_SIZE - udg_cocoonsQuantity - 1))
    local integer i = 0
    local integer j = 0
    local integer spiderlingsQuantity = IMinBJ(IMaxBJ(sq, 1), 64)
    local player p = GetOwningPlayer(c)
    local real hatchDelay = RMaxBJ(1.0, delay)
    local real radius = RMaxBJ(r, 32.0)
    local real x0 = GetUnitX(c)
    local real y0 = GetUnitY(c)
    local unit u = null

    loop
        exitwhen j >= cocoonsQuantity 
	set u = CreateUnit(p, cocoon, x0, y0, bj_UNIT_FACING)
	call SetUnitUseFood(u, false)
	call UnitAddAbility(u, 'Aloc')
	call UnitAddAbility(u, 'Amrf')
	call SetUnitInvulnerable(u, true)
	call SetUnitX(u, x0)
	call SetUnitY(u, y0)
	call PauseUnit(u, true)

	set i = udg_cocoonsQuantity
	set udg_cocoonSpawnUnitTypeId[i] = spiderling
	set udg_cocoonSpawnsQuantity[i] = spiderlingsQuantity
        set udg_cocoonUnitTypeId[i] = cocoon
        set udg_cocoonOwner[i] = p
        set udg_cocoonHatchDelay[i] = hatchDelay
        set udg_cocoonOriginX[i] = x0
        set udg_cocoonOriginY[i] = y0
        set udg_cocoonTargetX[i] = x1 + radius*Cos(I2R(i)*(360.0/I2R(cocoonsQuantity)*bj_DEGTORAD))
        set udg_cocoonTargetY[i] = y1 + radius*Sin(I2R(i)*(360.0/I2R(cocoonsQuantity)*bj_DEGTORAD)) 
        set udg_cocoonVectorX[i] = (udg_cocoonTargetX[i] - x0)/radius*1100.0
        set udg_cocoonVectorY[i] = (udg_cocoonTargetY[i] - y0)/radius*1100.0
        set udg_cocoon[i] = null
        set udg_cocoonMissile[i] = u
	set udg_cocoonsQuantity = udg_cocoonsQuantity + 1
	set j = j + 1
    endloop
   
    if null == udg_cocoonsTimer or 0 == TimerGetTimeout(udg_cocoonsTimer) then
        set udg_cocoonsTimer = CreateTimer() 
        call TimerStart(udg_cocoonsTimer, 0.05, true, function CocoonTimerCallback)
    endif

    set p = null
    set u = null
endfunction

function CreateSpellEffectCocoonDefault takes unit caster returns nothing
    call CreateSpellEffectCocoon(caster, udg_COCOON_UNITTYPEID, udg_COCOON_QUANTITY, udg_COCOON_SPAWN_UNITTYPEID, udg_COCOON_SPAWN_QUANTITY, udg_COCOON_DELAY, GetUnitX(caster), GetUnitY(caster), udg_COCOON_OFFSET)
endfunction
Настраивается с помощью аргументов к функции, а не глобалок. В карте которую прикрепляю есть пример. Это позволяет иметь разные конфигурации заклинания в одной карте. Например, разные цвета коконов или разные по силе паучки, в зависимости от паучихи.
Как импортировать. Включите копирование глобальных переменных в редакторе. Скопируйте триггер. Удостоверьтесь что все глобальные переменные последовали. Скопируйте скрипт JASS в скрипт карты (корень дерева триггеров). Настройка производится либо передачей аргументов "вручную", либо изменением глобальных переменных, которые начинаются с "COCOON_...". Все что начинаются с малых литер должны оставаться неприкасаемыми.
COCOON_DELAY - задержка перед появлением паучков, секунд.
COCOON_OFFSET - растояние от паучихи до кокона.
COCOON_QUANTITY - количество коконов за применение способности.
COCOON_SPAWN_QUANTITY - количество паучков.
COCOON_SPAWN_UNITTYPEID - тип юнита паучка.
COCOON_UNITTYPEID - тип юнита кокона.
Если у кого проблемы с этой версией заклинания, вот ещё одна для русской 1.26а.
прикреплены файлы
Zahanc #6 - 5 дней назад (отредактировано ) 2

» Освободители / Главная страница

Сыграл. В целом, нормально. Посмеялся над иконками из Казаков и Героев.
Мне кажется нужно больше особенностей. К примеру я считаю что нужно пойти дальше с улучшениями. Если один игрок улучшает войска, то это улучшение распространяется на оба лагеря.
Понравились переменные режимы стрельбы мортир.
FPS rate был низок.
Игра довольно простая. Я предлагаю убрать жёлтых сторожей с дорог вовсе. Или оставить, скажем, двух пехотинцев. Вместо этого, дать игрокам вызвать подкрепление, скажем один раз на этом этапе. Возможно дать предмет, боевой рожок с одним зарядом, как способ это представить.
Zahanc #7 - 1 неделю назад 0

» Осквернитель / Главная страница

Сегодня-завтра размещу первую главу для открытого тестирования.
Zahanc #8 - 2 недели назад 0

» WarCraft 3 / Странное поведение AI script

У меня были такие проблемы с 1.27 тоже.
Zahanc #9 - 2 недели назад 0

» WarCraft 3 / Получение точки применения способности ?

Да, он остался в памяти потому что он нужен в другой функции: SCOnDeathCallback
И затем удаляется когда он больше не нужен.
Попрошу модератора удалить оффтопик.
Zahanc #10 - 2 недели назад 0
Zahanc #11 - 2 недели назад 0

» WarCraft 3 / Получение точки применения способности ?

Каков контекст у этого всего? Буквально вчера написал заклинание AoE на точке.
/* SpellContaminate.j 1.0 */
globals
  constant integer CONTAMINATE = 'A601'
  constant integer CONTAMINATE_SUMMON = 'nvdl'
  constant real CONTAMINATE_AOE = 200.0
  constant real CONTAMINATE_DURATION = 16.0
  constant real CONTAMINATE_SUMMON_DURATION = 60.0
  constant real CONTAMINATE_UPDATE_TIMER_TIMEOUT = 2.0
  constant string CONTAMINATE_EFFECT = "Abilities\\Spells\\Undead\\UnholyAura\\UnholyAura.mdl"

  integer SCQuantity = 0
  effect array SCEffect
  integer array SCLevel
  location array SCLoc
  player array SCOwner 
  timer array SCTimerExpiration
endglobals

function SCOnDeathFilter takes nothing returns boolean
  local boolean isConvertable = false
  local unit u = GetDyingUnit()
  set isConvertable = not IsUnitType(u, UNIT_TYPE_UNDEAD) and not IsUnitType(u, UNIT_TYPE_MECHANICAL)
  return isConvertable and (SCQuantity > 0)
endfunction

function SCOnDeathCallback takes nothing returns nothing
  local integer i = 0
  local unit f = null
  local unit u = GetTriggerUnit()
  local location loc = GetUnitLoc(u)

  /* In case there are overlaping Contamination zones,
  make sure only one summon is created.
  Moreover, make sure only the oldest zone takes effect.*/
  loop
    exitwhen i >= SCQuantity or (f != null) 
    if DistanceBetweenPoints(loc, SCLoc[i]) <= (CONTAMINATE_AOE / 2 + CONTAMINATE_AOE / 2 * I2R(SCLevel[i])) then
      set f = CreateUnitAtLoc(SCOwner[i], CONTAMINATE_SUMMON, loc, GetUnitFacing(u))
      call SetUnitUseFood(f, false)
      call UnitAddType(f, UNIT_TYPE_SUMMONED)
      call UnitAddType(f, UNIT_TYPE_UNDEAD)
      call UnitApplyTimedLife(f, 'BTLF', CONTAMINATE_SUMMON_DURATION)
      call SetUnitExploded(f, true)

      call DestroyEffect(AddSpecialEffectLoc(CONTAMINATE_EFFECT, loc))
    endif
    set i = i + 1
  endloop

  call RemoveLocation(loc)
  set f = null
  set loc = null
  set u = null
endfunction

function SCOnCastFilter takes nothing returns boolean
  return CONTAMINATE == GetSpellAbilityId() 
endfunction

function SCTimerExpirationCallback takes nothing returns nothing
  local integer i = 0
  local timer t = GetExpiredTimer()
  local integer j = 0
  loop
    exitwhen i >= SCQuantity
    if t == SCTimerExpiration[i] then
      call RemoveLocation(SCLoc[i])
      call DestroyTimer(SCTimerExpiration[i])
      call DestroyEffect(SCEffect[i])

      /* Pull other instances down the stack,
      to preserve the creation order,
      that is relevant in resolving application conflicts. */
      set j = i + 1
      loop
        exitwhen j >= SCQuantity
	set SCEffect[j - 1] = SCEffect[j]
	set SCLevel[j - 1] = SCLevel[j]
	set SCLoc[j - 1] = SCLoc[j]
	set SCOwner[j - 1] = SCOwner[j]
	set j = j + 1
      endloop
      /* Accessing out of array size elements terminates the game,
      instead of returning null,
      hence the ugly patch that follows. */
      set SCQuantity = SCQuantity - 1
      set SCEffect[SCQuantity] = null
      set SCLevel[SCQuantity] = 0
      set SCLoc[SCQuantity] = null
      set SCOwner[SCQuantity] = null

      set t = null
      /* Assume each timer in the array is unique. */
      return
    endif
    set i = i + 1
  endloop
endfunction

function SCOnCastCallback takes nothing returns nothing
  local unit c = GetSpellAbilityUnit()
  local integer i = SCQuantity
  local location loc = null

  if i >= JASS_MAX_ARRAY_SIZE then
    return
  endif

  set loc = GetSpellTargetLoc()
  set SCEffect[i] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, loc)
  set SCLoc[i] = loc
  set SCOwner[i] = GetOwningPlayer(c)
  set SCLevel[i] = GetUnitAbilityLevel(c, CONTAMINATE)
  set SCTimerExpiration[i] = CreateTimer()
  call TimerStart(SCTimerExpiration[i], CONTAMINATE_DURATION, false, function SCTimerExpirationCallback)

  set SCQuantity = SCQuantity + 1

  set c = null
  set loc = null
endfunction

function initSpellContaminate takes nothing returns nothing
  local trigger t = CreateTrigger()
  local trigger t2 = CreateTrigger()

  call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
  call TriggerAddCondition(t, Condition(function SCOnCastFilter))
  call TriggerAddAction(t, function SCOnCastCallback)

  call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_DEATH)
  call TriggerAddCondition(t2, Condition(function SCOnDeathFilter))
  call TriggerAddAction(t2, function SCOnDeathCallback)

  set t = null
  set t2 = null
endfunction
/* end SpellContaminate.j */
  call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
  call TriggerAddCondition(t, Condition(function SCOnCastFilter))
  call TriggerAddAction(t, function SCOnCastCallback)
...
  set loc = GetSpellTargetLoc()
Хотя мне казалось что заклинания которые юнит поддерживает (channeling) тоже запускают "EVENT_PLAYER_UNIT_SPELL_CAST".
Zahanc #12 - 2 недели назад (отредактировано ) 3

» WarCraft 3 / Получение точки применения способности ?

constant native GetSpellTargetLoc           takes nothing returns location
native GetLocationX             takes location whichLocation returns real
native GetLocationY             takes location whichLocation returns real
Zahanc #13 - 2 недели назад (отредактировано ) 0

» WarCraft 3 / Странное поведение AI script

Значит они в атакующей группе. Я думал что может они остаются потому что количество юнитов в атакующей группе превышает 12, но перечитав скрипт не вижу такой проблемы.
+
О, они точно производятся ИИ? Или они создаются при инициализации карты?
+
Попробуйте ещё поменять количество начальных ресурсов, может быть. Я уже просто угадываю к этому моменту.
Zahanc #14 - 2 недели назад 0

» WarCraft 3 / Странное поведение AI script

Но они есть среди атакующих и "стражников". Может они просто стоят там и ждут своей очереди или что-то в этом роде? Хотя мне все ещё кажется что это скорее ошибка обновления.
По главному вопросу, я сам так и не нашел решения. Вероятно это ошибка в коде по ту сторону API. У меня были куда более странные проблемы.
Могу разве что посоветовать разделить базу на несколько владельцев.
Zahanc #15 - 2 недели назад 0

» WarCraft 3 / Странное поведение AI script

Да я тоже сталкивался с тем что ИИ посылает защитников в атаку. Насколько я смог понять это из-за того что ему кажется что его база под угрозой.
Никогда не сталкивался с лишними юнитами в защите, впрочем. Может просто не обновили скрипт в карте как полагается?
Zahanc #16 - 2 недели назад 0

» WarCraft 3 / Проблема с изменением архива кампании с Ladik's MPQ Editor.

Да действительно. Ladik's не создаёт необходимых записей в war3campaign.imp.
Может кто помочь с написанием Batch скрипта, который бы заполнял war3campaign.imp основываясь на дереве папок и файлов?
+ Впрочем, чем утруждаться со скриптами проще добавить записи в WE "вручную".
Zahanc #17 - 2 недели назад 0

» WarCraft 3 / Проблема с изменением архива кампании с Ladik's MPQ Editor.

listfile, да. На вид он тоже в порядке. Поэтому я спрашиваю есть ли какая-то ловушка с форматом listfile. Вроде порядка перечисления файлов.
Zahanc #18 - 2 недели назад 2

» WarCraft 3 / Проблема с изменением архива кампании с Ladik's MPQ Editor.

PT153,
Я думал это распространяется только на архивы игры, а не карты и кампании.
Я имею ввиду, об CASC говорят как о другом формате. Однако я мог открыть *.w3n как обычно.
Zahanc #19 - 2 недели назад 0

» WarCraft 3 / Ошибка при выборе рандомного игрока (Jass)

Это пример а не готовая наработка.
Zahanc #20 - 2 недели назад 0

» WarCraft 3 / Ошибка при выборе рандомного игрока (Jass)

Кстати есть функция ForcePickRandomPlayer. Например
function forceUsersFilter takes nothing returns boolean
  return PLAYER_SLOT_STATE_PLAYING == GetPlayerSlotState(GetFilterPlayer()) and MAP_CONTROL_USER == GetPlayerController(GetFilterPlayer())
endfunction

function getRandomPlayer takes nothing returns player
  local force f = CreateForce()
  call ForceEnumPlayers(f, Condition(forceUsersFilter))
  return ForcePickRandomPlayer(f)
endfunction
Не проверял.
Zahanc #21 - 2 недели назад 0

» WarCraft 3 / Ошибка при выборе рандомного игрока (Jass)

Были ли проверки в многопользовательском режиме? Может компьютер просто находит лишь одного играющего человека в однопользовательском режиме.
И что такое udg_AccEmpPlayer?
Zahanc #22 - 2 недели назад 0

» WarCraft 3 / Подскажите как проще всего написать рандом >покупку< героя

Я не знал про приём с умножением. Как это называется и как это работает?
И наверное это N*X - 1 а не N*X - N.
Zahanc #23 - 2 недели назад 1

» WarCraft 3 / Дамми спелл по типу "Буран"

Data - Options: Visible, Targeting Image
Data - Target Type: Point Target
Stats - Area of Effect: 200.0
Прикрепляю пример. Могу сделать периодический урон тоже если нужно.
прикреплены файлы
Zahanc #24 - 2 недели назад 0

» WarCraft 3 / Модель - странная штука. Вроде работает, а вроде и нет...

Используется ли модель как декорация? Если да, установлены ли вариации декорации в РО? В таком случае уберите вариации. Как основу используйте декорацию без вариаций, как указательный знак или факел.
Zahanc #25 - 2 недели назад (отредактировано ) 4

» WarCraft 3 / Warcraft 3 Custom Campaign Contest 2019

На создание Pit Lord, кампанию из двух карт, у меня ушел ровно месяц. Я занимался кампанией приблизительно 4 часа в день. Сообщаю чтобы участники могли соотнести себя.
Мне интересно посмотреть что получится. Поигрываю иногда в пользовательские кампании. Меня удручает что у девяти из десяти очень низкий уровень производства. Казалось бы, за пятнадцать лет можно было научиться, ан нет.
Zahanc #26 - 2 недели назад 0

» WarCraft 3 / ИИ использование способностей

Можно попробовать написать *.ai скрипт пустышку, как для кампаний. В конце концов должен же был компьютер уметь использовать Рёв в кампании.
Zahanc #27 - 2 недели назад 2

» WarCraft 3 / Дамми спелл по типу "Буран"

Это возможно. Нужно выставить нужные галки в одном из параметров "Канала" и удостовериться что установлен достаточно большой радиус действия.
Однако на сколько я помню невозможно затем в скрипте отследить всех юнитов которые попали в область. Придется самому считать от центра применения способности.
Zahanc #28 - 3 недели назад 0

» Повелитель Бездны / Главная страница

Обновлю по крайней мере английскую версию в феврале. Если дело пойдет гладко, то и русскую версию тоже.
Zahanc #29 - 3 недели назад 0

» WarCraft 3 / Галерея скриншотов ландшафта

Да, на снимках почти ничего не видно. Они здесь лишь как повод чтобы задать вопрос.
Как сделать классический уровень приятным? Такой уровень будет содержать обычные воду и утёсы. Я сам могу додуматься добавить густой туман и парочку новых декораций. И да, я читал статью Шурика и пару книжек на эту тему. Что ещё? Какова программа минимум для классического уровня?
BranaR,
Грубоватый интерфейс портит всё впечатление. Проходящие сквозь друг друга колонны на первом снимке и на некоторых других слегка не к месту мне кажется. Хотя это только мне так кажется, возможно.
В остальном, впечатляюще.
Zahanc #30 - 3 недели назад 0

» Осквернитель / Главная страница

Добавил заклинание Corpse Gas. Указанная дружественная нежить становится бомбой которая взрывается через 5 секунд. Урон зависит от здоровья дружественного юнита и уровня способности. Время отслеживается плавающим текстом.
globals 
  constant real SCG_DELAY = 5.0 
  constant real SCG_UPDATE_TIMEOUT = 0.1

  constant integer CORPSE_GAS = 'A600'

  unit array SCGCasters
  real array SCGDuration
  effect array SCGEffects
  integer array SCGLevel
  texttag array SCGIndicators
  unit array SCGTargets

  group SCGVictims
  integer SCGTargetsQuantity
endglobals 

function SCGOnExplosionCallback takes nothing returns nothing 
endfunction 

function spellCorpseGas takes unit c, unit t, integer lvl returns nothing
  local integer i = SCGTargetsQuantity
  local texttag indicator = null

  if (i >= JASS_MAX_ARRAY_SIZE) or (null == c) or (null == t) or (lvl < 1) then
    return
  endif


  set SCGCasters[i] = c
  set SCGEffects[i] = AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\TargetArtLumber\\TargetArtLumber.mdl"​, t, "origin")
  set SCGTargets[i] = t
  set SCGDuration[i] = SCG_DELAY
  set indicator = CreateTextTagUnitBJ(I2S(R2I(SCG_DELAY)), t, 0.0, 8.0, 100.0, 100.0, 100.0, 0)
  set SCGIndicators[i] = indicator
  set SCGLevel[i] = lvl
  set SCGTargetsQuantity = SCGTargetsQuantity + 1
endfunction 

function SCGOnCastCallback takes nothing returns nothing 
  local unit caster = GetSpellAbilityUnit() 

  local integer spellLevel = GetUnitAbilityLevel(caster, CORPSE_GAS) 

  call spellCorpseGas(caster, GetSpellTargetUnit(), spellLevel) 

  set caster = null 
endfunction 

function SCGUpdateCallback takes nothing returns nothing 
  local integer i = SCGTargetsQuantity
  local unit u = null
  local unit f = null
  local boolean mustBeDestroyed = false
  local real dmg = 0.0

  loop 
    exitwhen i <= 0
    set i = i - 1
    set u = SCGTargets[i] 
    if IsUnitAliveBJ(u) then
      /* update visuals */
      set SCGDuration[i] = SCGDuration[i] - SCG_UPDATE_TIMEOUT
      call SetTextTagTextBJ(SCGIndicators[i], I2S(R2I(SCGDuration[i])), 8.0)
      call SetTextTagPosUnitBJ(SCGIndicators[i], SCGTargets[i], 0.0)
      if SCGDuration[i] <= 2.0 then
        call SetTextTagColorBJ(SCGIndicators[i], 100.0, 0.0, 0.0, 0.0)
      endif
      /* end update visuals */

      /* explode when needed */
      if SCGDuration[i] <= 0.0 then 
	call GroupClear(SCGVictims)
	call GroupEnumUnitsInRangeCounted(SCGVictims, GetUnitX(u), GetUnitY(u), 512.0, null, 6)

	set dmg = (30.0 + 30.0 * I2R(SCGLevel[i])) * (GetUnitState(SCGTargets[i], UNIT_STATE_LIFE) / 300.0)

        call SetUnitExploded(SCGTargets[i], true)
        call UnitDamageTargetBJ(SCGCasters[i], SCGTargets[i], 300.0, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_DISEASE)
	call SetUnitExploded(SCGTargets[i], false)

	call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt​.mdl", SCGTargets[i], "origin"))
	loop
	  set f = FirstOfGroup(SCGVictims)
	  exitwhen null == f
	  if not IsUnitType(f, UNIT_TYPE_UNDEAD) and IsUnitAliveBJ(f) and GetUnitAbilityLevel(f, 'Avul') == 0 then
	    call UnitDamageTargetBJ(SCGCasters[i], f, dmg, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_DISEASE)
	    if dmg > 60.0 then
	      call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt​.mdl", f, "origin"))
	    endif
	  endif
	  call GroupRemoveUnit(SCGVictims, f)
	endloop
      endif 
      /* end explode if needed */
    endif 

    /* cleanup */
    set mustBeDestroyed = IsUnitDeadBJ(u) or SCGDuration[i] <= 0.0
    if mustBeDestroyed then 
      call DestroyTextTag(SCGIndicators[i])
      call DestroyEffect(SCGEffects[i])

      set SCGTargetsQuantity = SCGTargetsQuantity - 1

      set SCGCasters[i] = SCGCasters[SCGTargetsQuantity]
      set SCGDuration[i] = SCGDuration[SCGTargetsQuantity]
      set SCGEffects[i] = SCGEffects[SCGTargetsQuantity]
      set SCGIndicators[i] = SCGIndicators[SCGTargetsQuantity]
      set SCGLevel[i] = SCGLevel[SCGTargetsQuantity]
      set SCGTargets[i] = SCGTargets[SCGTargetsQuantity] 

      set SCGCasters[SCGTargetsQuantity] = null
      set SCGEffects[SCGTargetsQuantity] = null
      set SCGIndicators[SCGTargetsQuantity] = null
      set SCGTargets[SCGTargetsQuantity] = null 
    endif 
    /* end cleanup */
  endloop 

  set u = null 
  set f = null
endfunction 

function SCGOnCastFilter takes nothing returns boolean
  local boolean result = true 
  set result = CORPSE_GAS == GetSpellAbilityId() and result
  set result = GetSpellTargetUnit() != null and result
  set result = IsUnitType(GetSpellTargetUnit(), UNIT_TYPE_UNDEAD) and result
  return result
endfunction

function initSpellCorpseGas takes nothing returns nothing 
  local trigger t = CreateTrigger() 
  local timer updateTimer = CreateTimer()

  set SCGTargetsQuantity = 0
  set SCGVictims = CreateGroup()

  call TimerStart(updateTimer, SCG_UPDATE_TIMEOUT, true, function SCGUpdateCallback) 

  call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
  call TriggerAddCondition(t, Condition(function SCGOnCastFilter))	
  call TriggerAddAction(t, function SCGOnCastCallback) 
 
  set t = null 
endfunction 
прикреплены файлы
Zahanc #31 - 3 недели назад (отредактировано ) 0

» Осквернитель / Главная страница

Репозиторий Git на BitBucket. Использую скрипты чтобы паковать архив кампании. В будущем расширю чтобы упростить глобализацию.
git clone https://vladyslavbondatzohoeu@bitbucket.org/vladyslavbondatzohoeu/plaguebringergame.git
Zahanc #33 - 10 месяцев назад 0

» Осквернитель / Главная страница

Потерял исходники (опять). Осталось только то что на сайте. Выпуск откладывается.
Zahanc #34 - 10 месяцев назад 0

» WarCraft 3 / Вселенная WarCraft

Nosferoh,
Ну, они знакомы давно. Ещё Кенариус контактировал с минотаврами но Войны Древних, а таурены в своё время пытались поймать Малорна. Возможно, минотавры объединялись с Ночными Эльфами против кентавров.
Попрошу источники.
Zahanc #35 - 10 месяцев назад 0

» WarCraft 3 / Поясните белое пятно в сюжете игры

Разве в книгах от Кристи Голден этого нету?
Zahanc #36 - 10 месяцев назад 0

» WarCraft 3 / Пара элементарных вопросов

RikLine,
Можно отловить событие поражения для игрока или выход игрока.
Zahanc #37 - 10 месяцев назад 0

» WarCraft 3 / Пара элементарных вопросов

Нету функции возвращающей урон юнита.
Если очень нужно, придется прибегнуть к мемхаку или писать свою систему нанесения урона.
+
Возможно в новой версии игры ввели, не уверен. Не использую последнюю версию поскольку не могу заставить JNGP работать в таком случае.
Zahanc #38 - 11 месяцев назад 0

» Повелитель Бездны / Главная страница

Version 3.
Changelog.
  1. Replaced first three spells of Pit Lord.
  2. Fixed bug with optional quest in second map. Now only civilians count as sacrifices. Changed the reward also.

Добавлю русскую версию позже. Я потерял файлы локализации.
прикреплены файлы
Zahanc #39 - 11 месяцев назад 0

» Fa_losophy / XGMolution

Я так понял Raised предлагает сделать фильтрование ресурсов по тегам. Сейчас можно только выбрать все ресурсы содержащие один определённый тег.
Zahanc #40 - 11 месяцев назад 7

» Fa_losophy / XGMolution

Должен сказать что поиск по сайту слабый. Я попользовался им неделю как его выпустили, и с тех пор для поиска по сайту использую сторонние поисковики.
Zahanc #41 - 11 месяцев назад 4

» Дневник Сильваны / Как использовать все место на карте?

Нужно больше информации о том как манипулировать вниманием игрока. Как дать понять игроку куда идти? Как интересно спрятать тайники? Как создать ощущение пространства (обычно делается с помощью разницы высот)? Как донести тему местности (хотя это больше про эстетику).
Zahanc #42 - 11 месяцев назад (отредактировано ) 0

» WarCraft 3 / Галерея скриншотов ландшафта

Да, я почерпнул приём создания "темы" для игры прежде механик из литературы (Game Design Lenses, кажется). Что-то должно быть написано конкретно о дизайне уровней. Ищу дальше.
Zahanc #43 - 11 месяцев назад 0

» WarCraft 3 / Галерея скриншотов ландшафта

koloff,
То что Вы предлагаете имеет смысл для микродекоринга. Вопрос был:
Меня интересует именно механики, а не эстетика.
Например, как обыграть комнату с боссом? Где поставить тайники? Откуда должны нападать враги? И так далее. Избавиться от arbitrary geometry.
Zahanc #44 - 11 месяцев назад 0

» WarCraft 3 / Галерея скриншотов ландшафта

Немного не в тему, но я всё таки спрошу. Поделитесь какой литературой на тему дизайна уровней, пожалуйста. Меня интересует именно механики, а не эстетика. Пока что собираю отдельные рецепты по крупицам со всей Сети. Должно же быть что-то связное где-то.
Zahanc #45 - 11 месяцев назад 0

» Дневник Сильваны / Послушник

Мне нужен рескин гидры для кампании. Если вдруг ищите идеи.
Zahanc #46 - 11 месяцев назад 1

» Дневник Сильваны / Послушник

У меня тоже. Не суть.
Zahanc #47 - 11 месяцев назад 0
Zahanc #48 - 11 месяцев назад 1

» Дневник Сильваны / Послушник

Любопытно. По снимку, если бы не анимации, так на послушника вовсе не похоже.
Zahanc #49 - 11 месяцев назад 0

» WarCraft 3 / vJass: импортировать несколько скриптов.

Сделал так:
include "scriptA.j"
include "scriptB.j"
vJass и cJass включены. Предварительно добавил файлы в "D:\games\Jass New Gen Pack Rebuild\AdicHelper\lib". Я не могу хранить файлы в той же папке что и карта из-за того как устроен сборщик кампаний.
Заработало. Спасибо.
Zahanc #50 - 11 месяцев назад 0

» WarCraft 3 / vJass: импортировать несколько скриптов.

Да. Почему это важно?
+
Ещё включен сборщик кампаний, но это не должно иметь значение. К тому же, мне обязательно чтобы это работало со сборщиком.