Zephyr Contest #15 - Model Based

Status
Not open for further replies.
Level 8
Joined
Aug 27, 2012
Messages
349
I had a question about this part:

Is there a good documentation and are there enough configurable variables to fit the needs of different user?

Do I need to make it configurable for a different model? For example, I want to make my spell sync with the animation timing of the model that I chose. That means if someone were to use the spell with a different model it would look off due to wrong animation timings. Will this affect the score, since the whole purpose of this contest is to make a spell for a specific model.
 

KILLCIDE

Arena Moderator
Level 36
Joined
Jul 22, 2015
Messages
3,487
Hopefully I finish it by the 27th then! I got started on it tonight at the cost of not doing my homework for school :D I will be using General Frank's Lord Hyperion for my entry!

FlameBurst.gif
 
Level 8
Joined
Feb 1, 2015
Messages
128
@Marjosh38 have you checked your backups folder? In JNGP there is a folder with it -- and in your Warcraft III directory, too, in the maps folder, there is also always one backed up that was tested the last with editor. Maybe you're lucky and can get most of the work.

Yeh, Rheiko \o/.

Yeah I'd just checked it, but in warcraft III directory seems like my save map when it's not yet done. And because also my fault, my progress that I'd made comes into useless :(
 

NEL

NEL

Level 6
Joined
Mar 6, 2017
Messages
113
Description.png


JASS:
//
//
//        [code=jass] Prison v1.1
//            by nel
//
//
//===========================================================================
//
//        Description:
//
//            > Learn Prison [R]
//
//              Shame creates cell walls around himself to trap all nearby
//              enemy units. All enemy units inside the prison, deals damage,
//              reduces 70% movement speed and decreases 1 armor per second
//              and unable to escape.
//
//              Level 1 - (2% intelligence points * 10) damage per second,
//              and Prison lasts 10 seconds.
//              Level 2 - (3% intelligence points * 20) damage per second,
//              and Prison lasts 15 seconds.
//              Level 3 - (4% intelligence points * 30) damage per second,
//              and Prison lasts 20 seconds.
//
//              Cooldown: 240
//              Manacost: 120/110/100
//
//===========================================================================
//
//        Credits:
//            > HappyCockroach (Shame Models and Icons)
//            > morbent (SendToTheVoid Icons)
//          


//                            CONFIGURATION
//===========================================================================
//
//        Object IDs
//

    //    [abilityID] Prison
    constant function prison_ID takes nothing returns integer
        return 'A000'
    endfunction

    //    [abilityID] Armor Reduction
    constant function armorReduction_ID takes nothing returns integer
        return 'A001'
    endfunction
  
    //    [buffID] Exhaust [dummyCaster]
    constant function exhaustBuff_ID takes nothing returns integer
        return 'B000'
    endfunction
  
    //    [unitID] CELL
    constant function cellwall_ID takes nothing returns integer
        return 'h000'
    endfunction
  
    //    [unitID] AURA
    constant function aura_ID takes nothing returns integer
        return 'h002'
    endfunction
  
    //    [unitID] DummyCaster
    constant function dummyCaster_ID takes nothing returns integer
        return 'h001'
    endfunction
  
