Далее идут заклинания для кампании Осквернитель. Возможно представленные версии устаревшие. Для более новых версий смотрите репозиторий Git.
git clone https://vladyslavbondatzohoeu@bitbucket.org/vladyslavbondatzohoeu/plaguebringergame.git

Amalgamation:

/* Begin SpellAmalgamation.j
Version: 1.0 */
globals
    boolexpr SACorpseGroupFilter = null
    constant integer AMALGAMATION = 'n605' 
    constant integer SA_CACHE_SIZE_MAX = 32
    constant integer SA_LIFE_BONUS_1 = 'A607' 
    constant integer SA_LIFE_BONUS_2 = 'A609' 
    constant integer SA_LIFE_BONUS_3 = 'A60A' 
    constant integer SA_LIFE_BONUS_4 = 'A60B' 
    constant integer SA_LIFE_BONUS_5 = 'A60C' 
    constant integer SA_LIFE_BONUS_6 = 'A60D' 
    constant integer SA_LIFE_BONUS_7 = 'A60E' 
    constant integer SA_MANA_BONUS_1 = 'A60F'
    constant integer SA_MANA_BONUS_2 = 'A60G'
    constant integer SA_MANA_BONUS_3 = 'A60H'
    constant integer SA_MANA_BONUS_4 = 'A60I'
    constant integer SA_MANA_BONUS_5 = 'A60J'
    constant integer SA_MANA_BONUS_6 = 'A60K'
    constant integer SA_MANA_BONUS_7 = 'A608'
    constant integer SUMMON_AMALGAMATION = 'A606'
    integer SACacheSize = 0
    integer SAInheritableUnitTypeIdQuantity = 0 
    integer SAQuantity = 0
    integer array SACacheAbilityId
    integer array SACacheUnitTypeId
    integer array SAInheritableAbilityId
    integer array SAInheritableUnitTypeId
    unit array SACaster
    unit array SASummon
endglobals

function SAOnCastFilter takes nothing returns boolean
    return SUMMON_AMALGAMATION == GetSpellAbilityId()
endfunction

function SAGetInheritedAbilityId takes integer corpseUnitTypeId returns integer
    local boolean break = false
    local integer inheritedAbilityId = 0
    local integer i = 0
    local integer j = 0
    local boolean cached = false
   
    if corpseUnitTypeId > 0 then

         set i = 0
         loop
	     exitwhen i >= SACacheSize or break 
	     if corpseUnitTypeId == SACacheUnitTypeId[i] then
	         set inheritedAbilityId = SACacheAbilityId[i]
		 set break = true
		 set cached = true
	     endif
	     set i = i + 1
	 endloop

         set i = 0
         loop
             exitwhen i >= SAInheritableUnitTypeIdQuantity or break 
             if corpseUnitTypeId == SAInheritableUnitTypeId[i] then
	         set inheritedAbilityId = SAInheritableAbilityId[i]
                 set break = true
	     endif
	     set i = i + 1
         endloop

         if not cached then
	      if (SACacheSize + 1) >= SA_CACHE_SIZE_MAX then
	          set j = 0
	          loop
	              exitwhen j >= SACacheSize
		      set SACacheUnitTypeId[j] = SACacheUnitTypeId[j + 1]
	              set SACacheAbilityId[j] = SACacheAbilityId[j + 1]
		      set j = j + 1
	          endloop
	          set SACacheSize = SACacheSize - 1
	      endif
	      set SACacheUnitTypeId[SACacheSize] = corpseUnitTypeId
	      set SACacheAbilityId[SACacheSize] = inheritedAbilityId
	      set SACacheSize = SACacheSize + 1
         endif
    endif

    return inheritedAbilityId 
endfunction

function SARegisterUnitTypeId takes integer unitTypeId, integer abilityId returns nothing
    set SAInheritableUnitTypeId[SAInheritableUnitTypeIdQuantity] = unitTypeId
    set SAInheritableAbilityId[SAInheritableUnitTypeIdQuantity] = abilityId
    set SAInheritableUnitTypeIdQuantity = SAInheritableUnitTypeIdQuantity + 1
endfunction

function SACorpseGroupFilterCallback takes nothing returns boolean
    return IsUnitDeadBJ(GetFilterUnit()) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)
endfunction

