• 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.

Help

Status
Not open for further replies.
Level 12
Joined
Nov 5, 2007
Messages
730
I want to make a blind spell;when cast it should reduce the targets vision range to 300.Does anyone know how to do this?
 
Level 11
Joined
Feb 22, 2006
Messages
752
Vexorian made a spell tht does exactly that. Wc3campaigns.net is down (actually they are having IP redirect issues) and I've gotten called out for posting the alternate link so here's the code:

JASS:
//**********************************************************************************************
//*
//* Optical Flare
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯
//*     Requires:
//*          - The Pool Class functions
//*          - The Handle Variables functions
//*          - The Optical Flare Ability
//*          - The Optical Flare Buff
//*          - The Optical Flare Sight Destruction Ability
//*          - The Flare Vision unit type
//*          - This Trigger (make sure it points to the right rawcodes)
//*     Note:
//*          - If you have any custom detector ability in your map, you have to add it to the
//*            SetupDetectionPool function at the end of this configuration section.
//*     
//**********************************************************************************************

//==============================================================================================
// Optical Flare Configuration
//
constant function OpticalFlare_SpellId takes nothing returns integer
    return 'A007' //// The Rawcode of the Optical Flare Ability In your map
endfunction

constant function OpticalFlare_BuffId takes nothing returns integer
    return 'B000' //// The Rawcode of the Optical Flare Buff In your map
endfunction

constant function OpticalFlare_SightDestructorSpellId takes nothing returns integer
    return 'A006' //// The Rawcode of the Optical Flare Sight Destructor ability In your map
endfunction

constant function OpticalFlare_FakeSightUnit takes nothing returns integer
    return 'n000' //// The Rawcode of the Optical Flare Vision unit type In your map
endfunction

constant function OpticalFlare_MissileSpeed takes nothing returns integer
    return 1500 //// The missile speed, should be exactly the same as the one used by the ability
endfunction

function SetupDetectionPool takes integer spells returns nothing

    call PoolAddItem(spells,'Agyv') //True Sight (Flying Machine)
    call PoolAddItem(spells,'Atru') //True Sight (Shade)
    call PoolAddItem(spells,'Adtg') //True Sight (Neutral 1)
    call PoolAddItem(spells,'ANtr') //True Sight (Neutral 2)
    call PoolAddItem(spells,'Adts') //Magic Sentry
    call PoolAddItem(spells,'Adt1') //Detector (Sentry Ward)
    call PoolAddItem(spells,'Abdt') //Burrow Detection (fliers)

 //If you have any custom ability that allows passive detection, you must add a line for it
 // Example:

    call PoolAddItem(spells,'A008') //Creep Detection Ability

 // Remove the example from your map, or this ability would remove an ability it is not
 // supposed to remove.

endfunction

//===================================================================================================
function OpticalFlareDetectDetector takes unit u, integer p returns integer
 local integer n=CountItemsInPool(p)
 local integer i
    loop
        exitwhen n==0
        set i=PoolGetItem(p,n)
        if GetUnitAbilityLevel(u,i)>0 then
            return i
        endif
        set n=n-1
    endloop

 return 0
endfunction

function OpticalFlare_GetUnit takes timer t, string s returns unit
    return GetHandleHandle(t,s)
endfunction

function OpticalFlare_Timer takes nothing returns nothing
 local timer t=GetExpiredTimer()
 local unit b=OpticalFlare_GetUnit(t,"b")
 local unit sh=OpticalFlare_GetUnit(t,"sh")
 local real x=GetHandleReal(t,"x")
 local real y=GetHandleReal(t,"y")
 local real nx=GetUnitX(b)
 local real ny=GetUnitY(b)
 local real a=ModuloReal( Atan2(ny-y,nx-x) , 2*bj_PI)
 local real d= SquareRoot(Pow(x-nx,2) +Pow(y-ny,2))
    if ModuloReal(a+bj_PI/4,bj_PI*2)<=bj_PI then
        set d=d*40
    endif
    call SetUnitPosition(sh,nx+d*Cos(a),ny+d*Sin(a) )
    call SetHandleReal(t,"x",nx)
    call SetHandleReal(t,"y",ny)
    call SetUnitFacing(sh,GetUnitFacing(b))
    call SetUnitFlyHeight(sh, GetUnitFlyHeight(b)+120,0)
 set t=null
 set b=null
 set sh=null
endfunction

