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

[JASS] Dummy unit doesnt cast spell...

Status
Not open for further replies.
Level 13
Joined
Aug 26, 2004
Messages
150
Hi Ihav troubles with a dummy spell, this is the code I did to order the dummy to target a point:

JASS:
function DUMMYCAST2POINT takes unit realCaster, location spawnLoc, integer abilityRawCode, location attackLoc, real waitTime, string ORDER, real expirationTimer returns nothing 
   local unit dummyCaster
   call TriggerSleepAction(waitTime)
   call CreateNUnitsAtLoc( 1, 'n001', GetOwningPlayer(realCaster), spawnLoc, 180 ) 
   set dummyCaster = GetLastCreatedUnit()
   call UnitApplyTimedLife( dummyCaster, 'BTLF', expirationTimer )
   call UnitAddAbility( dummyCaster, abilityRawCode )
   call IssuePointOrderLoc( dummyCaster, ORDER, attackLoc )
   call UnitRemoveAbility( dummyCaster, abilityRawCode )
   call RemoveLocation(attackLoc)
   call RemoveLocation(spawnLoc)
   set attackLoc = null
   set spawnLoc = null
   set realCaster = null
   set dummyCaster = null
endfunction

and I call it in this function:

JASS:
function Trig_Elemental_Bolt_Actions takes nothing returns nothing
    local unit caster = GetAttacker()
    local unit target = GetTriggerUnit()
    local location loccaster = GetUnitLoc(caster)
    local location loctarget = GetUnitLoc(target)

    call DUMMYCAST2POINT(caster,loccaster, 'AOsh', loctarget, 0.00, "impale", 15.00)  

    call RemoveLocation(loccaster)
    set loccaster = null
    set target = null
    set caster = null
endfunction

problem is that it doesnt cast the spell, ive given the dummy unit a visible model to see if it atleast works and the function created the dummy unit but it doesnt cast the spell it just stands there until the expiration timer end n it dies. This is happening everytime I use this function.
 
Level 2
Joined
Sep 21, 2005
Messages
27
First thought...does impale target a unit or a location :?:

I imagine you'll get bad lag dynamically adding abilities to dummy units like that. "Bad" as in unnoticible unless you do it hundreds of times per second, but usually there's a jolt the first time such a spell is cast. For all I know, adding the ability dynamically is where your problem is. Does impale show up when you select the unit?

Also, might want to eliminate crappy location usage, at least if you're a code nerd and actually care...

JASS:
function DUMMYCAST2POINT takes unit UnitCasting, unit UnitAttacked, real waitTime, real expirationTimer, integer abilityRawCode, string ORDER returns nothing 
	local player CasterPlayer = GetOwningPlayer(UnitCasting)
	local unit DummyCaster

	call TriggerSleepAction(waitTime)
	set DummyCaster = CreateUnit(CasterPlayer, 'n001', GetUnitX(UnitCasting), GetUnitY(UnitCasting), 270.00)

	call UnitApplyTimedLife(DummyCaster, 'BTLF', expirationTimer)
	call UnitAddAbility(DummyCaster, abilityRawCode)
	call IssuePointOrder(DummyCaster, ORDER, GetUnitX(UnitAttacked), GetUnitY(UnitAttacked))
	call UnitRemoveAbility(DummyCaster, abilityRawCode)
endfunction

function Trig_Elemental_Bolt_Actions takes nothing returns nothing
	local unit Caster = GetAttacker()
	local unit Target = GetTriggerUnit()

	call DUMMYCAST2POINT(Caster, Target, 0.00, 15.00, 'AOsh', "impale")

	set Caster = null
	set Target = null
endfunction