function CreateSpellEffectAmalgamation takes unit caster, integer summonUnitTypeId, real x, real y, real aoe returns nothing
    local group corpses = null 
    local integer amalgamationQuantity = SAQuantity
    local integer corpseUnitTypeId = 0
    local integer i = 0
    local integer j = amalgamationQuantity
    local unit amalgamation = null
    local unit corpse = null
    local integer casterCorpsesQuantity = 0
    local integer corpsesQuantity = 0
    local integer noncasterCorpsesQuantity = 0

    set aoe = RMinBJ(RMaxBJ(aoe, 32.0), 10000.0)

    if null == caster then
        return
    endif

    /* Ensure each caster can have only one amalgamation. */
    loop
        exitwhen i >= amalgamationQuantity
	if SACaster[i] == caster then
	    call KillUnit(SASummon[i])
	    set j = i
	endif
	set i = i + 1
    endloop
    /* End ensure. */

    set amalgamation = CreateUnit(GetOwningPlayer(caster), summonUnitTypeId, x, y, GetUnitFacing(caster))
    call SetUnitUseFood(amalgamation, false)
    call UnitAddType(amalgamation, UNIT_TYPE_SUMMONED)
    call UnitAddType(amalgamation, UNIT_TYPE_UNDEAD)
    call SetUnitExploded(amalgamation, true)

    /* Inherit abilities. */
    set corpses = CreateGroup()
    call GroupEnumUnitsInRange(corpses, x, y, aoe*0.5, SACorpseGroupFilter)
    loop
        set corpse = FirstOfGroup(corpses)
        exitwhen corpse == null
        set corpseUnitTypeId = GetUnitTypeId(corpse)

        call UnitAddAbility(amalgamation, SAGetInheritedAbilityId(corpseUnitTypeId))

	if GetUnitState(corpse, UNIT_STATE_MAX_MANA) >= 1.0 then
	    set casterCorpsesQuantity = casterCorpsesQuantity + 1
	endif

        set corpsesQuantity = corpsesQuantity + 1
	call GroupRemoveUnit(corpses, corpse)
	call RemoveUnit(corpse)
    endloop
    call DestroyGroup(corpses)
    set corpses = null

    set noncasterCorpsesQuantity = corpsesQuantity - casterCorpsesQuantity

    if 1 == casterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_MANA_BONUS_1)
    elseif 2 == casterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_MANA_BONUS_2)
    elseif 3 == casterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_MANA_BONUS_3)
    elseif 4 == casterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_MANA_BONUS_4)
    elseif 5 == casterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_MANA_BONUS_5)
    elseif 6 == casterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_MANA_BONUS_6)
    elseif casterCorpsesQuantity >= 7 then
        call UnitAddAbility(amalgamation, SA_MANA_BONUS_7)
    endif

    if 1 == noncasterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_LIFE_BONUS_1)
    elseif 2 == noncasterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_LIFE_BONUS_2)
    elseif 3 == noncasterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_LIFE_BONUS_3)
    elseif 4 == noncasterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_LIFE_BONUS_4)
    elseif 5 == noncasterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_LIFE_BONUS_5)
    elseif 6 == noncasterCorpsesQuantity then
        call UnitAddAbility(amalgamation, SA_LIFE_BONUS_6)
    elseif noncasterCorpsesQuantity >= 7 then
        call UnitAddAbility(amalgamation, SA_LIFE_BONUS_7)
    endif
    /* End inherit abilities. */

    set SACaster[j] = caster
    set SASummon[j] = amalgamation
    set amalgamation = null
    set SAQuantity = SAQuantity + 1
endfunction

function SAOnCastCallback takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local real targetX = GetSpellTargetX()
    local real targetY = GetSpellTargetY()

    call CreateSpellEffectAmalgamation(caster, AMALGAMATION, targetX, targetY, 512.0)

    set caster = null
endfunction