//===========================================================================
//
//        Ability Stats Configuration
//

    // Stats - Additional Bonus Damage [Primary Attribute]
    function attrib_Base takes nothing returns string
        // Attributes:
        //  INT - Intelligence
        //  STR - Strength
        //  AGI - Agility
        //  NO  - No Additional Bonus Damage
        return "INT"
    endfunction


    // Stats - Additional Bonus Damage [Include Attribute Bonuses]
    function attrib_Bonuses takes nothing returns boolean
        return true
    endfunction


    // Stats - Additional Bonus Damage [Percentage]
    function attrib_Percentage takes integer lvl, unit u returns real
        local real array Percentage
      
        //////////////////////////////////
        set Percentage[1] = 0.02        // Level 1
        set Percentage[2] = 0.03        // Level 2
        set Percentage[3] = 0.04        // Level 3
        //////////////////////////////////
  
  



        // return
        if(StringCase(attrib_Base(), true) == "INT") then
            if(attrib_Bonuses() == true) then
                return GetHeroStatBJ(bj_HEROSTAT_INT, u, true) * Percentage[lvl]
            else
                return GetHeroStatBJ(bj_HEROSTAT_INT, u, false) * Percentage[lvl]
            endif
        elseif(StringCase(attrib_Base(), true) == "STR") then
            if(attrib_Bonuses() == true) then
                return GetHeroStatBJ(bj_HEROSTAT_STR, u, true) * Percentage[lvl]
            else
                return GetHeroStatBJ(bj_HEROSTAT_STR, u, false) * Percentage[lvl]
            endif
        elseif(StringCase(attrib_Base(), true) == "AGI") then
            if(attrib_Bonuses() == true) then
                return GetHeroStatBJ(bj_HEROSTAT_AGI, u, true) * Percentage[lvl]
            else
                return GetHeroStatBJ(bj_HEROSTAT_AGI, u, false) * Percentage[lvl]
            endif
        else
            // no extra damage
            return 0.0
        endif
    endfunction
  

    // Stats - Base Damage Per Second
    function DPS takes integer lvl, unit u returns real
        local real array DamagePerSecond
      
      
        ///////////////////////////////////////
        set DamagePerSecond[1] = 10.0        // Level 1
        set DamagePerSecond[2] = 20.0        // Level 2
        set DamagePerSecond[3] = 30.0        // Level 3
        ///////////////////////////////////////
  
  



        // return dmg
        return attrib_Percentage(lvl, u) + DamagePerSecond[lvl]
    endfunction
  
  
    // Stats - Duration
    function dur takes integer lvl returns real
        local real array Duration
      
      
        ////////////////////////////////////////
        set Duration[1] = 10.0                // Level 1
        set Duration[2] = 15.0                // Level 2
        set Duration[3] = 20.0                // Level 3
        ////////////////////////////////////////
      
      
        // return dur
        return Duration[lvl]
    endfunction
  
  
    // Stats - Maximum Armor Reduction
    function armorReduction_Limit takes integer lvl returns integer
        local integer array MaximumArmorReduction
      
      
        ///////////////////////////////////////
        set MaximumArmorReduction[1] = 30    // Level 1
        set MaximumArmorReduction[2] = 30    // Level 2
        set MaximumArmorReduction[3] = 30    // Level 3
        ///////////////////////////////////////
      
      
        // return armorReduction_Limit
        return MaximumArmorReduction[lvl]
    endfunction
  
  
    // Stats - Area of Effect
    constant function AoE takes nothing returns real
        return 710.0
    endfunction


    // Damage - Attack Type
    constant function atkType takes nothing returns attacktype
        return ATTACK_TYPE_NORMAL
    endfunction


    // Damage - Damage Type
    constant function dmgType takes nothing returns damagetype
        return DAMAGE_TYPE_NORMAL
    endfunction

//===========================================================================
//
//        Core configuration

    // Periodic Time
    constant function periodicTime takes nothing returns real
        return 0.03125000
    endfunction
  
//===========================================================================
//
//        VISUAL configuration

    //        [Values]
    //              
  
    // CELL - [Count]
    constant function cell_Count takes nothing returns integer
        return 150
    endfunction
  
    // CELL - [Radius]
    constant function cell_Radius takes nothing returns real
        return 700.0
    endfunction
  
    // AURA - [Model Size]
    constant function aura_Size takes nothing returns real
        return 700.0
    endfunction
  
    // AURA - [Transparent Speed]
    constant function transparent_Spd takes nothing returns real
        return 2.0
    endfunction
      
    //        [Special Effect]
    //

    // SFX - Damage effect
    constant function dmgEffect takes nothing returns string
        return "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
    endfunction
  
    // SFX - Damage effect attachpoint
    constant function dmgEffect_attachpoint takes nothing returns string
        return "origin"
    endfunction
  
    // SFX - Cell Wall Destroyed effect
    constant function cellEffect takes nothing returns string
        return "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
    endfunction
  
    // SFX - Blink Start
    constant function blinkstartEffect takes nothing returns string
        return "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"
    endfunction
  
    // SFX - Blink End
    constant function blinkendEffect takes nothing returns string
        return "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl"
    endfunction
  
    //        [Lightning Effect]
    //
  
    //    LIGHTNING EFFECT - Chain
    constant function chain takes nothing returns string
        // You can change the Lightning Effect.
        //
        // Lightning Effect ID:
        //    CLPB - Chain Lightning [Primary]
        //    CLSB - Chain Lightning [Secondary]
        //    DRAB - Drain
        //    DRAL - Drain Life
        //    DRAM - Drain Mana
        //    AFOD - Finger of Death
        //    FORK - Forked Lightning
        //    HWPB - Healing Wave [Primary]
        //    HWSB - Healing Wave [Secondary]
        //    CHIM - Lightning Attack
        //    LEAS - Magic Leash
        //    MBUR - Mana Burn
        //    MFPB - Mana Flare
        //    SPLK - Spirit Link
        return "DRAB"
    endfunction
  
    // LIGHTNING EFFECT - RED Color
    constant function RED takes nothing returns real
        return 50.0
    endfunction
  
    // LIGHTNING EFFECT - GREEN Color
    constant function GREEN takes nothing returns real
        return 0.0
    endfunction
  
    // LIGHTNING EFFECT - BLUE Color
    constant function BLUE takes nothing returns real
        return 60.0
    endfunction

  
//===========================================================================
//
//                            ENDCONFIGURATION
//