function OpticalFlare_Effect takes unit b, integer l returns nothing
 local real ac=GetUnitAcquireRange(b)
 local unit sh=CreateUnit( GetOwningPlayer(b), OpticalFlare_FakeSightUnit(), GetUnitX(b), GetUnitY(b), 0)
 local integer abi=OpticalFlareDetectDetector(b, GetStoredInteger(InitGameCache("opticalflare"),"opt","pool") )
 local timer t=CreateTimer()
    call SetUnitPathing(sh,false)
    call UnitRemoveAbility(b, abi )
    call UnitAddAbility(b, OpticalFlare_SightDestructorSpellId() )
    call UnitMakeAbilityPermanent(b,true,OpticalFlare_SightDestructorSpellId())
    call UnitMakeAbilityPermanent(b,true,OpticalFlare_BuffId())
    call SetHandleHandle(t,"b",b)
    call SetHandleHandle(t,"sh",sh)
    call TimerStart(t,0.01,true, function OpticalFlare_Timer )
    loop
        exitwhen IsUnitDeadBJ(b)
        call TriggerSleepAction(0)
        exitwhen not UnitHasBuffBJ(b, OpticalFlare_BuffId() )
    endloop
    call UnitRemoveAbility(b, OpticalFlare_SightDestructorSpellId() )
    call UnitAddAbility(b, abi )
 call RemoveUnit(sh)
 call FlushHandleLocals(t)
 call DestroyTimer(t)
 set t=null
 set sh=null
endfunction

function Trig_Optical_Flare_Actions takes nothing returns nothing
 local unit u=GetTriggerUnit()
 local unit blind=GetSpellTargetUnit()
 local integer l=GetUnitAbilityLevel(u,GetSpellAbilityId() )
    call PolledWait(  SquareRoot(Pow(GetUnitX(u)-GetUnitX(blind),2) + Pow(GetUnitY(u)-GetUnitY(blind),2)  ) / OpticalFlare_MissileSpeed() )
    call OpticalFlare_Effect(blind,l)
 set u=null
 set blind=null
endfunction

function Trig_Optical_Flare_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == OpticalFlare_SpellId()
endfunction

function InitTrig_Optical_Flare takes nothing returns nothing
 local integer i=CreatePool()
    call StoreInteger(InitGameCache("opticalflare"),"opt","pool",i)
    call SetupDetectionPool(i)
    set gg_trg_Optical_Flare = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Optical_Flare, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Optical_Flare, Condition( function Trig_Optical_Flare_Conditions ) )
    call TriggerAddAction( gg_trg_Optical_Flare, function Trig_Optical_Flare_Actions )
endfunction


There's another version of the code using vJass; it's a LOT more efficient:

JASS:
constant function OpticalFlare_SpellId takes nothing returns integer
    return 'A007' //// The Rawcode of the Optical Flare Ability In your map
endfunction

constant function OpticalFlare_BuffId takes nothing returns integer
    return 'B000' //// The Rawcode of the Optical Flare Buff In your map
endfunction

constant function OpticalFlare_SightDestructorSpellId takes nothing returns integer
    return 'A006' //// The Rawcode of the Optical Flare Sight Destructor ability In your map
endfunction

constant function OpticalFlare_FakeSightUnit takes nothing returns integer
    return 'n000' //// The Rawcode of the Optical Flare Vision unit type In your map
endfunction

constant function OpticalFlare_MissileSpeed takes nothing returns integer
    return 1500 //// The missile speed, should be exactly the same as the one used by the ability
endfunction

//=====================================================================

struct flaredata
    unit b  //Unit affected by the buff
    unit sh //The dummy unit
    real x  //]
    real y  ///Previous Position
    
    boolean destroyplease = false
endstruct

globals
    integer array DetectorSpells
    integer array DetectorSpellsN=0
    flaredata  array OpticalFlare_Ar
    integer OpticalFlare_total = 0
    timer OpticalFlare_timer=CreateTimer()
endglobals

function SetupDetectionAbilities returns nothing

    set DetectorSpells[1]='Agyv' //True Sight (Flying Machine)
    set DetectorSpells[2]='Atru' //True Sight (Shade)
    set DetectorSpells[3]='Adtg' //True Sight (Neutral 1)
    set DetectorSpells[4]='ANtr' //True Sight (Neutral 2)
    set DetectorSpells[5]='Adts' //Magic Sentry
    set DetectorSpells[6]='Adt1' //Detector (Sentry Ward)
    set DetectorSpells[7]='Abdt' //Burrow Detection (fliers)

    // set DetectorSpellsN=7 //normally these 7 spells  are needed, uncomment this line if they are just 7

 //If you have any custom ability that allows passive detection, you must add a line for it
 // Example:

    set DetectorSpells[8]='A008' //Creep Detection Ability
    set DetectorSpellsN=8 //We added 8 detector spells to the array, so let's specify that number here.

 // Remove the example for your map (also update the count), or this ability would remove an ability it is not
 // supposed to remove.