function InitSpellAmalgamation takes nothing returns nothing
    local trigger t0 = null
 
    /* Banish */
    call SARegisterUnitTypeId('hspt', 'ACbn')
    call SARegisterUnitTypeId('ospw', 'ACbn')
    call SARegisterUnitTypeId('edot', 'ACbn')
   
    /* Chain Lightning */
    call SARegisterUnitTypeId('hsor', 'ACcl')
    call SARegisterUnitTypeId('oshm', 'ACcl')
    call SARegisterUnitTypeId('nltl', 'ACcl')
    call SARegisterUnitTypeId('nthl', 'ACcl')
    call SARegisterUnitTypeId('nstw', 'ACcl')
    
    /* Death Coil */
    call SARegisterUnitTypeId('unec', 'ACdc')
    call SARegisterUnitTypeId('nbld', 'ACdc')
    call SARegisterUnitTypeId('nsra', 'ACdc')
    call SARegisterUnitTypeId('nsrh', 'ACdc')
    call SARegisterUnitTypeId('nsrw', 'ACdc')
       
    /* Devour Magic */
    call SARegisterUnitTypeId('edry', 'ACde')
       
    call SARegisterUnitTypeId('npfl', 'ACde')
    call SARegisterUnitTypeId('nfel', 'ACde')
    call SARegisterUnitTypeId('npfm', 'ACde')

    /* Frenzy */
    call SARegisterUnitTypeId('ogru', 'Afzy')
    call SARegisterUnitTypeId('ugho', 'Afzy')
    call SARegisterUnitTypeId('edoc', 'Afzy')
       
    /* Frost Armor */
    call SARegisterUnitTypeId('nnsw', 'ACfa')
       
    call SARegisterUnitTypeId('nwiz', 'ACfa')
    call SARegisterUnitTypeId('nwzr', 'ACfa')
    call SARegisterUnitTypeId('nwzg', 'ACfa')

    /* Frost Nova */
    call SARegisterUnitTypeId('nnrg', 'ACfn')
    call SARegisterUnitTypeId('nwzd', 'ACfa')
       
    /* Healing Wave */
    call SARegisterUnitTypeId('hmpr', 'AChv')
    call SARegisterUnitTypeId('odoc', 'AChv')
    call SARegisterUnitTypeId('nfre', 'AChv')
    call SARegisterUnitTypeId('nmrv', 'AChv')
    call SARegisterUnitTypeId('ndtp', 'AChv')
    call SARegisterUnitTypeId('ndth', 'AChv')
    call SARegisterUnitTypeId('nrzm', 'AChv')
    call SARegisterUnitTypeId('nsqo', 'AChv')
       
    /* Hex */
    call SARegisterUnitTypeId('ohun', 'AChx')
    call SARegisterUnitTypeId('nsty', 'AChx')
    call SARegisterUnitTypeId('nsat', 'AChx')
    call SARegisterUnitTypeId('nsts', 'AChx')
    call SARegisterUnitTypeId('ndqn', 'AChx')
    call SARegisterUnitTypeId('ndqv', 'AChx')
    call SARegisterUnitTypeId('ndqt', 'AChx')
       
    /* Howl of Terror */
    call SARegisterUnitTypeId('nowb', 'Acht')
    call SARegisterUnitTypeId('nowe', 'Acht')
    call SARegisterUnitTypeId('nohk', 'Acht')
    call SARegisterUnitTypeId('nfgu', 'Acht')
    call SARegisterUnitTypeId('nfgb', 'Acht')
    call SARegisterUnitTypeId('nfov', 'Acht')
       
    /* Silence */
    call SARegisterUnitTypeId('ndqs', 'Acsi')
    call SARegisterUnitTypeId('ndqp', 'Acsi')
    call SARegisterUnitTypeId('nstl', 'Acsi')
    call SARegisterUnitTypeId('nsth', 'Acsi')
       
    /* Shockwave */
    call SARegisterUnitTypeId('hkni', 'ACsh')
    call SARegisterUnitTypeId('otau', 'ACsh')
    call SARegisterUnitTypeId('nbal', 'ACsh')
    call SARegisterUnitTypeId('ncks', 'ACsh')
    call SARegisterUnitTypeId('ncnk', 'ACsh')
    call SARegisterUnitTypeId('njgb', 'ACsh')
    call SARegisterUnitTypeId('njga', 'ACsh')
       
    /* Sleep */
    call SARegisterUnitTypeId('ndtr', 'ACsl')
    call SARegisterUnitTypeId('ndtt', 'ACsl')
    call SARegisterUnitTypeId('ndtb', 'ACsl')
    call SARegisterUnitTypeId('ndtw', 'ACsl')
    call SARegisterUnitTypeId('ndmu', 'ACsl')
    call SARegisterUnitTypeId('nzom', 'ACsl')
       
    /* Slam */
    call SARegisterUnitTypeId('okod', 'ACtc')
    call SARegisterUnitTypeId('uabo', 'ACtc')
    call SARegisterUnitTypeId('emtg', 'ACtc')
    call SARegisterUnitTypeId('nfra', 'ACtc')
    call SARegisterUnitTypeId('nsgb', 'ACtc')
    call SARegisterUnitTypeId('nogr', 'ACtc')
    call SARegisterUnitTypeId('nomg', 'ACtc')
    call SARegisterUnitTypeId('nogl', 'ACtc')
    call SARegisterUnitTypeId('nrzg', 'ACtc')
       
    /* Slow */
    call SARegisterUnitTypeId('nmcf', 'ACsw')
    call SARegisterUnitTypeId('nmdb', 'ACsw')
    call SARegisterUnitTypeId('nmtw', 'ACsw')
    call SARegisterUnitTypeId('nmsn', 'ACsw')
    call SARegisterUnitTypeId('nmsc', 'ACsw')
    call SARegisterUnitTypeId('nmrl', 'ACsw')
    call SARegisterUnitTypeId('nmrr', 'ACsw')
    call SARegisterUnitTypeId('nmpg', 'ACsw')
    call SARegisterUnitTypeId('nmfs', 'ACsw')
    call SARegisterUnitTypeId('nmrm', 'ACsw')
    call SARegisterUnitTypeId('nmmu', 'ACsw')
    call SARegisterUnitTypeId('opeo', 'ACsw')
    call SARegisterUnitTypeId('hpea', 'ACsw')
    call SARegisterUnitTypeId('nkob', 'ACsw')
    call SARegisterUnitTypeId('nkog', 'ACsw')
    call SARegisterUnitTypeId('nkol', 'ACsw')
    call SARegisterUnitTypeId('n601', 'ACsw')
    call SARegisterUnitTypeId('nkot', 'ACsw')
       
    /* Carrion Swarm */
    call SARegisterUnitTypeId('ucry', 'ACca')
    call SARegisterUnitTypeId('nnwq', 'ACca')
    call SARegisterUnitTypeId('nnws', 'ACca')

    /* Spiked Shell */
    call SARegisterUnitTypeId('hfoo', 'ANth')
    call SARegisterUnitTypeId('nhyc', 'ANth')
    call SARegisterUnitTypeId('ntrh', 'ANth')
    call SARegisterUnitTypeId('ntrs', 'ANth')
    call SARegisterUnitTypeId('ntrt', 'ANth')
    call SARegisterUnitTypeId('ntrg', 'ANth')
    call SARegisterUnitTypeId('ntrd', 'ANth')
    call SARegisterUnitTypeId('nspd', 'ANth')
    call SARegisterUnitTypeId('nnwa', 'ANth')
    call SARegisterUnitTypeId('nnwl', 'ANth')
    call SARegisterUnitTypeId('nnwr', 'ANth')
   
    set SACorpseGroupFilter = Condition(function SACorpseGroupFilterCallback)

    set t0 = CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ(t0, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t0, Condition(function SAOnCastFilter))
    call TriggerAddAction(t0, function SAOnCastCallback)

    set t0 = null
