• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Cover of Darkness 1.02

Cover of Darkness
The idea of the Spell is from HoN a game like Dota ( Dark Lady )

What it should do:
-Disables the shared sight for all enemys Players
-Decrease the sightrange of all enemy Units

Tooltip:
Turns the day into a deep night and breaks the shared view for all enemy, So every foe stands alone with a defective sight and turns into an easy mark for the Lycanthrop.

Requires:
- BonusMod (Earth-Fury)
- Group Utils (Rising_Dusk) - optional
- JNGP ( newest JassHelper )

Important:
This is a testversion so the spell works only on allies not on enemys, just to show how it works :)
This can be change in the trigger.
I have make 2 versions of the spell one with one without GroupUtils

JASS:
cope CoverofDarkness
    /*_______________________________________________________________
    | Author: Kruemel-Monster
    | Version: 1.0
    | Requirements:
    | -BonusMod (Earth-Fury)
    | Description: 
    | -Disables the shared sight for all enemys Players
    | -Decrease the sightrange of all enemy Units
    | Tooltip:
    | Turns the day into such a deep night, that all enemys
    | get a defective sight. So every foe can only fight alone.
    | 
    | Some Bugs:
    | -It could malfunctions if you cange the Alliance while on Effect
    | -Every unit could attack with autoattack over her sightrange ( so they attack you even if they dont see you )
    |  This is not rightly tested, i only saw this effect on neutral creeps as they having 0 sightrange
    |
    | How to import:
    | 1. Copy the BonusMod trigger and this trigger into your map
    | Info: 2 -> 5. is only if you dont have the Bonus Mod abilities
    |   2. Search inside the BonusMod trigger for :
    |   -> runtextmacro BonusMod_BeginBonuses("false") <- line 225
    |      Replace the false into a true
    |   -> runtextmacro BonusMod_BeginBonuses("true")
    |   3. Save the map, close the map and reopen the map
    |   4. Now you should have like 80 Abilities in you Object Editor
    |   5. if that is true, you can change the line again into false
    |   -> runtextmacro BonusMod_BeginBonuses("false") 
    | 6. Copy the ability Cover of Darkness into your map
    | 7. Search inside this trigger for the global TESTMODE and set it to false
    |_________________________________________________________________
    */     // Ye ye i know my Descitption sucks ;D
    globals
        private constant boolean  TESTMODE = true
        // It would be lame if your units are not under the effect of the Spell
        // The TESTMODE allows you to affect only allies
        // TESTMODE = true  ::: You and your allies are affected
        // TESTMODE = false ::: Your enemys are affected
        private constant integer  ABIL_ID  = 'A000'
        // The Base Ability Id
        private constant integer  SIGHT_MALUS = -575
        // The Amount of Sightrange loose
        // Be carful the Spell makes a night so all units have a night sight range
        // And the normal night sight range is 800
        private constant string   CASTER_SFX = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl"
        // The Effect on the Caster
    endglobals
    // It is important that the Spell Duration is equal to the Duration of the Ability
    private constant function GetSpellDuration takes integer level returns real
        return ((level*2.)+5)
    endfunction
    