//===========================================================================
//
//        [trigger] Unit casted a spell
//

function cut_Tree takes nothing returns nothing
    local destructable tree = GetEnumDestructable()
  
    call IssueTargetDestructableOrder( udg_PRISON_treeDetector, "harvest", tree)
    if(GetUnitCurrentOrder(udg_PRISON_treeDetector) == String2OrderIdBJ("harvest"))then
        call IssueImmediateOrderBJ(udg_PRISON_treeDetector, "stop" )
        call KillDestructable(tree)
    endif
    set tree = null
endfunction

function trigger_Cast takes nothing returns nothing
    local integer tempInt
    local location tempLoc
    local location tempLocB
    local location tempLocC
    local real tempReal = 0.0

    if(GetSpellAbilityId() == prison_ID()) then
        // Turn ON Periodic Loop
        if(IsTriggerEnabled(gg_trg_Prison) == false) then
            call EnableTrigger(gg_trg_Prison)
        endif
      
      
        // Index
        set udg_PRISON_Max = udg_PRISON_Max + 1
      
        set udg_PRISON_Caster[udg_PRISON_Max] = GetTriggerUnit()
        set udg_PRISON_Level[udg_PRISON_Max] = GetUnitAbilityLevelSwapped( prison_ID(), udg_PRISON_Caster[udg_PRISON_Max])
        set udg_PRISON_Duration[udg_PRISON_Max] = dur( udg_PRISON_Level[udg_PRISON_Max] )
        set udg_PRISON_perSec[udg_PRISON_Max] = 1
      
        // Create CELLs
        set tempInt = 1
        loop
            exitwhen tempInt > cell_Count()
            // get angle for tempLoc
            set tempReal = (360.00 / cell_Count()) + tempReal
            set tempLoc = GetUnitLoc(udg_PRISON_Caster[udg_PRISON_Max])
          
            call CreateNUnitsAtLoc(1, cellwall_ID(), Player(PLAYER_NEUTRAL_PASSIVE), PolarProjectionBJ( tempLoc, cell_Radius(), tempReal), tempReal)
            call UnitApplyTimedLifeBJ(dur(udg_PRISON_Level[udg_PRISON_Max]), 'BTLF', GetLastCreatedUnit())
            call RemoveLocation(tempLoc)
            set tempLoc = null
          
            set tempInt = tempInt + 1
        endloop
      
        // Create AURA
        set tempLocB = GetUnitLoc(udg_PRISON_Caster[udg_PRISON_Max])
        call CreateNUnitsAtLoc(1, aura_ID(), Player(PLAYER_NEUTRAL_PASSIVE), tempLocB, 0)
        set udg_PRISON_aura[udg_PRISON_Max] = GetLastCreatedUnit()
        call SetUnitScalePercent(udg_PRISON_aura[udg_PRISON_Max], aura_Size(), aura_Size(), aura_Size())
      
        // Cut all nearby trees
        set tempLocC = GetUnitLoc(udg_PRISON_aura[udg_PRISON_Max])
        call EnumDestructablesInCircleBJ( AoE(), tempLocC, function cut_Tree)
      
        // Create prisonerGroup
        set udg_PRISON_prisonerGroup[udg_PRISON_Max] = CreateGroup()
      
        // Remove memory leaks
        call RemoveLocation(tempLocB)
        call RemoveLocation(tempLocC)
        set tempLocC = null
        set tempLocB = null
    endif
endfunction

//===========================================================================
//
//        [trigger] Time - Every periodicTime() seconds of game time
//

function trigger_transparentLoop takes nothing returns nothing
    local integer Index
  
    set Index = 1
    loop
        exitwhen Index > udg_PRISON_transparentMax
      
        if(udg_PRISON_transparent_aura[Index] != null and udg_PRISON_transparent[Index] >= 100) then
            // remove aura
            call RemoveUnit(udg_PRISON_transparent_aura[Index])
          
            // Index Recycle
            set udg_PRISON_transparent[Index] = udg_PRISON_transparent[udg_PRISON_transparentMax]
            set udg_PRISON_transparent_aura[Index] = udg_PRISON_transparent_aura[udg_PRISON_transparentMax]
          
            set udg_PRISON_transparent[udg_PRISON_transparentMax] = 0
            set udg_PRISON_transparent_aura[udg_PRISON_transparentMax] = null
          
            set Index = Index - 1
            set udg_PRISON_transparentMax = udg_PRISON_transparentMax - 1
        else
            // transparent
            set udg_PRISON_transparent[Index] = udg_PRISON_transparent[Index] + transparent_Spd()
            call SetUnitVertexColorBJ(udg_PRISON_transparent_aura[Index], 100, 100, 100, udg_PRISON_transparent[Index])
        endif
      
        // Check if udg_PRISON_transparentMax is equal to 0 then
        // turn off this trigger
        if(udg_PRISON_transparentMax == 0) then
            call DisableTrigger(udg_PRISON_trigger_transparent)
        endif
        set Index = Index + 1
    endloop