endfunction
/* End SpellAmalgamation.j */

Contaminate:

/* SpellContaminate.j 1.1 */
globals
  constant integer CONTAMINATE = 'A601'
  constant integer CONTAMINATE_SUMMON_1 = 'n602'
  constant integer CONTAMINATE_SUMMON_2 = 'n603'
  constant integer CONTAMINATE_SUMMON_3 = 'n604'
  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\\Orc\\TrollBerserk\\TrollBeserkerTarget.mdl"
  constant string CONTAMINATE_EFFECT_SUMMON = "Abilities\\Spells\\Orc\\Devour\\DevourEffectArt.mdl"
 
  constant integer SC_MAX_EFFECTS_PER_INSTANCE = 16 

  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)
  set u = null
  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)
  local integer summonUnitTypeId = CONTAMINATE_SUMMON_1

  /* 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 then
      if SCLevel[i] >= 3 then
        set summonUnitTypeId = CONTAMINATE_SUMMON_3
      elseif SCLevel[i] == 2 then
        set summonUnitTypeId = CONTAMINATE_SUMMON_2
      else
        set summonUnitTypeId = CONTAMINATE_SUMMON_1
      endif
      set f = CreateUnitAtLoc(SCOwner[i], summonUnitTypeId, 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_SUMMON, 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
  local integer k = 0
  loop
    exitwhen i >= SCQuantity
    if t == SCTimerExpiration[i] then
      call RemoveLocation(SCLoc[i])
      call DestroyTimer(SCTimerExpiration[i])
      set k = 0
      loop
        exitwhen k >= SC_MAX_EFFECTS_PER_INSTANCE
	call DestroyEffect(SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + k])
	set k = k + 1
      endloop

      /* Pull other instances down the stack,
      to preserve the creation order,
      that is relevant in resolving application conflicts. */
      set j = i 
      loop
        exitwhen j >= SCQuantity
	set k = 0
	loop
	  exitwhen k >= SC_MAX_EFFECTS_PER_INSTANCE
	  set SCEffect[j*SC_MAX_EFFECTS_PER_INSTANCE + k] = SCEffect[(j + 1)*SC_MAX_EFFECTS_PER_INSTANCE + k]
	  set k = k + 1
	endloop
	set SCLevel[j] = SCLevel[j + 1]
	set SCLoc[j] = SCLoc[j + 1]
	set SCOwner[j] = SCOwner[j + 1]
	set SCTimerExpiration[j] = SCTimerExpiration[j + 1]
	set j = j + 1
      endloop
      set SCQuantity = SCQuantity - 1

      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
  local location eLoc = null
  local real x = GetSpellTargetX()
  local real y = GetSpellTargetY()
  local integer spellRank = GetUnitAbilityLevel(c, GetSpellAbilityId())
  local real aoe = CONTAMINATE_AOE 
  local integer effectsQuantity = 0

  if i >= JASS_MAX_ARRAY_SIZE/SC_MAX_EFFECTS_PER_INSTANCE - 1 then
    return
  endif

  set loc = GetSpellTargetLoc()
  set eLoc = Location(x, y)

  call MoveLocation(eLoc, x + aoe/2.0*1.0, y + aoe/2.0*0.0)
  set SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + 0] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, eLoc)
  call MoveLocation(eLoc, x + aoe/2.0*0.7, y + aoe/2.0*0.7)
  set SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + 1] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, eLoc)
  call MoveLocation(eLoc, x + aoe/2.0*0.0, y + aoe/2.0*1.0)
  set SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + 2] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, eLoc)
  call MoveLocation(eLoc, x + aoe/2.0*(-0.7), y + aoe/2.0*0.7)
  set SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + 3] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, eLoc)
  call MoveLocation(eLoc, x + aoe/2.0*(-1.0), y + aoe/2.0*0.0)
  set SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + 4] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, eLoc)
  call MoveLocation(eLoc, x + aoe/2.0*(-0.7), y + aoe/2.0*(-0.7))
  set SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + 5] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, eLoc)
  call MoveLocation(eLoc, x + aoe/2.0*0.0, y + aoe/2.0*(-1.0))
  set SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + 6] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, eLoc)
  call MoveLocation(eLoc, x + aoe/2.0*0.7, y + aoe/2.0*(-0.7))
  set SCEffect[i*SC_MAX_EFFECTS_PER_INSTANCE + 7] = AddSpecialEffectLoc(CONTAMINATE_EFFECT, eLoc) 
  
  call RemoveLocation(eLoc)
  set eLoc = null

  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_EFFECT)
  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 */