And just for interest, with IDs (and Code Nerd style):
JASS:
function DUMMYCAST2POINT takes unit UnitCasting, unit UnitAttacked, real waitTime, real expirationTimer, integer abilityRawCode, integer Order returns nothing 
	local player CasterPlayer = GetOwningPlayer(UnitCasting)
	local unit DummyCaster

	call TriggerSleepAction(waitTime)
	set DummyCaster = CreateUnit(CasterPlayer, 'n001', GetUnitX(UnitCasting), GetUnitY(UnitCasting), 270.00)

	call UnitApplyTimedLife(DummyCaster, 'BTLF', expirationTimer)
	call UnitAddAbility(DummyCaster, abilityRawCode)
	call IssuePointOrderById(DummyCaster, Order, GetUnitX(UnitAttacked), GetUnitY(UnitAttacked))
	call UnitRemoveAbility(DummyCaster, abilityRawCode)

	set CasterPlayer = null
	set DummyCaster = null
endfunction

function Trig_Elemental_Bolt_Actions takes nothing returns nothing
	local unit Caster = GetAttacker()
	local unit Target = GetTriggerUnit()

	call DUMMYCAST2POINT(Caster, Target, 0.00, 15.00, 'AOsh', 852555)

	set Caster = null
	set Target = null
endfunction
 
Level 13
Joined
Aug 26, 2004
Messages
150
Hi, thankz for replying,
And no I dont notice any lag(my pc isnt the best in speed btw).
I actually had solved my problem. The thing was that the dummy actually casted the ability(units got slowed(that was the effect)) but there was no art for it(I mean it didnt show the art missile or special I think), I imagine this is because UnitRemoveAbility() removes the ability too fast, but Im not really sure, I deleted that sentence n it worked fine.
But thankz for pointing me that about locations, why do people hate them so much? I understand that the less function calls is the best rigth? Ill fix all the location in my spell(But Ive heard that some locations r unavoidable), althought itll be a boring taks...anyway thank u, can u explain me more about IDs? why should I use them?
 
Level 2
Joined
Sep 21, 2005
Messages
27
You don't have to use IDs. The only time you would use them is if you're calling something over and over and it needs to be efficient(TD pathing with 500+ units). Sending a number to a function is quicker than sending a string, but not by enough that it matters at all if the spell is being called even every second.

I said "Code Nerd" style, because most code nerds strive for absolute efficiency, regardless of the time taken to implement it. :p Another reason not to use IDs, is because I couldn't find them listed anywhere.

Locations seem to memory leak - not much, but enough to be annoying in extremely long games where you deal with lots. Aside from that...you're creating an object to store two numbers. This object has its own functions that are required to clean it up, and probably some internal ones too....to store two numbers.

It just seems like a waste to use a clunkier storage method that results in function calling when you can simply get a single number. Calling GetUnitX() or GetUnitY() results in more code, but also faster execution since it still only adds up to two functions. Creating a location and then removing it later and nullifying it is also a couple functions and maybe allocating some memory and doing internal variable stuff too(though variables don't seem to slow JASS down as much as Javascript).

>> And no I dont notice any lag(my pc isnt the best in speed btw).

You aren't calling the spell 100 times per second. :) I've spoken with several people that make larger maps, and once they get big enough you start hunting for ways to make them run smoother.
 
Level 3
Joined
Mar 2, 2006
Messages
40
Suggestion

I suggest using the following code :
JASS:
function DummyCastPoint takes unit FakeCaster, real TargetX, real TargetY, integer AbilId, string Order, integer level, real SpellDelay returns nothing
    local player owner = GetOwningPlayer(FakeCaster)
    local location point = GetUnitLoc(FakeCaster)
    local unit dummy = CreateUnitAtLoc(owner, DummyId(), point, 270.00)
    call UnitAddAbility(dummy, AbilId)
    call SetUnitAbilityLevel(dummy, AbilId, level)
    call IssuePointOrder(dummy, Order, TargetX, TargetY)
    call TriggerSleepAction(SpellDelay)
    call RemoveUnit(dummy)
    set owner = null
    set point = null
endfunction

function DummyCastPointLoc takes unit FakeCaster, location TargetLoc, integer AbilId, string Order, integer level, real SpellDelay returns nothing
    call DummyCastPoint(FakeCaster, GetLocationX(TargetLoc), GetLocationY(TargetLoc), AbilId, Order, level, SpellDelay)
endfunction
It's greatly improved.
 
Status
Not open for further replies.
Top