• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Better way to illusion allies and move them to you?

Status
Not open for further replies.
Level 13
Joined
Jul 26, 2008
Messages
1,009
So I had an interesting idea. Why not make a Mirror Image type spell and instead of creating illusions of the caster, it creates illusions of heroes visible to the caster and sets them to their original color. This would effectively fool player enemies.

Well I decided to just make the base mirror image, do a global map search, and pick out the heroes visible to have illusion cast on them by a dummy. The dummies would then be moved over to the player.

The problem is, sometimes it doesn't get anything at all, and won't produce an image. Not even of the caster. Is there a more effective way to do what I want?

JASS:
struct DummyAlly

    private static integer SPELLID = 'NeAl'
    private static integer DUMMYID = 'duFA'
    private static unit caster
    private static playercolor PC

    private static method IsHero takes nothing returns boolean
        if IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) and IsVisibleToPlayer(GetUnitX(GetFilterUnit()), GetUnitY(GetFilterUnit()), GetOwningPlayer(.caster)) then//GetPlayerAlliance(GetOwningPlayer(TEMP), GetOwningPlayer(GetFilterUnit()), ALLIANCE_SHARED_VISION)
            debug call BJDebugMsg(GetUnitName(GetFilterUnit()))
            return true
        endif
     return false
    endmethod

    private static method Summoning takes nothing returns nothing
        if GetUnitAbilityLevel(GetSummoningUnit(), DUMMYID) > 0 and IsUnitIllusion(GetSummonedUnit()) and .caster != null and GetUnitAbilityLevel(.caster, SPELLID) > 0 and GetOwningPlayer(.caster) == GetOwningPlayer(GetSummonedUnit()) then
            call SetUnitX(GetSummonedUnit(), GetUnitX(.caster))
            call SetUnitY(GetSummonedUnit(), GetUnitY(.caster))
            call SetUnitColor(GetSummonedUnit(), PC)
        endif
    endmethod

    private static method create takes unit caster, unit u returns thistype
     local thistype this = thistype.allocate()
     local group g = NewGroup()
     local integer i = 0
     local unit dummy
        set .caster = caster
        call GroupEnumUnitsInRect(g, GetWorldBounds(), function thistype.IsHero)
        loop
            set u = GroupPickRandomUnit(g)
            set PC = GetPlayerColor(GetOwningPlayer(.caster))
            set dummy = CreateUnit(GetOwningPlayer(.caster), 'e002', GetUnitX(u), GetUnitY(u), 0)
            call UnitAddAbility(dummy, 'Aloc')
            call UnitAddAbility(dummy, DUMMYID)
            call SetUnitAbilityLevel(dummy, DUMMYID, 3)
            call UnitApplyTimedLife(dummy, 'B000', 2)
            call IssueTargetOrderById(dummy, 852274, u)
            set dummy = null
            set i = i + 1
            exitwhen i >= GetUnitAbilityLevel(.caster, SPELLID)
        endloop
     call ReleaseGroup(g)
     return this
    endmethod

    private static method Actions takes nothing returns nothing
     local unit u = GetTriggerUnit()
        if GetSpellAbilityId() == SPELLID then
            call TriggerSleepAction(0.5)
            call thistype.create(u,null)
        endif
     set u = null
    endmethod

    //===========================================================================
    private static method onInit takes nothing returns nothing
     local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddAction( t, function thistype.Actions )
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SUMMON)
        call TriggerAddAction( t, function thistype.Summoning )
    endmethod

endstruct
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
Try removing that TriggerSleepAction and see if that works.
If you want the spell to have a delay, use a timer to do the delayed actions.

Some tips:

  • You also never destroy the struct. Unless you make the spell delayed with a timer, there's really no need for a struct to be allocated or used.
  • You should add a check for dead heroes to be filtered out.
  • Use IsUnitVisible rather than checking if the point is visible to the caster.
  • Don't use a NewGroup for the group enumeration. Use a global group variable that can be used for all spells like ENUM_GROUP.
  • Use bj_mapInitialPlayableArea instead of GetWorldBounds which returns a new rect each time.
 
Status
Not open for further replies.
Top