Corpse Gas:

/* SpellCorpseGas.j 1.1 */
globals
  constant integer CORPSE_GAS = 'A600'

  constant real SCG_DELAY = 5.0
  constant real SCG_UPDATE_TIMEOUT = 0.1
  constant string SCGEffectExplosion = "war3campImported\\assets\\Soul_Sorcery\\Soul_Blast.mdl"
  constant string SCGEffectImpact = "war3campImported\\assets\\Recolored_Mana_Burn\\Mana_Burn_Soul.mdl" 
  constant string SCGEffectIndicator = "war3campImported\\assets\\Soul_Sorcery\\Soul_Curse.mdx"
  effect array SCGEffects
  group SCGVictims
  integer SCGTargetsQuantity
  integer array SCGLevel
  real array SCGDuration
  texttag array SCGIndicators
  unit array SCGCasters
  unit array SCGTargets
endglobals

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

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


  set SCGCasters[i] = c
  set SCGDuration[i] = SCG_DELAY
  set SCGEffects[i] = AddSpecialEffectTarget(SCGEffectIndicator, t, "origin")
  set SCGIndicators[i] = CreateTextTagUnitBJ(I2S(R2I(SCG_DELAY)), t, 0.0, 8.0, 100.0, 100.0, 100.0, 0)
  set SCGLevel[i] = lvl
  set SCGTargets[i] = t

  set SCGTargetsQuantity = SCGTargetsQuantity + 1
endfunction