endfunction

function trigger_lightningLoop takes nothing returns nothing
    local integer Index
    local location source_loc
    local location target_loc
  
    set Index = 1
    loop
        exitwhen Index > udg_PRISON_lightningMax
      
        if(udg_PRISON_lightningStop[Index] == true or IsUnitDeadBJ(udg_PRISON_lightningSourceUnit[Index]) == true or IsUnitDeadBJ(udg_PRISON_lightningTargetedUnit[Index]) == true) then
            call DestroyLightningBJ(udg_PRISON_lightning[Index])
          
            // Index Recycle
            set udg_PRISON_lightning[Index] = udg_PRISON_lightning[udg_PRISON_lightningMax]
            set udg_PRISON_lightningSourceUnit[Index] = udg_PRISON_lightningSourceUnit[udg_PRISON_lightningMax]
            set udg_PRISON_lightningTargetedUnit[Index] = udg_PRISON_lightningTargetedUnit[udg_PRISON_lightningMax]
            set udg_PRISON_lightningStop[Index] = udg_PRISON_lightningStop[udg_PRISON_lightningMax]
          
            set udg_PRISON_lightning[udg_PRISON_lightningMax] = null
            set udg_PRISON_lightningSourceUnit[udg_PRISON_lightningMax] = null
            set udg_PRISON_lightningTargetedUnit[udg_PRISON_lightningMax] = null
            set udg_PRISON_lightningStop[udg_PRISON_lightningMax] = false
          
            set udg_PRISON_lightningMax = udg_PRISON_lightningMax - 1
            set Index = Index - 1
        else
            // Move Lightning
            set source_loc = GetUnitLoc(udg_PRISON_lightningSourceUnit[Index])
            set target_loc = GetUnitLoc(udg_PRISON_lightningTargetedUnit[Index])
            call MoveLightningLoc(udg_PRISON_lightning[Index], source_loc, target_loc)
          
            // Remove memory leaks
            call RemoveLocation(source_loc)
            call RemoveLocation(target_loc)
            set source_loc = null
            set target_loc = null
        endif
      
        // Check if udg_PRISON_lightningMax reach the 0, then turn off this
        // trigger
        if(udg_PRISON_lightningMax == 0) then
            call DisableTrigger(udg_PRISON_trigger_lightning)
        endif
        set Index = Index + 1
    endloop
endfunction

function dmgGroup_Func takes nothing returns nothing
    local unit Prisoner = GetEnumUnit()
    local real dmg = DPS(udg_PRISON_Level[udg_PRISON_Index], udg_PRISON_Caster[udg_PRISON_Index])
  
    if(IsUnitAliveBJ(Prisoner) == true) then
        // Deals damage
        call UnitDamageTargetBJ(udg_PRISON_Caster[udg_PRISON_Index] ,Prisoner ,dmg ,atkType(),dmgType())
      
        // Decreases 1 armor
        if(GetUnitAbilityLevelSwapped(armorReduction_ID(), Prisoner) == 0) then
            call UnitAddAbilityBJ(armorReduction_ID(), Prisoner)
        elseif(GetUnitAbilityLevelSwapped(armorReduction_ID(), Prisoner) < armorReduction_Limit(udg_PRISON_Level[udg_PRISON_Index])) then
            call IncUnitAbilityLevelSwapped(armorReduction_ID(), Prisoner)
        endif
      
        // Special Effect for Prisoner
        call AddSpecialEffectTargetUnitBJ(dmgEffect_attachpoint(), Prisoner, dmgEffect())
        call DestroyEffectBJ(GetLastCreatedEffectBJ())
    else
        // Prisoner is dead
        call GroupRemoveUnitSimple(Prisoner, udg_PRISON_prisonerGroup[udg_PRISON_Index])
    endif
  
    // null
    set Prisoner = null
endfunction

