| 10-25-2008, 10:29 PM | #1 |
I have a JASS spell that crashes the game. But here is where it goes wierd. It only crashes when another player casts it. ![]() JASS:function Trig_Death_Nova_Conditions takes nothing returns boolean if ( not ( GetSpellAbilityId() == 'A015' ) ) then return false endif return true endfunction function ManaText takes unit u, string s returns nothing call CreateTextTagUnitBJ( "+ "+s,u, 0, 10, 20, 20, 80, 0 ) call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false ) call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 60, 90 ) call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4 ) call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 3 ) endfunction function DeathNovaCheck takes nothing returns boolean local timer t = GetExpiredTimer() if (IsUnitEnemy(GetFilterUnit() , udg_tempPlayer) == FALSE ) then return false endif if (( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == TRUE )) then return false endif if (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) < 1) then return false endif return true endfunction function DeathNovaKnockback takes nothing returns nothing local timer t = GetExpiredTimer() local location l = GetUnitLoc(GetEnumUnit()) local location d = GetUnitLoc(GetHandleUnit(t, "caster")) local real k = GetHandleReal(t, "distance") local location dl = PolarProjectionBJ(l, k, AngleBetweenPoints(d, l)) local effect e = AddSpecialEffectLoc("Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl", l) call SetUnitPositionLoc(GetEnumUnit(), dl) call DestroyEffect(e) call RemoveLocation(l) call RemoveLocation(dl) call RemoveLocation(d) set d = null set l = null set dl = null endfunction function DeathNovaKnockbackTimer takes nothing returns nothing local timer t = GetExpiredTimer() local real d = GetHandleReal(t, "distance") local group g = GetHandleGroup(t, "group") call ForGroup(g, function DeathNovaKnockback) call SetHandleReal(t, "distance", GetHandleReal(t, "distance")-1) if (d < 0) then call DestroyGroup(g) call FlushHandleLocals(t) call DestroyTimer(t) endif endfunction function DeathNovaDamage takes nothing returns nothing local unit u = GetTriggerUnit() local real dam = (GetHeroInt(u, true)*1.5)+60 call DamageText(GetEnumUnit(), I2S(R2I(dam))) call UnitDamageTarget(GetTriggerUnit(), GetEnumUnit(), dam, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS) endfunction function Trig_Death_Nova_Actions takes nothing returns nothing local timer t = CreateTimer() local integer i = 0 local real manarestored = (GetHeroInt(GetTriggerUnit(), true)*2)+25 local location l = GetUnitLoc(GetTriggerUnit()) local group g = CreateGroup() local unit d local location sl set udg_tempPlayer = GetOwningPlayer(GetTriggerUnit()) call SetHandleHandle(t, "caster", GetTriggerUnit()) call SetHandleHandle(t, "group", g) call SetHandleReal(t, "distance", 20) call GroupEnumUnitsInRangeOfLoc(g, l, 350, Condition(function DeathNovaCheck)) call DestroyBoolExpr(Condition(function DeathNovaCheck)) loop exitwhen i > 9 set sl = PolarProjectionBJ(l, 30, i*36) set d = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'hfoo', GetLocationX(l), GetLocationY(l), 0) call UnitAddAbility(d, 'A016') call IssuePointOrder(d, "carrionswarm", GetLocationX(sl), GetLocationY(sl)) call UnitApplyTimedLife(d, 'BTLF', 4) set i = i+1 endloop call ForGroup(g, function DeathNovaDamage) call SetUnitState(GetTriggerUnit(), UNIT_STATE_MANA, GetUnitState(GetTriggerUnit(), UNIT_STATE_MANA)+manarestored) call ManaText(GetTriggerUnit(), I2S( R2I(manarestored) )) call TimerStart(t, 0.03, true, function DeathNovaKnockbackTimer) call RemoveLocation(l) call RemoveLocation(sl) set sl = null set l = null endfunction //=========================================================================== function InitTrig_Death_Nova takes nothing returns nothing set gg_trg_Death_Nova = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Death_Nova, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Death_Nova, Condition( function Trig_Death_Nova_Conditions ) ) call TriggerAddAction( gg_trg_Death_Nova, function Trig_Death_Nova_Actions ) endfunction This is what the spell is supposed to do: Conjures a powerful dark explosion at the location of the caster, dealing damage and knocking back all nearby enemies. In addition, the caster gains mana. Damage Dealt: [ INT x 1.5 ] + 60 Mana Restored: [ INT x 2 ] + 25 Cooldown: 180 seconds It works, but only for Player 1. For some reason, when I'm Player 6 it doesn't work. If you are going to say "why are you using BJs noob", then atleast tell me how to convert it to use without BJs. I'd like to know why it crashes more than how to make it work more efficiently... call GroupEnumUnitsInRangeOfLoc(g, l, 350, Condition(function DeathNovaCheck)) call DestroyBoolExpr(Condition(function DeathNovaCheck)) The error is here. When I remove these 2 lines, the spell works fine (except it doesn't). I tried to replace it with this: call GroupEnumUnitsInRangeOfLoc(g, l, 350, null) And it still didn't work. HALP! |
| 10-25-2008, 10:40 PM | #2 |
EDIT: Okay was too fast ;) EDIT2: On first glance I can tell you have a lot of things that can be improved in your code. But the only thing I can make out that would cause a crash is the "GetExpiredTimer" in a function that isn't called by a timer (DeathNovaCheck,DeathNovaKnockback). New Code: (WIP ^^) JASS:globals group udg_KnockbackUnit real udg_KnockbackDist endglobals function Trig_Death_Nova_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A015' endfunction function ManaText takes unit u, string s returns nothing call CreateTextTagUnitBJ( "+ "+s,u, 0, 10, 20, 20, 80, 0 ) call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false ) call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 60, 90 ) call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 4 ) call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 3 ) endfunction function DeathNovaCheck takes nothing returns boolean return IsUnitEnemy(GetFilterUnit() , udg_tempPlayer) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == TRUE ) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > .405) endfunction function DeathNovaKnockback takes nothing returns nothing local real xe = GetUnitX(GetEnumUnit()) local real ye = GetUnitY(GetEnumUnit()) local real xc = GetUnitX(udg_KnockbackUnit) local real yc = GetUnitY(Gudg_KnockbackUnit) local real k = udg_KnockbackDist local real angle = Atan2(yc-ye,xc-xe) call DestroyEffect(AddSpecialEffect(xe,ye,"Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl")) set xe = xe+Cos(angle)*k set ye = ye+Sin(angle)*k call SetUnitPosition(GetEnumUnit(), xe, ye) endfunction function DeathNovaKnockbackTimer takes nothing returns nothing local timer t = GetExpiredTimer() local real d = GetHandleReal(t, "distance") local group g = GetHandleGroup(t, "group") set udg_KnockbackUnit = GetHandleUnit(t,"caster") set udg_KnockbackDist = GetHandleReal(t,"distance") call ForGroup(g, function DeathNovaKnockback) call SetHandleReal(t, "distance", GetHandleReal(t, "distance")-1) if (d < 0) then call DestroyGroup(g) call FlushHandleLocals(t) call DestroyTimer(t) endif set g = null endfunction function DeathNovaDamage takes nothing returns nothing local unit u = GetTriggerUnit() local real dam = (GetHeroInt(u, true)*1.5)+60 call DamageText(GetEnumUnit(), I2S(R2I(dam))) call UnitDamageTarget(GetTriggerUnit(), GetEnumUnit(), dam, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS) endfunction function Trig_Death_Nova_Actions takes nothing returns nothing local timer t = CreateTimer() local unit caster = GetTriggerUnit() local integer i = 0 local real manarestored = (GetHeroInt(caster, true)*2)+25 local real x = GetUnitX(caster) local real y = GetUnitY(caster) local real xt local real yt local group g = CreateGroup() local unit d set udg_tempPlayer = GetOwningPlayer(caster) call SetHandleHandle(t, "caster", caster) call SetHandleHandle(t, "group", g) call SetHandleReal(t, "distance", 20) call GroupEnumUnitsInRangeOfLoc(g, l, 350, Condition(function DeathNovaCheck)) loop exitwhen i > 9 set xt = x+Cos(i*36*(bj_PI/180))*30 set yt = y+Cos(i*36*(bj_PI/180))*30 set d = CreateUnit(udg_tempPlayer, 'hfoo', x, y, 0) call UnitAddAbility(d, 'A016') call IssuePointOrder(d, "carrionswarm", xt, yt) call UnitApplyTimedLife(d, 'BTLF', 4) set i = i+1 endloop call ForGroup(g, function DeathNovaDamage) call SetUnitState(caster, UNIT_STATE_MANA, GetUnitState(caster, UNIT_STATE_MANA)+manarestored) call ManaText(caster, I2S( R2I(manarestored) )) call TimerStart(t, 0.03, true, function DeathNovaKnockbackTimer) set caster = null set d = null set g = null endfunction //=========================================================================== function InitTrig_Death_Nova takes nothing returns nothing set gg_trg_Death_Nova = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Death_Nova, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Death_Nova, Condition( function Trig_Death_Nova_Conditions ) ) call TriggerAddAction( gg_trg_Death_Nova, function Trig_Death_Nova_Actions ) endfunction It might work now but you should really take a look into JNGP and some newer attachment systems. good night from me |
| 10-26-2008, 06:57 PM | #3 |
I fixed it by changing the order of variable declaration and handles. On a side note, how do you make a unit deal 0 - 0 damage? |
| 10-26-2008, 11:53 PM | #4 |
Set it's damage range to -1–-1 and then make the number of sides of dice 1. I think. |