function SCGDestructibleCallback takes nothing returns nothing
    call SetDestructableLife( GetEnumDestructable(), ( GetDestructableLife(GetEnumDestructable()) - 50.00 ) )
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 boolean mustBeDestroyed = false
  local boolean isVictimAffected = false
  local integer i = SCGTargetsQuantity
  local real dmg = 0.0
  local texttag tt = null
  local texttag tt2 = null
  local unit f = null
  local unit u = null
  local location loc = null
  local integer victimsQuantity = 0

  loop
    exitwhen i <= 0
    set i = i - 1
    set u = SCGTargets[i]
    if IsUnitAliveBJ(u) then
      /* track duration */
      set SCGDuration[i] = SCGDuration[i] - SCG_UPDATE_TIMEOUT
      if SCGDuration[i] <= 2.0 then
        call SetTextTagColorBJ(tt, 100.0, 0.0, 0.0, 0.0)
      endif
      /* end track duration */

      /* update visuals */
      set tt = SCGIndicators[i]
      call SetTextTagTextBJ(tt, I2S(R2I(SCGDuration[i])), 8.0)
      call SetTextTagPosUnitBJ(tt, u, 0.0)
      /* 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(u, UNIT_STATE_LIFE) / 300.0)
	loop
	  set f = FirstOfGroup(SCGVictims)
	  exitwhen null == f
	  set isVictimAffected = not IsUnitType(f, UNIT_TYPE_UNDEAD) and IsUnitAliveBJ(f) and GetUnitAbilityLevel(f, 'Avul') == 0
	  if isVictimAffected then
	    call UnitDamageTargetBJ(SCGCasters[i], f, dmg, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_DISEASE)
	    call DestroyEffect(AddSpecialEffectTarget(SCGEffectImpact, f, "origin"))
	    set victimsQuantity = victimsQuantity + 1
	  endif
	  call GroupRemoveUnit(SCGVictims, f)
	endloop

        set loc = GetUnitLoc(u)
        call EnumDestructablesInCircleBJ(256.0, loc, function SCGDestructibleCallback)

        /* indicate damage */
        set tt2 = CreateTextTagLocBJ(I2S(R2I(dmg) * victimsQuantity), loc, 8.00, 10.00, 100, 34.00, 0.00, 0 )
        call SetTextTagPermanentBJ(tt2, false)
        call SetTextTagFadepointBJ(tt2, 1.00)
        call SetTextTagLifespanBJ(tt2, 2.00)
        /* end indicate damage */

	call DestroyEffect(AddSpecialEffectLoc(SCGEffectExplosion, loc))
	call RemoveLocation(loc)

        call SetUnitExploded(u, true)
	
        call UnitDamageTargetBJ(SCGCasters[i], u, 300.0, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_DISEASE)
	call SetUnitExploded(u, false)
      endif
      /* end explode if needed */
    endif

    /* cleanup */
    set mustBeDestroyed = IsUnitDeadBJ(u) or IsUnitHidden(u) or SCGDuration[i] <= 0.0
    if mustBeDestroyed then
      call DestroyEffect(SCGEffects[i])
      call DestroyTextTag(SCGIndicators[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 f = null
  set tt = null
  set tt2 = null 
  set u = null
  set loc = null
endfunction

function SCGOnCastFilter takes nothing returns boolean
  local unit c = GetSpellAbilityUnit()
  local unit t = GetSpellTargetUnit()
  local boolean result = true

  set result = CORPSE_GAS == GetSpellAbilityId() and result
  set result = t != null and result
  set result = IsUnitType(t, UNIT_TYPE_UNDEAD) and result
  set result = GetOwningPlayer(t) == GetOwningPlayer(c) and result
  return result
endfunction

function InitSpellCorpseGas takes nothing returns nothing
  local trigger t = CreateTrigger()

  set SCGTargetsQuantity = 0
  set SCGVictims = CreateGroup()

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

  call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
  call TriggerAddCondition(t, Condition(function SCGOnCastFilter))
  call TriggerAddAction(t, function SCGOnCastCallback)

  set t = null
endfunction
/* End SpellCorpseGas.j */

Extinguish Life:

/* Begin SpellExtinguishLife.j
Version: 1.0 */
globals
    constant integer EXTINGUISH_LIFE = 'A605'

    constant string SEL_EFFECT_CASTER = "Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl"
    constant string SEL_EFFECT_IMPACT = "war3campImported\\assets\\Recolored_Mana_Burn\\Mana_Burn_Unholy.mdl"

    boolexpr SELUndeadGroupFilter = null
    player SELLastOwner = null
endglobals

function SELOnCastFinishFilter takes nothing returns boolean
    return EXTINGUISH_LIFE == GetSpellAbilityId() and IsUnitDeadBJ(GetSpellTargetUnit())
endfunction

function SELOnCastFinishCallback takes nothing returns nothing
    local effect e = null 
    local unit caster = GetSpellAbilityUnit()
    local real possibleMana = 50.0 + 50.0*I2R(GetUnitAbilityLevel(caster, GetSpellAbilityId()))
    call SetUnitState(caster, UNIT_STATE_MANA, GetUnitState(caster, UNIT_STATE_MANA) + possibleMana)
    set e = AddSpecialEffectTarget(SEL_EFFECT_CASTER, caster, "origin")
    call DestroyEffect(e)
    set e = null
    set caster = null
endfunction

function SELUndeadGroupFilterCallback takes nothing returns boolean
    local unit f = GetFilterUnit()
    local boolean result = false

    set result = SELLastOwner == GetOwningPlayer(f) and IsUnitType(f, UNIT_TYPE_UNDEAD)

    set f = null
    return result
endfunction

function CreateSpellEffectExtinguishLife takes unit caster, integer spellRank, unit target, real damage returns nothing
    local effect e = null
    local group g = CreateGroup()
    local player owner = GetOwningPlayer(caster)
    local real totalDamage = damage
    local real bonusDamage = 0.0
    local unit f = null

    call GroupEnumUnitsInRange(g, GetUnitX(target), GetUnitY(target), 512.0, null)
    loop
        set f = FirstOfGroup(g)
        exitwhen null == f 

        if owner == GetOwningPlayer(f) and IsUnitType(f, UNIT_TYPE_UNDEAD) and IsUnitAliveBJ(f) then
	    set bonusDamage = bonusDamage + 16.0

       	    set e = AddSpecialEffectTarget(SEL_EFFECT_IMPACT, f, "origin")
            call DestroyEffect(e)
	endif

	call GroupRemoveUnit(g, f)
    endloop
    set e = null
    set owner = null

    call DestroyGroup(g)
    set g = null

    set totalDamage = damage + RMaxBJ(bonusDamage, I2R(100*spellRank))
    call UnitDamageTargetBJ(caster, target, totalDamage, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL)
endfunction

function SELOnCastFilter takes nothing returns boolean
    return (EXTINGUISH_LIFE == GetSpellAbilityId()) and IsUnitAliveBJ(GetSpellTargetUnit())
endfunction

function SELOnCastCallback takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local real damageAmount = 100.0
    call CreateSpellEffectExtinguishLife(caster, GetUnitAbilityLevel(caster, GetSpellAbilityId()), GetSpellTargetUnit(), damageAmount)
    set caster = null
endfunction

function InitSpellExtinguishLife takes nothing returns nothing
    local trigger t0 = null
    local trigger t1 = null

    set SELUndeadGroupFilter = Condition(function SELUndeadGroupFilterCallback)

    set t0 = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t0, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t0, Condition(function SELOnCastFilter))
    call TriggerAddAction(t0, function SELOnCastCallback)
    
    set t1 = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_SPELL_FINISH)
    call TriggerAddCondition(t1, Condition(function SELOnCastFinishFilter))
    call TriggerAddAction(t1, function SELOnCastFinishCallback)

    set t0 = null
    set t1 = null