//  CODE STARTS : READ AND CHANGE AT OWN RISK
    
    globals
        private constant real     TIME_OUT = 0.1
    endglobals
    private struct Spell
        real    Time
        unit    Caster
        integer Level
        static  Spell array     Active
        static  integer         Count   = 0
        static  timer           Timer   = CreateTimer()
        static  trigger         Trigger = CreateTrigger()
        static  force           Force   = CreateForce()
        static  force           Force2  = CreateForce()
        static  group           Group   = CreateGroup()
        static  integer array   Multi
        static  player          CurPlayer
        static  boolean         flag_add
        method release takes integer number returns nothing
            set Count = Count - 1
            set Active[number] = Active[Count]
            call destroy()
        endmethod
        static  method EnumForce_change takes nothing returns boolean
            local integer pId = GetPlayerId(CurPlayer)
            if CurPlayer != GetFilterPlayer() then  // This is some funny Bug, if you Disable the Shared Visison to your self all units wont see anything ;)
                if flag_add then
                    set Multi[pId] = Multi[pId] - 1
                    if Multi[pId] == 0 then
                        call SetPlayerAlliance(CurPlayer,GetFilterPlayer(),ALLIANCE_SHARED_VISION,flag_add)
                        call SetPlayerAlliance(GetFilterPlayer(),CurPlayer,ALLIANCE_SHARED_VISION,flag_add)
                    endif
                else
                    set Multi[pId] = Multi[pId] + 1
                    call SetPlayerAlliance(CurPlayer,GetFilterPlayer(),ALLIANCE_SHARED_VISION,flag_add)
                    call SetPlayerAlliance(GetFilterPlayer(),CurPlayer,ALLIANCE_SHARED_VISION,flag_add)
                endif
            endif
            return false
        endmethod
        static   method EnumGroup_change takes nothing returns boolean
            if not(flag_add) then
                call SetUnitBonus(GetFilterUnit(),BONUS_SIGHT_RANGE,SIGHT_MALUS)
            else
                if Multi[GetPlayerId(CurPlayer)] == 0 then
                    call SetUnitBonus(GetFilterUnit(),BONUS_SIGHT_RANGE,0)
                endif
            endif
            return false
        endmethod
        static  method EnumForce_enemys takes nothing returns boolean
            set  CurPlayer = GetFilterPlayer()
            call ForceEnumAllies(Force2,CurPlayer,function Spell.EnumForce_change)
            call ForceClear(Force2)
            call GroupEnumUnitsOfPlayer(Group,CurPlayer,function Spell.EnumGroup_change)
            call GroupClear(Group)
            return false
        endmethod
        static  method onloop takes nothing returns nothing
            local Spell this
            local integer index = 0
            loop
                exitwhen index >= Count
                set  this  = Active[index]
                set  Time  = Time + TIME_OUT
                if  Time >= GetSpellDuration(Level) then
                    set  flag_add = true
                    static if TESTMODE then
                        call ForceEnumAllies(Force,GetOwningPlayer(Caster),function Spell.EnumForce_enemys)
                        set  CurPlayer = Player(12)
                        call GroupEnumUnitsOfPlayer(Group,Player(12),function Spell.EnumGroup_change)
                        call GroupClear(Group)
                    else
                        call ForceEnumEnemies(Force,GetOwningPlayer(Caster),function Spell.EnumForce_enemys)
                        set  CurPlayer = Player(12)
                        call GroupEnumUnitsOfPlayer(Group,Player(12),function Spell.EnumGroup_change)
                        call GroupClear(Group)
                    endif
                    call ForceClear(Force)
                    set  Caster = null
                    call release(index)
                else
                    set  index = index + 1
                endif
            endloop
            if  Count == 0 then
                call PauseTimer(Timer)
            endif
        endmethod
        static  method create takes nothing returns Spell
            local Spell this
            if  GetSpellAbilityId() == ABIL_ID then
                set  this = allocate()
                set  Active[Count] = this
                set  Count    = Count + 1
                set  Time     = 0
                set  flag_add = false
                set  Caster   = GetTriggerUnit()
                set  Level    = GetUnitAbilityLevel(Caster,ABIL_ID)
                call DestroyEffect(AddSpecialEffectTarget(CASTER_SFX,Caster,"origin"))
                static if TESTMODE then
                    call ForceEnumAllies(Force,GetOwningPlayer(Caster),function Spell.EnumForce_enemys)
                    set  CurPlayer = Player(12)
                    call GroupEnumUnitsOfPlayer(Group,Player(12),function Spell.EnumGroup_change)
                    call GroupClear(Group)
                else
                    call ForceEnumEnemies(Force,GetOwningPlayer(Caster),function Spell.EnumForce_enemys)
                    set  CurPlayer = Player(12)
                    call GroupEnumUnitsOfPlayer(Group,Player(12),function Spell.EnumGroup_change)
                    call GroupClear(Group)
                endif
                call ForceClear(Force)
                if   Count == 1 then
                    call TimerStart(Timer,TIME_OUT,true,function Spell.onloop)
                endif
            endif
            return this
        endmethod
        static  method onInit takes nothing returns nothing
            call TriggerRegisterAnyUnitEventBJ(Trigger,EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddAction(Trigger,function Spell.create)
        endmethod
    endstruct
endscope
JASS:
scope CoverofDarkness
    /*_______________________________________________________________
    | Author: Kruemel-Monster
    | Version: 1.0
    | Requirements:
    | -BonusMod (Earth-Fury)
    | -GroupUtils (Rising_Dusk)
    | Description: 
    | -Disables the shared sight for all enemys Players
    | -Decrease the sightrange of all enemy Units
    | Tooltip:
    | Turns the day into such a deep night, that all enemys
    | get a defective sight. So every foe can only fight alone.
    | 
    | Some Bugs:
    | -It could malfunctions if you cange the Alliance while on Effect
    | -Every unit could attack with autoattack over her sightrange ( so they attack you even if they dont see you )
    |  This is not rightly tested, i only saw this effect on neutral creeps as they having 0 sightrange
    |
    | How to import:
    | 1. Copy the BonusMod trigger, GroupUtils trigger and this trigger into your map
    | Info: 2 -> 5. is only if you dont have the Bonus Mod abilities
    |   2. Search inside the BonusMod trigger for :
    |   -> runtextmacro BonusMod_BeginBonuses("false") <- line 225
    |      Replace the false into a true
    |   -> runtextmacro BonusMod_BeginBonuses("true")
    |   3. Save the map, close the map and reopen the map
    |   4. Now you should have like 80 Abilities in you Object Editor
    |   5. if that is true, you can change the line again into false
    |   -> runtextmacro BonusMod_BeginBonuses("false") 
    | 6. Copy the ability Cover of Darkness into your map
    | 7. Search inside this trigger for the global TESTMODE and set it to false
    |_________________________________________________________________
    */     // Ye ye i know my Descitption sucks ;D
    globals
        private constant boolean  TESTMODE = true
        // It would be lame if your units are not under the effect of the Spell
        // The TESTMODE allows you to affect only allies
        // TESTMODE = true  ::: You and your allies are affected
        // TESTMODE = false ::: Your enemys are affected
        private constant integer  ABIL_ID  = 'A000'
        // The Base Ability Id
        private constant integer  SIGHT_MALUS = -575
        // The Amount of Sightrange loose
        // Be carful the Spell makes a night so all units have a night sight range
        // And the normal night sight range is 800
        private constant string   CASTER_SFX = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl"
        // The Effect on the Caster
    endglobals
    // It is important that the Spell Duration is equal to the Duration of the Ability
    private constant function GetSpellDuration takes integer level returns real
        return ((level*2.)+5)
    endfunction
    
//  CODE STARTS : READ AND CHANGE AT OWN RISK
    
    globals
        private constant real     TIME_OUT = 0.1
    endglobals
    private struct Spell
        real    Time
        unit    Caster
        integer Level
        static  Spell array     Active
        static  integer         Count   = 0
        static  timer           Timer   = CreateTimer()
        static  trigger         Trigger = CreateTrigger()
        static  force           Force   = CreateForce()
        static  force           Force2  = CreateForce()
        static  integer array   Multi
        static  player          CurPlayer
        static  boolean         flag_add
        method release takes integer number returns nothing
            set Count = Count - 1
            set Active[number] = Active[Count]
            call destroy()
        endmethod
        static  method EnumForce_change takes nothing returns boolean
            local integer pId = GetPlayerId(CurPlayer)
            if CurPlayer != GetFilterPlayer() then  // This is some funny Bug, if you Disable the Shared Visison to your self all units wont see anything ;)
                if flag_add then
                    set Multi[pId] = Multi[pId] - 1
                    if Multi[pId] == 0 then
                        call SetPlayerAlliance(CurPlayer,GetFilterPlayer(),ALLIANCE_SHARED_VISION,flag_add)
                        call SetPlayerAlliance(GetFilterPlayer(),CurPlayer,ALLIANCE_SHARED_VISION,flag_add)
                    endif
                else
                    set Multi[pId] = Multi[pId] + 1
                    call SetPlayerAlliance(CurPlayer,GetFilterPlayer(),ALLIANCE_SHARED_VISION,flag_add)
                    call SetPlayerAlliance(GetFilterPlayer(),CurPlayer,ALLIANCE_SHARED_VISION,flag_add)
                endif
            endif
            return false
        endmethod
        static   method EnumGroup_change takes nothing returns boolean
            if not(flag_add) then
                call SetUnitBonus(GetFilterUnit(),BONUS_SIGHT_RANGE,SIGHT_MALUS)
            else
                if Multi[GetPlayerId(CurPlayer)] == 0 then
                    call SetUnitBonus(GetFilterUnit(),BONUS_SIGHT_RANGE,0)
                endif
            endif
            return false
        endmethod
        static  method EnumForce_enemys takes nothing returns boolean
            set  CurPlayer = GetFilterPlayer()
            call ForceEnumAllies(Force2,CurPlayer,function Spell.EnumForce_change)
            call ForceClear(Force2)
            call GroupEnumUnitsOfPlayer(ENUM_GROUP,CurPlayer,function Spell.EnumGroup_change)
            call GroupClear(ENUM_GROUP)
            return false
        endmethod
        static  method onloop takes nothing returns nothing
            local Spell this
            local integer index = 0
            loop
                exitwhen index >= Count
                set  this  = Active[index]
                set  Time  = Time + TIME_OUT
                if  Time >= GetSpellDuration(Level) then
                    set  flag_add = true
                    static if TESTMODE then
                        call ForceEnumAllies(Force,GetOwningPlayer(Caster),function Spell.EnumForce_enemys)
                        set  CurPlayer = Player(12)
                        call GroupEnumUnitsOfPlayer(ENUM_GROUP,Player(12),function Spell.EnumGroup_change)
                        call GroupClear(ENUM_GROUP)
                    else
                        call ForceEnumEnemies(Force,GetOwningPlayer(Caster),function Spell.EnumForce_enemys)
                        set  CurPlayer = Player(12)
                        call GroupEnumUnitsOfPlayer(ENUM_GROUP,Player(12),function Spell.EnumGroup_change)
                        call GroupClear(ENUM_GROUP)
                    endif
                    call ForceClear(Force)
                    set  Caster = null
                    call release(index)
                else
                    set  index = index + 1
                endif
            endloop
            if  Count == 0 then
                call PauseTimer(Timer)
            endif
        endmethod
        static  method create takes nothing returns Spell
            local Spell this
            if  GetSpellAbilityId() == ABIL_ID then
                set  this = allocate()
                set  Active[Count] = this
                set  Count    = Count + 1
                set  Time     = 0
                set  flag_add = false
                set  Caster   = GetTriggerUnit()
                set  Level    = GetUnitAbilityLevel(Caster,ABIL_ID)
                call DestroyEffect(AddSpecialEffectTarget(CASTER_SFX,Caster,"origin"))
                static if TESTMODE then
                    call ForceEnumAllies(Force,GetOwningPlayer(Caster),function Spell.EnumForce_enemys)
                    set  CurPlayer = Player(12)
                    call GroupEnumUnitsOfPlayer(ENUM_GROUP,Player(12),function Spell.EnumGroup_change)
                    call GroupClear(ENUM_GROUP)
                else
                    call ForceEnumEnemies(Force,GetOwningPlayer(Caster),function Spell.EnumForce_enemys)
                    set  CurPlayer = Player(12)
                    call GroupEnumUnitsOfPlayer(ENUM_GROUP,Player(12),function Spell.EnumGroup_change)
                    call GroupClear(ENUM_GROUP)
                endif
                call ForceClear(Force)
                if   Count == 1 then
                    call TimerStart(Timer,TIME_OUT,true,function Spell.onloop)
                endif
            endif
            return this
        endmethod
        static  method onInit takes nothing returns nothing
            call TriggerRegisterAnyUnitEventBJ(Trigger,EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddAction(Trigger,function Spell.create)
        endmethod
    endstruct
endscope

Keywords:
Darkness, Sight, Moon, Lycan, Lycanthroop
Contents

Noch eine WARCRAFT-III-Karte (Map)

Reviews
21:30, 28th Dec 2009 TriggerHappy: Why are you using forces? Anyways, I suppose the code and spell is decent enough.

Moderator

M

Moderator

21:30, 28th Dec 2009
TriggerHappy:

Why are you using forces?
Anyways, I suppose the code and spell is decent enough.
 
Level 19
Joined
Feb 25, 2009
Messages
2,004
The spell in HoN is instant, and sight range is bigger than in HoN, which doesn't make any sense, 'cause its makes it easier to focus on your hero if you are in danger. It should only show your hero, and I think you can add a function that reduces the target's acquistion range (imo)

Still its a good one. 4/5, vote for approval.

PS: DARKNESS FALLS!
 
Level 14
Joined
Nov 18, 2007
Messages
816
  • Dont inline TriggerRegisterAnyUnitEventBJ
  • Use a group stack. GroupUtils
  • Dont use dummy filters, do whatever you want to do to all enumed units inside those filters.
  • constant handles are a no-go.
  • your recycling algorithm sucks. Tell me one reason why a stable algorithm is required.
  • Changing alliances inside a spell is a bad idea.
 
Level 2
Joined
Jun 20, 2009
Messages
8
@Mortar- : Sry i dont get what you mean with the sight range ( my english sucks )
I tryed it with the acquire range but it didnt work, the creeps still autoattack me :/. Will try it again with 0 acquire range.
@Deaod :
1. Where i inlinded TriggerRegisterAnyUnitEventBJ ? you mean the GUI Triggers ?
2. I didnt want to require more Systems.
3. I dont get what you mean, i dont have a dummy filter ?!? Do you want that i disable the sight thing inside the Filter ?
4. Why ? :O
5. Hm so it (should) gets MUI. Tell me whats wrong with the resycling system pls :)
6. Ye i know but i need to do or i cant break the shared sight
 
Level 2
Joined
Jun 20, 2009
Messages
8
Ok i can change the sightrange loose to 575 so you can only see your unit,
BUT wc3 has a feature that gives you short time vision if you get attacked by a a unit outside your sight range.

Dont want to update you can easily change the value by your own:
JASS:
private constant integer  SIGHT_MALUS = -575

I also checked the SetUnitAcquireRange again and it seems that this functions dont work, my units still attack (tested values: -1,0,1)
 
Level 14
Joined
Nov 18, 2007
Messages
816
1. Where i inlinded TriggerRegisterAnyUnitEventBJ ? you mean the GUI Triggers ?
No, in your initialization function

2. I didnt want to require more Systems.
Bad idea.

3. I dont get what you mean, i dont have a dummy filter ?!? Do you want that i disable the sight thing inside the Filter ?
I want you to actually DO something in the filter, instead of just returning true.

4. Why ? :O
Because Vex's Optimizer screws up the script when you do that, since it inlines constant expressions (and the content of constant variables).

5. Hm so it (should) gets MUI. Tell me whats wrong with the resycling system pls :)
Instead of moving every instance one down, you could just swap the instance you want to recycle with the last active instance in the array.
 
Level 2
Joined
Jun 20, 2009
Messages
8
1. I dont get what i should do ?
Do you think that this is better ?:
JASS:
call TriggerRegisterAnyUnitEventBJ(Trigger,EVENT_PLAYER_UNIT_SPELL_EFFECT)
2. I have uploaded now both
3. I have heard that null Boolexpr do leak so i created a true filter
4. Ok thats a fact i didnt know - > changed
5. :D :D y your right that was stupid -> changed


Update 1.01
 
Top