Добавлен Zahanc,
опубликован
Далее идут заклинания для кампании Осквернитель. Возможно представленные версии устаревшие. Для более новых версий смотрите репозиторий 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 */
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Можно, но тогда код зависит от порядка в котором я создавал способности в РО. Это не JNGP. Насколько я вижу в оригинальном редакторе нет возможности указывать равкод.
+
Кстати в 1.30 появилась функция изменения статистики юнитов. Я сознательно избегаю её использования.