endfunction
/* End SpellExtinguishLife.j */

Void Shield:

/* SpellVoidShield.j 1.0 */
globals
  constant string VOID_SHIELD_EFFECT_TARGET = "war3campImported\\assets\\JetFangInferno\\DarkVoid.mdx"
  constant string VOID_SHIELD_EFFECT_IMPACT = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdx"
  constant integer VOID_SHIELD = 'A602'
  constant real VOID_SHIELD_DURATION = 30.0

  effect array SVSEffects
  real array SVSTargetMinLife
  timer array SVSTimerDuration
  trigger array SVSDamageTriggers
  unit array SVSCasters
  unit array SVSTargets

  trigger SVSDamageTrigger = null
  group SVSTargetsGroup = null
  integer SVSQuantity = 0
endglobals

function SVSDestroyEffectByIndex takes integer i returns nothing
  local boolean uniqueTarget = true 
  local integer j = 0
  local location targetLoc = null
  
  loop
    exitwhen j >= SVSQuantity or (not uniqueTarget)
    if SVSTargets[j] == SVSTargets[i] and i != j then
      set uniqueTarget = false
      call EnableTrigger(SVSDamageTriggers[j])
    endif
    set j = j + 1
  endloop

  if uniqueTarget then
    call GroupRemoveUnit(SVSTargetsGroup, SVSTargets[i])
  endif

  set SVSQuantity = SVSQuantity - 1
  set targetLoc = GetUnitLoc(SVSTargets[i])
  call SetUnitPositionLoc(SVSCasters[i], targetLoc)
  call ShowUnit(SVSCasters[i], true)

  call DestroyEffect(SVSEffects[i])
  set SVSEffects[i] = SVSEffects[SVSQuantity]
  set SVSTargetMinLife[i] = SVSTargetMinLife[SVSQuantity]
  set SVSCasters[i] = SVSCasters[SVSQuantity]

  call TriggerClearActions(SVSDamageTriggers[i])
  call TriggerClearConditions(SVSDamageTriggers[i])
  call DestroyTrigger(SVSDamageTriggers[i])
  set SVSDamageTriggers[i] = SVSDamageTriggers[SVSQuantity]

  set SVSTargets[i] = SVSTargets[SVSQuantity]
  call DestroyTimer(SVSTimerDuration[i])
  set SVSTimerDuration[i] = SVSTimerDuration[SVSQuantity]

  set SVSEffects[SVSQuantity] = null
  set SVSTargetMinLife[SVSQuantity] = 0.0
  set SVSCasters[SVSQuantity] = null
  set SVSDamageTriggers[SVSQuantity] = null
  set SVSTargets[SVSQuantity] = null
  set SVSTimerDuration[SVSQuantity] = null

  call RemoveLocation(targetLoc)
  set targetLoc = null


endfunction

function SVSOnDeathFilter takes nothing returns boolean
  return IsUnitInGroup(GetDyingUnit(), SVSTargetsGroup)
endfunction

function SVSOnDeathCallback takes nothing returns nothing
  local unit u = GetDyingUnit()
  local integer i = 0
  loop
    exitwhen i >= SVSQuantity 
    if u == SVSTargets[i] then
      call SVSDestroyEffectByIndex(i)
      set u = null
      return
    elseif u == SVSCasters[i] then
      call SetUnitPosition(u, GetUnitX(SVSTargets[i]), GetUnitY(SVSTargets[i]))
      call SVSDestroyEffectByIndex(i)
    endif
    set i = i + 1
  endloop
  set u = null
endfunction

function SVSOnDamageFilter takes nothing returns boolean
  return IsUnitInGroup(GetTriggerUnit(), SVSTargetsGroup) 
endfunction