endfunction

function OpticalFlareDetectDetector takes unit u returns integer
 local integer i
 local integer n=DetectorSpellsN
    loop
        exitwhen n==0
        set i=DetectorSpells[n]
        if GetUnitAbilityLevel(u,i)>0 then
            return i
        endif
        set n=n-1
    endloop
 return 0
endfunction

function OpticalFlare_Timer takes nothing returns nothing
 local integer i=0
 local flaredata dat
 local real nx
 local real ny
 local real a
 local real d

    loop
        exitwhen i==OpticalFlare_total
        set dat= OpticalFlare_Ar[i]
        if (dat.destroyplease) then
             //This is tricky.
             // We already have the ith flaredata referenced by dat, so we
             // will first remove it from the array, since the order does not matter
             // we can simply move the last flaredata to this position and decrease
             // the total

             set  OpticalFlare_Ar[i]= OpticalFlare_Ar[ OpticalFlare_total - 1]
             set OpticalFlare_total=OpticalFlare_total-1

             //now we are free to destroy the dat
             call dat.destroy() //another way to destroy struct objects.

             //If we don't substract i, it will skip the new object we just moved
             // to the ith position (we are increasing i later)
             set i=i-1

        else //Notice how this ressembles the original expire function
              set nx=GetUnitX(dat.b)
              set ny=GetUnitY(dat.b)
              set a=ModuloReal( Atan2(ny-dat.y , nx-dat.x ) , 2*bj_PI)
              set d= SquareRoot(Pow(dat.x-nx,2) +Pow(dat.y-ny,2))

              if ModuloReal(a+bj_PI/4,bj_PI*2)<=bj_PI then
                  set d=d*40
              endif
              call SetUnitPosition(dat.sh,nx+d*Cos(a),ny+d*Sin(a) )
              set dat.x=nx
              set dat.y=ny
              call SetUnitFacing(    dat.sh,GetUnitFacing( dat.b ))
              call SetUnitFlyHeight( dat.sh, GetUnitFlyHeight( dat.b )+120,0)
        endif
        set i=i+1
    endloop

    if (OpticalFlare_total==0) then
        // let's pause the timer, it is not needed anymore
        call PauseTimer(OpticalFlare_timer)
    endif

endfunction

function OpticalFlare_Effect takes unit b, integer l returns nothing
 local real ac=GetUnitAcquireRange(b)
 local unit sh=CreateUnit( GetOwningPlayer(b), OpticalFlare_FakeSightUnit(), GetUnitX(b), GetUnitY(b), 0)
 local integer abi=OpticalFlareDetectDetector(b )
 local flaredata dat = flaredata.create()
    call SetUnitPathing(sh,false)
    call UnitRemoveAbility(b, abi )
    call UnitAddAbility(b, OpticalFlare_SightDestructorSpellId() )
    call UnitMakeAbilityPermanent(b,true,OpticalFlare_SightDestructorSpellId())
    call UnitMakeAbilityPermanent(b,true,OpticalFlare_BuffId())

    set dat.x=0. //struct fields aren't automatically initialized to 0, unlike handle vars
    set dat.y=0. // It is also possible to make them initialize to a default value inside the struct block
    set dat.b=b
    set dat.sh=sh

    if(OpticalFlare_total==0) then //There are no elements in the array so the timer is inactive
        call TimerStart(OpticalFlare_timer,0.01,true,function OpticalFlare_Timer) //restart it
    endif

    set OpticalFlare_total=OpticalFlare_total+1 //increase the number of elements
    set OpticalFlare_Ar[ OpticalFlare_total-1 ] = dat //add the flaredata to the array, notice that these are arrays
                                                      //that begin with the [0] index...
    loop
        exitwhen IsUnitDeadBJ(b)
        call TriggerSleepAction(0)
        exitwhen not UnitHasBuffBJ(b, OpticalFlare_BuffId() )
    endloop
    call UnitRemoveAbility(b, OpticalFlare_SightDestructorSpellId() )
    call UnitAddAbility(b, abi )

 call RemoveUnit(sh)
 set dat.destroyplease = true //Will send a signal to the timer function so it destroys this object...
 set sh=null