function nearbyGroup_Func takes nothing returns nothing
    local unit nonPrisoner = GetEnumUnit()
    local unit dummyCaster
    local player p = GetOwningPlayer(udg_PRISON_Caster[udg_PRISON_Index])
    local location nonPrisoner_loc = GetUnitLoc(nonPrisoner)
    local location source_loc
    local location target_loc
  
    if(IsUnitAliveBJ(nonPrisoner) == true) then
        if(GetUnitTypeId(nonPrisoner) != cellwall_ID() and GetUnitTypeId(nonPrisoner) != aura_ID() and GetUnitTypeId(nonPrisoner) != dummyCaster_ID()) then
            if(IsUnitType(nonPrisoner, UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy(nonPrisoner, p) == true) then
                if(IsUnitInGroup(nonPrisoner, udg_PRISON_prisonerGroup[udg_PRISON_Index]) == false) then
                    // add this nonPrisoner on prisonerGroup
                    call GroupAddUnitSimple(nonPrisoner, udg_PRISON_prisonerGroup[udg_PRISON_Index])
                  
                    // DummyCaster casts exhaust to nonPrisoner
                    if(UnitHasBuffBJ(nonPrisoner, exhaustBuff_ID()) == false)then
                        call CreateNUnitsAtLoc( 1, dummyCaster_ID(), Player(PLAYER_NEUTRAL_PASSIVE), nonPrisoner_loc, 0)
                        set dummyCaster = GetLastCreatedUnit()
                        call IssueTargetOrderBJ( dummyCaster, "slow", nonPrisoner)
                        call RemoveLocation(nonPrisoner_loc)
                    endif
                    set dummyCaster = null
              
                    // Add lightning effect
                    if(IsTriggerEnabled(udg_PRISON_trigger_lightning) == false) then
                        call EnableTrigger(udg_PRISON_trigger_lightning)
                    endif
                  
                    // Index
                    set udg_PRISON_lightningMax = udg_PRISON_lightningMax + 1
                  
                    set udg_PRISON_lightningSourceUnit[udg_PRISON_lightningMax] = udg_PRISON_Caster[udg_PRISON_Index]
                    set udg_PRISON_lightningTargetedUnit[udg_PRISON_lightningMax] = nonPrisoner
                    set udg_PRISON_lightningStop[udg_PRISON_lightningMax] = false
                  
                    set source_loc = GetUnitLoc(udg_PRISON_lightningSourceUnit[udg_PRISON_lightningMax])
                    set target_loc = GetUnitLoc(udg_PRISON_lightningTargetedUnit[udg_PRISON_lightningMax])
                    call AddLightningLoc( chain(), source_loc, target_loc)
                    set udg_PRISON_lightning[udg_PRISON_lightningMax] = GetLastCreatedLightningBJ()
                    call SetLightningColorBJ(udg_PRISON_lightning[udg_PRISON_lightningMax], RED(), GREEN(), BLUE(), 1 )
                  
                    // Remove memory leaks
                    call RemoveLocation(source_loc)
                    call RemoveLocation(target_loc)
                    set source_loc = null
                    set target_loc = null
                endif
            endif
        endif
    endif
    set nonPrisoner = null
    set nonPrisoner_loc = null
    set p = null
endfunction

function removeBuffGroup_Func takes nothing returns nothing
    local unit Prisoner = GetEnumUnit()
    local integer Index
  
    // Remove Exhaust Buff
    if(UnitHasBuffBJ(Prisoner, exhaustBuff_ID()) == true)then
        call UnitRemoveBuffBJ( exhaustBuff_ID(), Prisoner)
    endif
  
    // Remove Armor Reduction
    if(GetUnitAbilityLevelSwapped(armorReduction_ID(), Prisoner) > 0) then
        call UnitRemoveAbilityBJ(armorReduction_ID(), Prisoner)
    endif
  
    // Remove Lightning Effect
    set Index = 1
    loop
        exitwhen Index > udg_PRISON_lightningMax
        if(Prisoner == udg_PRISON_lightningTargetedUnit[Index] and udg_PRISON_Caster[udg_PRISON_Index] == udg_PRISON_lightningSourceUnit[Index]) then
            set udg_PRISON_lightningStop[Index] = true
            set Index = udg_PRISON_lightningMax
        endif
        set Index = Index + 1
    endloop
  
    // Remove Prisoner
    call GroupRemoveUnitSimple(Prisoner, udg_PRISON_prisonerGroup[udg_PRISON_Index])
endfunction

function distanceGroup_Func takes nothing returns nothing
    local unit Prisoner = GetEnumUnit()
    local location Prisoner_loc = GetUnitLoc(Prisoner)
    local location Aura_loc = GetUnitLoc(udg_PRISON_aura[udg_PRISON_Index])
    local location move_loc
    local location blinkstart_loc
    local location blinkend_loc
    local real Prisoner_angle
  
    // Move Prisoner to Prisoner_loc
    if(DistanceBetweenPoints(Prisoner_loc, Aura_loc) > AoE()) then
        set blinkstart_loc = GetUnitLoc(Prisoner)
        set Prisoner_angle = GetUnitFacing(Prisoner)
        set move_loc = GetUnitLoc(udg_PRISON_aura[udg_PRISON_Index])
      
        // blink start effect
        call AddSpecialEffectLocBJ(blinkstart_loc, blinkstartEffect())
        call DestroyEffectBJ(GetLastCreatedEffectBJ())
        call SetUnitPositionLoc(Prisoner, PolarProjectionBJ(move_loc, cell_Radius()/2, Prisoner_angle))
      
        // blink end effect
        set blinkend_loc = GetUnitLoc(Prisoner)
        call AddSpecialEffectLocBJ(blinkend_loc, blinkstartEffect())
        call DestroyEffectBJ(GetLastCreatedEffectBJ())
      
        // Remove memory leaks
        call RemoveLocation(move_loc)
        call RemoveLocation(blinkstart_loc)
        call RemoveLocation(blinkend_loc)
        set move_loc = null
        set blinkstart_loc = null
        set blinkend_loc = null
    endif
  
    // Remove memory leaks
    call RemoveLocation(Prisoner_loc)
    call RemoveLocation(Aura_loc)
    set Prisoner = null
    set Prisoner_loc = null
    set Aura_loc = null
endfunction

function trigger_coreLoop takes nothing returns nothing
    local group nearbyGroup
    local location nearbyGroup_loc

    set udg_PRISON_Index = 1
    loop
        exitwhen udg_PRISON_Index > udg_PRISON_Max
      
        // check if Duration reach the 0
        if( udg_PRISON_Duration[udg_PRISON_Index] <= 0) then
            // Remove AURA
            if(IsTriggerEnabled(udg_PRISON_trigger_transparent) == false) then
                call EnableTrigger(udg_PRISON_trigger_transparent)
            endif
          
            set udg_PRISON_transparentMax = udg_PRISON_transparentMax + 1
            set udg_PRISON_transparent_aura[udg_PRISON_transparentMax] = udg_PRISON_aura[udg_PRISON_Index]
            set udg_PRISON_transparent[udg_PRISON_transparentMax] = 0
          
            // Remove buffs, armor reduction, and group
            call ForGroupBJ( udg_PRISON_prisonerGroup[udg_PRISON_Index], function removeBuffGroup_Func)
            call DestroyGroup(udg_PRISON_prisonerGroup[udg_PRISON_Index])
          
            // Index Recycle
            set udg_PRISON_Duration[udg_PRISON_Index] = udg_PRISON_Duration[udg_PRISON_Max]
            set udg_PRISON_perSec[udg_PRISON_Index] = udg_PRISON_perSec[udg_PRISON_Max]
            set udg_PRISON_aura[udg_PRISON_Index] = udg_PRISON_aura[udg_PRISON_Max]
            set udg_PRISON_Caster[udg_PRISON_Index] = udg_PRISON_Caster[udg_PRISON_Max]
            set udg_PRISON_Level[udg_PRISON_Index] = udg_PRISON_Level[udg_PRISON_Max]
            set udg_PRISON_prisonerGroup[udg_PRISON_Index] = udg_PRISON_prisonerGroup[udg_PRISON_Max]

            set udg_PRISON_Duration[udg_PRISON_Max] = 0.00
            set udg_PRISON_perSec[udg_PRISON_Max] = 0.00
            set udg_PRISON_aura[udg_PRISON_Max] = null
            set udg_PRISON_Caster[udg_PRISON_Max] = null
            set udg_PRISON_Level[udg_PRISON_Max] = 0
            set udg_PRISON_prisonerGroup[udg_PRISON_Max] = null
          
            set udg_PRISON_Index = udg_PRISON_Index - 1
            set udg_PRISON_Max = udg_PRISON_Max - 1
        else
            // if not, do perSec Method
            if(udg_PRISON_perSec[udg_PRISON_Index] <= 0) then
                set udg_PRISON_Duration[udg_PRISON_Index] = udg_PRISON_Duration[udg_PRISON_Index] - 1
                set udg_PRISON_perSec[udg_PRISON_Index] = 1
              
                // deals damage, exhausts, and decreases 1 armor
                // to all enemy units inside the prison per second
                call ForGroupBJ( udg_PRISON_prisonerGroup[udg_PRISON_Index], function dmgGroup_Func)
            else
                set udg_PRISON_perSec[udg_PRISON_Index] = udg_PRISON_perSec[udg_PRISON_Index] - periodicTime()
              
                // nearby enemy units
                set nearbyGroup_loc = GetUnitLoc(udg_PRISON_aura[udg_PRISON_Index])
                set nearbyGroup = GetUnitsInRangeOfLocAll(AoE(), nearbyGroup_loc)
                call ForGroupBJ( nearbyGroup, function nearbyGroup_Func)
                call DestroyGroup(nearbyGroup)
                call RemoveLocation(nearbyGroup_loc)
                set nearbyGroup = null
                set nearbyGroup_loc = null
              
                // check the distance between aura and enemy unit
                call ForGroupBJ( udg_PRISON_prisonerGroup[udg_PRISON_Index], function distanceGroup_Func)
            endif
        endif
      
        // check if udg_PRISON_Max reach the 0, then turn off this
        // trigger
        if(udg_PRISON_Max == 0) then
            call DisableTrigger(gg_trg_Prison)
        endif
        set udg_PRISON_Index = udg_PRISON_Index + 1
    endloop
endfunction

//===========================================================================
//
//        [trigger] Unit - A unit Dies
//                  
//                > Remove a dummy corpses instantly
//                    to avoid lag
//

function trigger_dummyRemove takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local location tempLoc = GetUnitLoc(u)

    if(GetUnitTypeId(u) == cellwall_ID() or GetUnitTypeId(u) == dummyCaster_ID()) then
        // Special Effect for cell wall
        if(GetUnitTypeId(u) == cellwall_ID()) then
            call AddSpecialEffectLocBJ(tempLoc, cellEffect())
            call DestroyEffectBJ( GetLastCreatedEffectBJ())
            call RemoveLocation(tempLoc)
        endif
        call RemoveUnit(u)
    endif
    set u = null
    set tempLoc = null
endfunction

//===========================================================================
//
//        [trigger] Time - Elapsed game time is 0.00 seconds
//                  
//                > Preload all dummies amd abilities
//

function trigger_initializeSpell takes nothing returns nothing
    local unit unitA
    local unit unitB
    local location loc = GetRectCenter(GetPlayableMapRect())
    local location locA = GetRectCenter(GetPlayableMapRect())
    local location locB = GetRectCenter(GetPlayableMapRect())
  
    // add Tree Detector
    call CreateNUnitsAtLoc(1, dummyCaster_ID(), Player(PLAYER_NEUTRAL_PASSIVE), loc, 0)
    set udg_PRISON_treeDetector = GetLastCreatedUnit()
    call ShowUnitHide(udg_PRISON_treeDetector)
  
    // Preload dummy units and abilities
    call CreateNUnitsAtLoc(1, cellwall_ID(), Player(PLAYER_NEUTRAL_PASSIVE), locA, 0)
    set unitA = GetLastCreatedUnit()

    call CreateNUnitsAtLoc(1, dummyCaster_ID(), Player(PLAYER_NEUTRAL_PASSIVE), locB, 0)
    set unitB = GetLastCreatedUnit()
    call UnitAddAbilityBJ(prison_ID(), unitB)
    call UnitAddAbilityBJ(armorReduction_ID(), unitB)
  
    // Remove memory leaks
    call RemoveLocation(locA)
    call RemoveLocation(locB)
    call RemoveUnit(unitA)
    call RemoveUnit(unitB)
    set locA = null
    set locB = null
    set unitA = null
    set unitB = null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

//===========================================================================
function InitTrig_Prison takes nothing returns nothing
    local trigger castTRIGGER = CreateTrigger()
    local trigger diesTRIGGER = CreateTrigger()
    local trigger initTRIGGER = CreateTrigger()
    set gg_trg_Prison = CreateTrigger()
    set udg_PRISON_trigger_lightning = CreateTrigger()
    set udg_PRISON_trigger_transparent = CreateTrigger()
  
  
    // TRIGGER - Unit - A unit Starts the effect of an ability
    call TriggerRegisterAnyUnitEventBJ(castTRIGGER, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction(castTRIGGER, function trigger_Cast)
  
  
    // TRIGGER - Time - Every periodicTime() seconds of game time
    call DisableTrigger(gg_trg_Prison)
    call TriggerRegisterTimerEventPeriodic(gg_trg_Prison, periodicTime())
    call TriggerAddAction(gg_trg_Prison, function trigger_coreLoop)
  
  
    // TRIGGER - Unit - A unit Dies
    call TriggerRegisterAnyUnitEventBJ(diesTRIGGER, EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddAction(diesTRIGGER, function trigger_dummyRemove)


    // TRIGGER - Time - Elapsed game time is 0.00 seconds
    call TriggerRegisterTimerEventSingle(initTRIGGER, 0.00)
    call TriggerAddAction(initTRIGGER, function trigger_initializeSpell)
    set initTRIGGER = null


    // TRIGGER - Time - Every periodicTime() seconds of game time
    call DisableTrigger(udg_PRISON_trigger_lightning)
    call TriggerRegisterTimerEventPeriodic(udg_PRISON_trigger_lightning, periodicTime())
    call TriggerAddAction(udg_PRISON_trigger_lightning, function trigger_lightningLoop)
  
  
    // TRIGGER - Time - Every periodicTime() seconds of game time
    call DisableTrigger(udg_PRISON_trigger_transparent)
    call TriggerRegisterTimerEventPeriodic(udg_PRISON_trigger_transparent, periodicTime())
    call TriggerAddAction(udg_PRISON_trigger_transparent, function trigger_transparentLoop)
endfunction
 

Attachments

  • Screenshot A.png
    Screenshot A.png
    1.7 MB · Views: 306
  • Screenshot B.png
    Screenshot B.png
    1.7 MB · Views: 288
  • Screenshot C.png
    Screenshot C.png
    1.7 MB · Views: 288
  • nel Prison v1.1.w3x
    205.8 KB · Views: 36
Last edited:

NEL

NEL

Level 6
Joined
Mar 6, 2017
Messages
113
About the armor reduction. You should use not -1, -2 ,-3....,-10,-11,-12,-13... because of large leveled ability increases loading time, but 1st ability : 0,-1,-2,-3....-9; 2nd ability 0,-10,-20,-30...-90. See? I use only 20 levels (2 abilities with 10 levels of each) but I can achieve -99 armor reduction instead of -30.

nice idea bro :D
 

Tank-Commander

Spell Reviewer
Level 29
Joined
May 26, 2009
Messages
1,839
Most of the code infrastructure is done though I've not bolted it together or tested it yet
but here's a teaser image - doesn't really do anything at the moment though due to lack of stuff being bolted together

Edit: physics attached and it works, got to tweak it a little bit but it's a start
 

Attachments

  • WIP1.png
    WIP1.png
    436.8 KB · Views: 48
  • WIP2.png
    WIP2.png
    1.5 MB · Views: 44
Last edited:
Most of the code infrastructure is done though I've not bolted it together or tested it yet
but here's a teaser image - doesn't really do anything at the moment though due to lack of stuff being bolted together

Edit: physics attached and it works, got to tweak it a little bit but it's a start
I cant get any concept or alike from the pictures.
 

Tank-Commander

Spell Reviewer
Level 29
Joined
May 26, 2009
Messages
1,839
well the key parts to the concept won't really be incorporated until the spell is pretty much done, at which point I'd be posting the entry post not WIPs the parts you can see (including the WIP I'm posting here) are the basic element of the spell - the advanced stuff that's going to "complete it" are coming up, it's just essentially the spell windup

eitherway, demonstrating the projectile homing physics of the "seeking" part of my spell, 3 is when the target is found close, 4 is the target found far and 5 is target found at what would probably be considered an average distance, obviously this looks much better in animated form but I'm too busy writing code to bother making GIFs

takes about 1 second to go from "found target" to having all projectiles reach the target

sitting pretty at 500 lines at the moment
Edit: projectile total damage now consistent regardless of the number of projectiles still alive (projectiles die if they leave the search range before a target is found, since projectiles leave the range at a different speed it's possible that some will be dead and a target still found)

Edit2: Alright the spell is mostly complete now visually, I'm going to add a freezing wave effect to the final part (will function like a large AOE stun) which'll give it a bit more "power" visually and effect-wise and then I'll be done. the name I've given it is Apex Blizzard (might change but probably not) and you have a GIF of the main effect (sans freezing wave)
 

Attachments

  • WIP3.png
    WIP3.png
    910.4 KB · Views: 47
  • WIP4.png
    WIP4.png
    1.2 MB · Views: 61
  • WIP5.png
    WIP5.png
    1.1 MB · Views: 64
  • Apex Blizzard 1.gif
    Apex Blizzard 1.gif
    7.6 MB · Views: 102
Last edited:

Tank-Commander

Spell Reviewer
Level 29
Joined
May 26, 2009
Messages
1,839
well each projectile seeks independently if that's what you're asking, it functions similarly to a skillshot in that regard, majority of the damage is dealt to the primary target so you want the seeking lines to line up with your intended target (and the intended target to be closest, since otherwise it could go in the opposite direction) if none of the seeking lines hit anything then the spell does nothing, of course directly casting it under your target works too, the physics engine allows me to combine the seeking phase with the intended spell effect without creating new projectiles and makes it blend a bit more seamlessly - think you'd be hard pressed to get this specific mechanic with a spell without doing something like this (without it looking a bit daft)
as for why multiple projectiles are on each line this actually gives them a bit more offset - the seeking is 2D (but can hit flying units as well as ground) - and thus a slightly more forgiving seek against mobile targets also plainly yeah looks a lot better than just having flat seek lines

Edit: Uploading my entry to the section, just attaching one of my GIFs here (bit too big for the resource section)
ok done it Apex Blizzard V1.00 (the map name itself is Tank-Commander - Apex Blizzard)
 

Attachments

  • Apex Blizzard Normal Cast.gif
    Apex Blizzard Normal Cast.gif
    31.1 MB · Views: 2,475
Last edited:
Level 6
Joined
Jan 8, 2010
Messages
158
Unfortunately I had to return home this weekend (after putting this off for so long.) So my computer was at the dorm while I had a crappy laptop (without WC3 :/) Anyways, please be sure to mention me if another spell contest comes up :) And I'll be sure to leave reviews for all spells here when it comes time.
 

Tank-Commander

Spell Reviewer
Level 29
Joined
May 26, 2009
Messages
1,839
Last edited:
Status
Not open for further replies.
Top