function SVSOnDamageCallback takes nothing returns nothing
  local effect e = null
  local integer i = 0
  local real dmg = GetEventDamage()
  local trigger trg = GetTriggeringTrigger()
  local unit c = null
  local unit f = GetEventDamageSource()
  local unit t = GetTriggerUnit()
  local real fx = GetUnitX(f)
  local real fy = GetUnitY(f)
  local real tx = GetUnitX(t)
  local real ty = GetUnitY(t)
  local real distance = SquareRoot((tx - fx)*(tx - fx) + (ty - fy)*(ty - fy))
  local real ex = 0.0 
  local real ey = 0.0 
  
  loop
    exitwhen i >= SVSQuantity or (c != null)
    if trg == SVSDamageTriggers[i] then
      set c = SVSCasters[i]
    else
      set i = i + 1
    endif
  endloop

  /* Game version: 1.30.4 */
  call BlzSetEventDamage(0.0)
  /* End game version: 1.30.4 */

  call SetUnitPosition(c, GetUnitX(t), GetUnitY(t))
    /* Use damage instead of stat modification,
    to ensure the killer gets the credit. */
  if f != c then
    call UnitDamageTargetBJ(f, c, dmg, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL)
  endif
  if IsUnitDeadBJ(t) or IsUnitDeadBJ(c) then
    call SVSDestroyEffectByIndex(i)
  else
    if (GetUnitState(t, UNIT_STATE_LIFE) - dmg - 1.0) <= SVSTargetMinLife[i] then
      call SetUnitState(t, UNIT_STATE_LIFE, SVSTargetMinLife[i])
    endif
  endif

  if not IsUnitHidden(f) and not IsUnitHidden(t) then
    set ex = tx + (fx - tx)/distance*50.0
    set ey = ty + (fy - ty)/distance*50.0
    set e = AddSpecialEffect(VOID_SHIELD_EFFECT_IMPACT, ex, ey)
    call DestroyEffect(e)
  endif

  set e = null
  set trg = null
  set f = null
  set t = null
endfunction

function SVSTimerDurationCallback takes nothing returns nothing
  local timer t = GetExpiredTimer()
  local integer i = 0

  loop
    exitwhen i >= SVSQuantity
    if t == SVSTimerDuration[i] then
      call SVSDestroyEffectByIndex(i)
    endif
    set i = i + 1
  endloop

  call DestroyTimer(t)
  set t = null
endfunction

function SVSOnCastFilter takes nothing returns boolean
  return VOID_SHIELD == GetSpellAbilityId() and GetSpellTargetUnit() != null
endfunction

function SVSOnCastCallback takes nothing returns nothing
  local trigger trg = null
  local unit c = GetSpellAbilityUnit()
  local unit t = GetSpellTargetUnit()
  local integer i = 0 
  
  if SVSQuantity >= JASS_MAX_ARRAY_SIZE then
    return
  endif
  set i = SVSQuantity

  call ShowUnit(c, false)
  
  set trg = CreateTrigger()
  /*set trg = SVSDamageTrigger*/
  call TriggerRegisterUnitEvent(trg, t, EVENT_UNIT_DAMAGED)
  call TriggerAddCondition(trg, Condition(function SVSOnDamageFilter))
  call TriggerAddAction(trg, function SVSOnDamageCallback)

  /* If the target is already under the effect of another void shield,
  then turn off the effect of this new void shield,
  until the older effect expires or is canceled. 
  See SVSDestroyEffectByIndex.*/
  if IsUnitInGroup(t, SVSTargetsGroup) then
    call DisableTrigger(trg)
  endif

  set SVSDamageTriggers[i] = trg
  set SVSCasters[i] = c
  set SVSTargetMinLife[i] = RMaxBJ(GetUnitState(t, UNIT_STATE_LIFE), 4.0)
  set SVSTargets[i] = t
  set SVSTimerDuration[i] = CreateTimer()
  call TimerStart(SVSTimerDuration[i], VOID_SHIELD_DURATION, false, function SVSTimerDurationCallback)
  call GroupAddUnit(SVSTargetsGroup, t)
  set SVSEffects[i] = AddSpecialEffectTarget(VOID_SHIELD_EFFECT_TARGET, t, "overhead")

  set SVSQuantity = SVSQuantity + 1

  set c = null
  set t = null
  set trg = null
endfunction

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

  set SVSTargetsGroup = CreateGroup()
  set SVSDamageTrigger = CreateTrigger()

  call TriggerAddCondition(SVSDamageTrigger, Condition(function SVSOnDamageFilter))
  call TriggerAddAction(SVSDamageTrigger, function SVSOnDamageCallback)

  call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
  call TriggerAddCondition(t, Condition(function SVSOnCastFilter))
  call TriggerAddAction(t, function SVSOnCastCallback)

  set t2 = CreateTrigger()
  call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_DEATH)
  call TriggerAddCondition(t2, Condition(function SVSOnDeathFilter))
  call TriggerAddAction(t2, function SVSOnDeathCallback)

  set t = null
  set t2 = null
endfunction
/* End SpellVoidShield.j */
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
23
5 лет назад
0
какой ужасны костыль =) и указывать равкод если мы можем его нумеровать хендл с прирост с оригинала
0
22
5 лет назад
0
pro100master,
Можно, но тогда код зависит от порядка в котором я создавал способности в РО. Это не JNGP. Насколько я вижу в оригинальном редакторе нет возможности указывать равкод.
+
Кстати в 1.30 появилась функция изменения статистики юнитов. Я сознательно избегаю её использования.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.