endfunction

function Trig_Optical_Flare_Actions takes nothing returns nothing
 local unit u=GetTriggerUnit()
 local unit blind=GetSpellTargetUnit()
 local integer l=GetUnitAbilityLevel(u,GetSpellAbilityId() )
    call PolledWait(  SquareRoot(Pow(GetUnitX(u)-GetUnitX(blind),2) + Pow(GetUnitY(u)-GetUnitY(blind),2)  ) / OpticalFlare_MissileSpeed() )
    call OpticalFlare_Effect(blind,l)
 set u=null
 set blind=null
endfunction

function Trig_Optical_Flare_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == OpticalFlare_SpellId()
endfunction


function InitTrig_Optical_Flare takes nothing returns nothing
    call SetupDetectionAbilities()
    set gg_trg_Optical_Flare = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Optical_Flare, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Optical_Flare, Condition( function Trig_Optical_Flare_Conditions ) )
    call TriggerAddAction( gg_trg_Optical_Flare, function Trig_Optical_Flare_Actions )
endfunction


Basically, on spell effect the triggers remove sight for the affected unit (so its sight range is effectively 0), but then they also create an invisible dummy unit with a set unit sight range lower than the affected unit to basically "give" the affected unit a sight range. Whenever the affected unit(s) move, the dummy unit(s) move along with them. The whole thing with the detector abilities is to make sure that if the affected unit has any detector abilities (true sight, etc.) that they get removed (otherwise even with sight range turned off the unit would still retain its sight cuz of the ability), and then when the spell wears off the abilities are added again. So make sure, whichever version you use, to update the detector ability ids to match those in your map.

Once again, I did not make this spell, Vexorian did, so for god's sake DON'T GIVE ME CREDIT FOR IT.
 
Last edited:
Level 12
Joined
Nov 5, 2007
Messages
730
Whoa thats pretty complicated.Im horrible at JASS,and i really need this spell,is there an easier way to do this?Or maybe is there anyone who can make edit my map and add this spell?

Anyways +rep for the information,ill try to use it somehow
 
Level 12
Joined
Nov 5, 2007
Messages
730
Im good at triggering but i never even attempted to use JASS...so i dont know what to do with this code...Ill try to improvise,copy paste then make dummy units and all but i dunno how to adjust it to last as long as i want to...
 
Level 11
Joined
Feb 22, 2006
Messages
752
To implement, you need Vexorian's Caster System and Jasshelper. I've got both in my attachments here: http://www.hiveworkshop.com/forums/profile.php?do=editattachments
since wc3campaigns.net is having IP issues right now. Just dl CasterSystem 14.5 and the Jass NewGen pack.

Now, create an ability that can target unit, get rid of all its potential effects like damage, attack speed reduction, etc. You should however, make sure that the ability gives a buff to the target unit. You can keep the special effects too. Change the duration of the spell to however long you want your spell to last.

Next, create a dummy unit with the locust ability and no model file (so you can't see or select it). Change the sight range of the dummy unit to 300.00.

Then, create a trigger named "Optical Flare" (without quotes) and convert entire thing to Custom Text. Then, copy and paste the second set of code I gave you (the one that uses vJass) into that trigger, replacing EVERYTHING that was originally in the trigger's code.

In the SetupDetectionAbilities function, you need to update the script (follow instructions in the comments) to add any custom detection abilities you might have in your map (true sight, etc.). If you dont have any, then don't worry about it.

You will also need to update these functions:

JASS:
constant function OpticalFlare_SpellId takes nothing returns integer
    return 'A007' //// The Rawcode of the Optical Flare Ability In your map
endfunction
constant function OpticalFlare_BuffId takes nothing returns integer
    return 'B000' //// The Rawcode of the Optical Flare Buff In your map
endfunction
constant function OpticalFlare_SightDestructorSpellId takes nothing returns integer
    return 'A006' //// The Rawcode of the Optical Flare Sight Destructor ability In your map
endfunction
constant function OpticalFlare_FakeSightUnit takes nothing returns integer
    return 'n000' //// The Rawcode of the Optical Flare Vision unit type In your map
endfunction
constant function OpticalFlare_MissileSpeed takes nothing returns integer
    return 1500 //// The missile speed, should be exactly the same as the one used by the ability
endfunction


Follow instructions to change them as you wish (if your spell doesn't have a missile, just change the missile speed value to something really high like 5000)
 
Status
Not open for further replies.
Top