| 02-15-2007, 03:11 AM | #1 |
Well erm im making a spell and there is an error that i cant find :o JASS:function Trig_spell_spell takes nothing returns nothing local real r = I2R(GetUnitUserData(GetLastCreatedUnit())) / 2 if r == 0 then call PauseTimer(GetExpiredTimer()) call DestroyTimer(GetExpiredTimer()) call RemoveUnit( GetLastCreatedUnit()) return endif call SetUnitX( GetLastCreatedUnit(), (GetUnitX(GetTriggerUnit()) + r * Cos(GetUnitFacing(GetLastCreatedUnit()) * bj_DEGTORAD))) call SetUnitY( GetLastCreatedUnit(), (GetUnitY(GetTriggerUnit()) + r * Sin(GetUnitFacing(GetLastCreatedUnit()) * bj_DEGTORAD))) call SetUnitUserData( GetLastCreatedUnit(), R2I(r) - 1 ) call SetUnitFacing( GetLastCreatedUnit(), GetUnitFacing(GetLastCreatedUnit()) + 1 ) endfunction function Trig_spell_Conditions takes nothing returns boolean if GetSpellAbilityId() == 'A000' then return true endif return false endfunction function Trig_spell_Actions takes nothing returns nothing local location l = Location(GetRectCenterX(bj_mapInitialPlayableArea), GetRectCenterY(bj_mapInitialPlayableArea)) local timer t = CreateTimer() call CreateUnitAtLocSaveLast(GetOwningPlayer(GetTriggerUnit()), 'h000', l, 0) call SetUnitUserData( GetLastCreatedUnit(), 800 ) call TimerStart(t, 0.03, true, function Trig_spell_spell) call RemoveLocation(l) set l = null endfunction //=========================================================================== function InitTrig_spell takes nothing returns nothing set gg_trg_spell = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_spell, EVENT_PLAYER_UNIT_SPELL_CAST ) call TriggerAddCondition( gg_trg_spell, Condition( function Trig_spell_Conditions ) ) call TriggerAddAction( gg_trg_spell, function Trig_spell_Actions) endfunction The unit creates, the dummy unit who is created circles around the middle where he was created, not where the triggering unit is for some reason. I've no idea why it does that. The coordinates are obviously set to triggering unit + distance ( r ) |
| 02-15-2007, 03:22 AM | #2 |
You are using GetLastCreatedUnit() and GetTriggerUnit() in your timer callback function. Those units aren't passed to that function. You need to attach them to the timer using handle variables, or set them to global variables, or use some other method to store them. |
| 02-15-2007, 03:59 AM | #3 |
He's right. Also, that code is inefficient; here it is optimized and with globals. Handles would require a bit more work. JASS:function Trig_spell_spell takes nothing returns nothing local unit u = udg_My_Moving_Unit //In case it changes local unit u2 = udg_My_Casting_Unit //In case it changes local real r = I2R(GetUnitUserData(u)) / 2 if r == 0 then call PauseTimer(GetExpiredTimer()) call DestroyTimer(GetExpiredTimer()) call RemoveUnit(u) return endif call SetUnitX( u, (GetUnitX(u2) + r * Cos(GetUnitFacing(u) * bj_DEGTORAD)) ) call SetUnitY( u, (GetUnitY(u2) + r * Sin(GetUnitFacing(u) * bj_DEGTORAD)) ) call SetUnitUserData( u, R2I(r) - 1 ) call SetUnitFacing(u, (GetUnitFacing(u) + 1)) set u = null set u2 = null endfunction function Trig_spell_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A000' endfunction function Trig_spell_Actions takes nothing returns nothing local real x = GetRectCenterX(GetPlayableMapRect()) //Maybe this isn't what you're looking for... local real y = GetRectCenterY(GetPlayableMapRect()) local timer t = CreateTimer() set udg_My_Casting_Unit = GetTriggerUnit() set udg_My_Moving_Unit = CreateUnit(GetOwningPlayer(udg_My_Casting_Unit), 'h000', l, 0) call SetUnitUserData( udg_My_Moving_Unit, 800 ) call TimerStart(t, 0.03, true, function Trig_spell_spell) //This might leak a Timer, though I'm not sure if it's a handle (I don't think it is) endfunction //=========================================================================== function InitTrig_spell takes nothing returns nothing set gg_trg_spell = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_spell, EVENT_PLAYER_UNIT_SPELL_CAST ) call TriggerAddCondition( gg_trg_spell, Condition( function Trig_spell_Conditions ) ) call TriggerAddAction( gg_trg_spell, function Trig_spell_Actions) endfunction Just throwing another idea out there: wouldn't this be possible with a loop? EDIT: Oh... minimum wait time on TriggerSleepAction() >< |
| 02-15-2007, 04:05 AM | #4 |
You could also do it this way using structs and a global timer. JASS:globals spelldata array spelldata_ar integer spelldata_total = 0 timer spell_timer = CreateTimer() endglobals struct spelldata unit caster unit new endstruct function Trig_spell_spell takes nothing returns nothing local spelldata dat local real r local integer i=0 loop exitwhen i == spelldata_total set dat = spelldata_ar[i] set r = I2R(GetUnitUserData(dat.new))/2 if r ==0 then call RemoveUnit(dat.new) set spelldata_ar[i] = spelldata_ar[spelldata_total-1] set spelldata_total = spelldata_total -1 call dat.destroy() set i = i -1 else call SetUnitX(dat.new, (GetUnitX(dat.caster) + r * Cos(GetUnitFacing(dat.new) * bj_DEGTORAD))) call SetUnitY(dat.new, (GetUnitY(dat.caster) + r * Sin(GetUnitFacing(dat.new) * bj_DEGTORAD))) call SetUnitUserData(dat.new, R2I(r) -1) call SetUnitFacing(dat.new, GetUnitFacing(dat.new) + 1) endif set i = i + 1 endloop if spelldata_total == 0 then call PauseTimer(spell_timer) endif endfunction function Trig_spell_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A000' endfunction function Trig_spell_Actions takes nothing returns nothing local spelldata dat = spelldata.Create() local location l = Location(GetRectCenterX(bj_mapInitialPlayableArea), GetRectCenterY(bj_mapInitialPlayableArea)) if spelldata_total == 0 then call TimerStart(spell_timer, .03, TRUE, function Trig_spell_spell) endif set dat.new = CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), 'h000', l, 0) set dat.caster = GetTriggerUnit() call SetUnitUserData(dat.new, 800 ) set spelldata_ar[spelldata_total] = dat set spelldata_total = spelldata_total+1 call RemoveLocation(l) set l = null endfunction //=========================================================================== function InitTrig_spell takes nothing returns nothing set gg_trg_spell = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_spell, EVENT_PLAYER_UNIT_SPELL_CAST ) call TriggerAddCondition( gg_trg_spell, Condition( function Trig_spell_Conditions ) ) call TriggerAddAction( gg_trg_spell, function Trig_spell_Actions) endfunction |
| 02-15-2007, 10:32 PM | #5 |
I do not want to use a global, is there any way i can do this without using CSCACHE, and globals? EDIT: Last credit unit works perfectly, it moves the unit and it does it the right angle, its just triggering unit i guess. |
| 02-16-2007, 01:37 AM | #6 |
If you were to do it without globals and CScache, it would not be MUI. Is this just an effect, or is it an actual spell? |
| 02-16-2007, 03:29 AM | #7 |
its a spell, and you mean quite the opposite. If i used globals or cscache it would be not be mui, othervise it is. its same as telling me that if i used locals it would not be mui. |
| 02-16-2007, 03:51 AM | #8 |
It is impossible to use only locals for this spell, you need some way to let the timer callback function know what units to manipulate. Globals may or may not let your spell be MUI. It depends on how you use them. CScache will definitely make it MUI. The code I posted above allows for MUI. If you don't like structs you can implement the same thing using unit arrays instead. |
| 02-16-2007, 05:41 AM | #9 |
The thing is i do not know what structs are. Do you require any extra scripts or globals for them? how do they work, link me to a tutorial if thats needed. |
| 02-16-2007, 05:53 AM | #10 |
