• 🏆 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!

[JASS] Help For Project 2

Status
Not open for further replies.
Hi guys, i have a quick question. This is the following spell:

JASS:
function LightningBolt_Conds takes nothing returns boolean
    return GetSpellAbilityId() == 'A008'
endfunction
//===================================================
function LB_InstantKill_Conds takes nothing returns boolean
    local integer level = GetUnitAbilityLevel(GetTriggerUnit(),'A008')
    local real chance 
    if level == 1 then
        set chance = 100
    elseif level == 2 then
        set chance = 0
    elseif level == 3 then 
        set chance = 0
    elseif level == 4 then 
        set chance = 0.25
    elseif level == 5 then 
        set chance = 1
    endif
    return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LightningBolt_Acts takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local unit dummy = CreateUnit( GetOwningPlayer(caster), 'h000', GetUnitX(target), GetUnitY(target), 0)

    if GetUnitAbilityLevel(caster, 'A008') == 1 then 
        call UnitAddAbility(dummy, 'A009')
        call SetUnitAbilityLevel(dummy, 'A009', 1) 
        call IssueTargetOrder(dummy, "slow", target)
        call UnitApplyTimedLife(dummy, 'BTLF', 2)
        if LB_InstantKill_Conds >0 then
            call KillUnit(target)
        endif
    elseif GetUnitAbilityLevel(caster, 'A008') == 2 then
        call UnitAddAbility(dummy, 'A009')
        call SetUnitAbilityLevel(dummy, 'A009', 2) 
        call IssueTargetOrder(dummy, "slow", target)
        call UnitApplyTimedLife(dummy, 'BTLF', 2)
    elseif GetUnitAbilityLevel(caster, 'A008') == 3 then   
        call UnitAddAbility(dummy, 'A009')
        call SetUnitAbilityLevel(dummy, 'A009', 3) 
        call IssueTargetOrder(dummy, "slow", target)
        call UnitApplyTimedLife(dummy, 'BTLF', 2)
    elseif GetUnitAbilityLevel(caster, 'A008') == 4 then   
        call UnitAddAbility(dummy, 'A009')
        call SetUnitAbilityLevel(dummy, 'A009', 4) 
        call IssueTargetOrder(dummy, "slow", target)
        call UnitApplyTimedLife(dummy, 'BTLF', 2)
    elseif GetUnitAbilityLevel(caster, 'A008') == 5 then   
        call UnitAddAbility(dummy, 'A009')
        call SetUnitAbilityLevel(dummy, 'A009', 5) 
        call IssueTargetOrder(dummy, "slow", target)
        call UnitApplyTimedLife(dummy, 'BTLF', 2)
    endif
    set caster = null
    set target = null
    set dummy = null        
endfunction
//===========================================================================
function InitTrig_Lightning_Bolt takes nothing returns nothing
    local trigger LightningBolt = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( LightningBolt, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( LightningBolt, Condition( function LightningBolt_Conds ) )
    call TriggerAddAction( LightningBolt, function LightningBolt_Acts )
    set LightningBolt = null
endfunction

Can you please explain me why the LB_InstantKill_Conds is computed as a variable, when it is a method ??? What am i doing wrong ?
 
Hi guys. Now I have other 2 problems =(...
Here they are:

JASS:
//============ WRONG CODE, WHY ??? 
    local location m = GetUnitLoc(target) + 100
//============ END OF WRONG CODE

and:

JASS:
//============= WRONG  CODE WHY?
      set enor = AddSpecialEffectLoc("String of my effect", m)
//============= END OF WRONG CODE

Together this two codes cause me:
1 - bad combination for binary operator
2 - cannot convert real to location

Well, i just want create the effect 100 meters away from the target unit. But i can't !

How can i fix this ??
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
1. Don't use locations, use coordinates. Didn't I already explain this to you?
NewX = OldX + distance*Cos(direction)
NewY = OldY + distance*Sin(direction)
But if you really want to use locations.. you could use this:
JASS:
local location m = Location(GetUnitX(target)+100*Cos(someangle),GetUnitY(target)+100*Sin(someangle))

2- That function sucks for using locations, but meh... probably an error in the surrounding lines of that code. Paste me both lines surrounding that one.
 
Level 17
Joined
Jun 17, 2007
Messages
1,433
Hi guys. Now I have other 2 problems =(...
Here they are:

JASS:
//============ WRONG CODE, WHY ??? 
    local location m = GetUnitLoc(target) + 100
//============ END OF WRONG CODE
and:

JASS:
//============= WRONG  CODE WHY?
      set enor = AddSpecialEffectLoc("String of my effect", m)
//============= END OF WRONG CODE
Together this two codes cause me:
1 - bad combination for binary operator
2 - cannot convert real to location

Well, i just want create the effect 100 meters away from the target unit. But i can't !

How can i fix this ??
The problem is in the first one.
Remember point offset by in GUI? That's what has to be done, it isn't as simple as your method.
JASS:
local real r = your directiom
local real l = your base location before being offset
set udg_x = PolarProjectionBJ(l), 100.00, r)
//be sure to remove the leaks properly(or use coordinates) and remove the BJ.
 
Wow, thx for all you help guys. Now the problem is no more !
rep+ for you all !

And Hyndi, yes you have already explained me this... sorry for asking. Thing is that I just got back in jass like 2 weeks ago, and so I forgot some stuff (my first problem that i posted here, was because i was not using the "call" words ... so you can see how bad i was lol).

Anyway your efforts to help me are not invalid, you know how many problems i have with this kind of this, but just for you to record, i am learning which post you do, I am not ignoring them.

oh, locations are just easier to use, but i use coordinates every time i can.
Btw, I also used
JASS:
call RemoveLocation(m)
and
JASS:
set m = null
in the end of the code, to prevent any leaks.

Thx for your help guys, now the spell is complete =) (i think, don't know yet lol)
 
Hi guys. Well, here I have the "working version of the code". The reason why I am posting here is because I think you guys can help me optimize it.

I will remove all BJ's from the code, and shorten the chance conditions a little bit, but I think that's all I can do.
If you have any other optimizing idea to apply in my code, please post it, as long as it doesn't force me to remake all the spell again.

JASS:
function LightningBolt_Conds takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction
//===================================================
function LB_InstantKill_Conds takes nothing returns boolean
    local integer level = GetUnitAbilityLevel(GetTriggerUnit(),'A002')
    local real chance 
    if level == 1 then
        set chance = 0
    elseif level == 2 then
        set chance = 0
    elseif level == 3 then 
        set chance = 0
    elseif level == 4 then 
        set chance = 0.5
    elseif level == 5 then 
        set chance = 1
    endif
    return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LB_DoubleDamage_Conds takes nothing returns boolean
    local integer level = GetUnitAbilityLevel(GetTriggerUnit(),'A002')
    local real chance 
    if level == 1 then
        set chance = 0
    elseif level == 2 then
        set chance = 4
    elseif level == 3 then 
        set chance = 6
    elseif level == 4 then 
        set chance = 8
    elseif level == 5 then 
        set chance = 10
    endif
    return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LB_DoNothing_Conds takes nothing returns boolean
    local integer level = GetUnitAbilityLevel(GetTriggerUnit(),'A002')
    local real chance 
    if level == 1 then
        set chance = 0
    elseif level == 2 then
        set chance = 0
    elseif level == 3 then 
        set chance = 0.25
    elseif level == 4 then 
        set chance = 0.5
    elseif level == 5 then 
        set chance = 1
    endif
    return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LightningBolt_Acts takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local unit dummy = CreateUnit( GetOwningPlayer(caster), 'h000', GetUnitX(target), GetUnitY(target), 0)
    local integer damage = 75 * GetUnitAbilityLevel(caster, 'A002')
    local texttag t = CreateTextTag()
    local effect enor
    local real randDistance = GetRandomReal(8, 160) 
    local real randAngle = GetRandomReal(0, 360)
    local location m = Location( GetUnitX(target) + randDistance * Cos(randAngle), GetUnitY(target) + randDistance * Sin(randAngle))
    if GetUnitAbilityLevel(caster, 'A002') == 1 then  
        set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
        call UnitAddAbility(dummy, 'A000')
        call UnitAddAbility(dummy, 'A001')
        call SetUnitAbilityLevel(dummy, 'A000', 1)        
        call SetUnitAbilityLevel(dummy, 'A001', 1) 
        call IssueTargetOrder(dummy, "thunderbolt", target)
        call TriggerSleepAction(0.5)
        call IssueTargetOrder(dummy, "slow", target)        
        call UnitApplyTimedLife(dummy, 'BTLF', 2)
        call UnitDamageTarget(caster, target, damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)   
        call DestroyEffect(enor)
    elseif GetUnitAbilityLevel(caster, 'A002') == 2 then
        set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
        call UnitAddAbility(dummy, 'A000')
        call UnitAddAbility(dummy, 'A001')
        call SetUnitAbilityLevel(dummy, 'A000', 2)        
        call SetUnitAbilityLevel(dummy, 'A001', 2) 
        call IssueTargetOrder(dummy, "thunderbolt", target)
        call TriggerSleepAction(0.5)
        call IssueTargetOrder(dummy, "slow", target)        
        call UnitApplyTimedLife(dummy, 'BTLF', 2)
        if LB_DoubleDamage_Conds() == true then 
            call UnitDamageTarget(caster, target, 2 * damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
            call SetTextTagText(t, "Doubled", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 80, 80, 255, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )   
            call DestroyEffect(enor)
            call TriggerSleepAction(2.00)                
            call DestroyTextTag(t)
        else
            call UnitDamageTarget(caster, target, damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
        endif
        call DestroyEffect(enor)        
    elseif GetUnitAbilityLevel(caster, 'A002') == 3 then   
        if LB_DoubleDamage_Conds() == false and LB_DoNothing_Conds() == true then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoubleDamage_Conds() == true and LB_DoNothing_Conds() == false then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call UnitAddAbility(dummy, 'A000')
            call UnitAddAbility(dummy, 'A001')
            call SetUnitAbilityLevel(dummy, 'A000', 3)        
            call SetUnitAbilityLevel(dummy, 'A001', 3) 
            call IssueTargetOrder(dummy, "thunderbolt", target)
            call TriggerSleepAction(0.5)
            call IssueTargetOrder(dummy, "slow", target)        
            call UnitApplyTimedLife(dummy, 'BTLF', 2) 
            call UnitDamageTarget(caster, target, 2 * damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
            call SetTextTagText(t, "Doubled", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 80, 80, 255, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )   
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoubleDamage_Conds() == false and LB_DoNothing_Conds() == false then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call UnitAddAbility(dummy, 'A000')
            call UnitAddAbility(dummy, 'A001')
            call SetUnitAbilityLevel(dummy, 'A000', 3)        
            call SetUnitAbilityLevel(dummy, 'A001', 3) 
            call IssueTargetOrder(dummy, "thunderbolt", target)
            call TriggerSleepAction(0.5)
            call IssueTargetOrder(dummy, "slow", target)        
            call UnitApplyTimedLife(dummy, 'BTLF', 2)
            call UnitDamageTarget(caster, target, damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
            call DestroyEffect(enor)
        elseif LB_DoubleDamage_Conds() == true and LB_DoNothing_Conds() == true then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        endif
    elseif GetUnitAbilityLevel(caster, 'A002') == 4 then   
        if LB_DoNothing_Conds() == true and LB_DoubleDamage_Conds() == true and LB_InstantKill_Conds() == true then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == true and LB_DoubleDamage_Conds() == true and LB_InstantKill_Conds() == false then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == true and LB_DoubleDamage_Conds() == false and LB_InstantKill_Conds() == true then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == true and LB_DoubleDamage_Conds() == false and LB_InstantKill_Conds() == false then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == false and LB_DoubleDamage_Conds() == true and LB_InstantKill_Conds() == true then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call KillUnit(target)
            call SetTextTagText(t, "Fried", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 250, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == false and LB_DoubleDamage_Conds() == true and LB_InstantKill_Conds() == false then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call UnitAddAbility(dummy, 'A000')
            call UnitAddAbility(dummy, 'A001')
            call SetUnitAbilityLevel(dummy, 'A000', 4)        
            call SetUnitAbilityLevel(dummy, 'A001', 4) 
            call IssueTargetOrder(dummy, "thunderbolt", target)
            call TriggerSleepAction(0.5)
            call IssueTargetOrder(dummy, "slow", target)        
            call UnitApplyTimedLife(dummy, 'BTLF', 2) 
            call UnitDamageTarget(caster, target, 2 * damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
            call SetTextTagText(t, "Doubled", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 80, 80, 255, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )   
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == false and LB_DoubleDamage_Conds() == false and LB_InstantKill_Conds() == true then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call KillUnit(target)
            call SetTextTagText(t, "Fried", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 250, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == false and LB_DoubleDamage_Conds() == false and LB_InstantKill_Conds() == false then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call UnitAddAbility(dummy, 'A000')
            call UnitAddAbility(dummy, 'A001')
            call SetUnitAbilityLevel(dummy, 'A000', 4)        
            call SetUnitAbilityLevel(dummy, 'A001', 4) 
            call IssueTargetOrder(dummy, "thunderbolt", target)
            call TriggerSleepAction(0.5)
            call IssueTargetOrder(dummy, "slow", target)        
            call UnitApplyTimedLife(dummy, 'BTLF', 2) 
            call UnitDamageTarget(caster, target, damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
            call DestroyEffect(enor)
        endif
    elseif GetUnitAbilityLevel(caster, 'A002') == 5 then   
        if LB_DoNothing_Conds() == true and LB_DoubleDamage_Conds() == true and LB_InstantKill_Conds() == true then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == true and LB_DoubleDamage_Conds() == true and LB_InstantKill_Conds() == false then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == true and LB_DoubleDamage_Conds() == false and LB_InstantKill_Conds() == true then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == true and LB_DoubleDamage_Conds() == false and LB_InstantKill_Conds() == false then
            set enor = AddSpecialEffectLoc("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", m)
            call SetTextTagText(t, "Missed", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 0, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == false and LB_DoubleDamage_Conds() == true and LB_InstantKill_Conds() == true then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call KillUnit(target)
            call SetTextTagText(t, "Fried", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 250, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == false and LB_DoubleDamage_Conds() == true and LB_InstantKill_Conds() == false then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call UnitAddAbility(dummy, 'A000')
            call UnitAddAbility(dummy, 'A001')
            call SetUnitAbilityLevel(dummy, 'A000', 5)        
            call SetUnitAbilityLevel(dummy, 'A001', 5) 
            call IssueTargetOrder(dummy, "thunderbolt", target)
            call TriggerSleepAction(0.5)
            call IssueTargetOrder(dummy, "slow", target)        
            call UnitApplyTimedLife(dummy, 'BTLF', 2) 
            call UnitDamageTarget(caster, target, 2 * damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
            call SetTextTagText(t, "Doubled", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 80, 80, 255, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )   
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == false and LB_DoubleDamage_Conds() == false and LB_InstantKill_Conds() == true then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call KillUnit(target)
            call SetTextTagText(t, "Fried", .023 )   
            call SetTextTagPosUnit( t, caster, 0 )
            call SetTextTagColor(t, 255, 250, 0, 255 )   
            call SetTextTagPermanent(t, false)
            call SetTextTagVelocity( t, 0, .0277 )    
            call TriggerSleepAction(2.00)
            call DestroyTextTag(t)
            call DestroyEffect(enor)
        elseif LB_DoNothing_Conds() == false and LB_DoubleDamage_Conds() == false and LB_InstantKill_Conds() == false then
            set enor = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
            call UnitAddAbility(dummy, 'A000')
            call UnitAddAbility(dummy, 'A001')
            call SetUnitAbilityLevel(dummy, 'A000', 5)        
            call SetUnitAbilityLevel(dummy, 'A001', 5) 
            call IssueTargetOrder(dummy, "thunderbolt", target)
            call TriggerSleepAction(0.5)
            call IssueTargetOrder(dummy, "slow", target)        
            call UnitApplyTimedLife(dummy, 'BTLF', 2) 
            call UnitDamageTarget(caster, target, damage, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
            call DestroyEffect(enor)
        endif
    endif
    call RemoveLocation(m)
    set m = null
    set caster = null
    set target = null
    set dummy = null 
    set t = null
    set enor = null     
endfunction
//===========================================================================
function InitTrig_Lightning_Bolt takes nothing returns nothing
    local trigger LightningBolt = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( LightningBolt, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( LightningBolt, Condition( function LightningBolt_Conds ) )
    call TriggerAddAction( LightningBolt, function LightningBolt_Acts )
    set LightningBolt = null
endfunction
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Want me to optimize the formulae too? I didn't because you may want to change them, but if those're set in stone, I can easily optimize them.

JASS:
function LightningBolt_Conds takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction
//===================================================
function LB_InstantKill_Conds takes integer level returns boolean
    local real chance 
    if level == 1 then
        set chance = 0
    elseif level == 2 then
        set chance = 0
    elseif level == 3 then 
        set chance = 0
    elseif level == 4 then 
        set chance = 0.5
    elseif level == 5 then 
        set chance = 1
    endif
    return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LB_DoubleDamage_Conds takes integer level returns boolean
    local real chance
    if level == 1 then
        set chance = 0
    elseif level == 2 then
        set chance = 4
    elseif level == 3 then 
        set chance = 6
    elseif level == 4 then 
        set chance = 8
    elseif level == 5 then 
        set chance = 10
    endif
    return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LB_DoNothing_Conds takes integer level returns boolean
    local real chance 
    if level == 1 then
        set chance = 0
    elseif level == 2 then
        set chance = 0
    elseif level == 3 then 
        set chance = 0.25
    elseif level == 4 then 
        set chance = 0.5
    elseif level == 5 then 
        set chance = 1
    endif
    return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LightningBolt_Acts takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local integer i = GetUnitAbilityLevel(GetTriggerUnit(),'A002')
    local unit dummy = CreateUnit( GetOwningPlayer(caster), 'h000', GetUnitX(target), GetUnitY(target), 0)
    local texttag t = CreateTextTag()
    local effect e   
    call SetTextTagPosUnit( t, caster, 0 )   
    call SetTextTagPermanent(t, false)
    call SetTextTagVelocity( t, 0, .0277 )
    if not LB_DoNothing_Conds(i) then
        set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
    endif
    if LB_DoNothing_Conds(i) then
        set e = AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", GetUnitX(target) + GetRandomReal(8, 160) * Cos(GetRandomReal(0, 2*bj_PI)),GetUnitY(target) + GetRandomReal(8, 160) * Sin(GetRandomReal(0, 2*bj_PI)))
        call SetTextTagText(t, "Missed", .023 )
        call SetTextTagColor(t, 255, 0, 0, 255 )
    elseif LB_InstantKill_Conds(i) then
        call KillUnit(target)
        call SetTextTagText(t, "Fried", .023 )
        call SetTextTagColor(t, 255, 250, 0, 255 )
    else
        if LB_DoubleDamage_Conds(i) then
            call UnitDamageTarget(caster, target, 75 * i, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
            call SetTextTagText(t, "Doubled", .023 )
            call SetTextTagColor(t, 80, 80, 255, 255 )
        endif
        call UnitAddAbility(dummy, 'A000')
        call UnitAddAbility(dummy, 'A001')
        call SetUnitAbilityLevel(dummy, 'A000', 1)        
        call SetUnitAbilityLevel(dummy, 'A001', 1) 
        call IssueTargetOrder(dummy, "thunderbolt", target)
        call TriggerSleepAction(.5)
        call IssueTargetOrder(dummy, "slow", target)        
        call UnitApplyTimedLife(dummy, 'BTLF', 2)
        call UnitDamageTarget(caster, target, 75 * i, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
    endif  
    call DestroyEffect(e)
    set caster = null
    set target = null
    set dummy = null
    set e = null
    call TriggerSleepAction(2)
    call DestroyTextTag(t) 
    set t = null    
endfunction

function InitTrig_Lightning_Bolt takes nothing returns nothing
    set gg_trg_Lightning_Bolt = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Lightning_Bolt, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Lightning_Bolt, Condition( function LightningBolt_Conds ) )
    call TriggerAddAction( gg_trg_Lightning_Bolt, function LightningBolt_Acts )
endfunction
 
MM, well, thx PP for you effort...
However I just wanted to know the wrong stuff in my code, I didn't want you to optimize it for me =S

Thing is that I intent to post this spell in the spell section, and every line of code must be commented for Py, and for everyone. That's why I just wanted to know what was wrong, so than I could change it and understand it.

Still thx for your optimization... However, it does have some problems.
1 - When the chance is miss, 2 thunders are created, instead of only 1
2 - When the chance is double damage, the unit gets hit by the thunder, runs away, and then its stunned.
3 - When a unit its fried, the yellow text "fried" goes up to the plus infinite (this means that it keeps ascending and only disappears a lot of time after)
4 - Your optimization also has the former problem my code has: I still don't know if all chances are being evaluated.

And Although Py won't need a versatile version of the code (he may use a "stone" version) I would like my code to be versatile so other people may use it for other things.
So, yes, you can create a "stone" improved code, but that will be for Py only.

Still, thx a lot. How is the ABC thing going ?

Oh, btw, +rep
 
Thing is that I intent to post this spell in the spell section, and every line of code must be commented for Py, and for everyone. That's why I just wanted to know what was wrong, so than I could change it and understand it.
You don't have to comment every single line, just the ones that people might get a bit confused about.

How is the ABC thing going ?

Turns out the vJass compiler doesn't like campaigns. So if I want to use vJass I'll have to do some extra fiddling around in order to get the vJass compiler to, well, compile the code correctly.
 
You don't have to comment every single line, just the ones that people might get a bit confused about.

Well, I usually play safe. I can understand things that you cannot and vice-versa. So it makes perfect sense to comment every line of code, because I never know who is going to read it.

Mm, and about vJASS, are you sure it is 100% needed ? I don't know much about it, but it seems that its causing too many problems already. Anyway, your choice =)
 
Level 5
Joined
Dec 17, 2007
Messages
145
/Agree

vJASS is massively helpful though, nobody can deny it. However, at the rate Vex and all of them are going, it'll be a full-blown coding language soon. I mean, some of the features are just useless unless you're cohadar and like making massive systems that end world hunger for menial tasks.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
FP, "If you have any other optimizing idea to apply in my code, please post it, as long as it doesn't force me to remake all the spell again." - your post with the code.

1 - When the chance is miss, 2 thunders are created, instead of only 1
That is physically impossible, one thunder is only created in the exact opposite condition of the other.

Oh wait, I see why. Chance is reapplied since the function is called again. Fixed.

2 - When the chance is double damage, the unit gets hit by the thunder, runs away, and then its stunned.
You had the wait in there yourself... Just remove it if you don't want that to happen.

3 - When a unit its fried, the yellow text "fried" goes up to the plus infinite (this means that it keeps ascending and only disappears a lot of time after)
Makes no sense, the texttag uses the same code as the others.

4 - Your optimization also has the former problem my code has: I still don't know if all chances are being evaluated.
There are only 3 chances, and they all are.

[jass=Optimized code with optimized formulae]function LightningBolt_Conds takes nothing returns boolean
return GetSpellAbilityId() == 'A002'
endfunction
//===================================================
function LB_InstantKill_Conds takes integer level returns boolean
return GetRandomReal(1, 100) <= .5*(level-3)
endfunction
//===================================================
function LB_DoubleDamage_Conds takes integer level returns boolean
local real chance = 2*level + 2
if level = 1 then
set chance = 0
endif
return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LB_DoNothing_Conds takes integer level returns boolean
local real chance = .25*Pow(level-2,2)
if level < 3 then then
set chance = 0
endif
return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LightningBolt_Acts takes nothing returns nothing
local unit caster = GetTriggerUnit()
local unit target = GetSpellTargetUnit()
local integer i = GetUnitAbilityLevel(GetTriggerUnit(),'A002')
local unit dummy = CreateUnit( GetOwningPlayer(caster), 'h000', GetUnitX(target), GetUnitY(target), 0)
local texttag t = CreateTextTag()
local effect e
local boolean b = LB_DoNothing_Conds(i)
call SetTextTagPosUnit( t, caster, 0 )
call SetTextTagPermanent(t, false)
call SetTextTagVelocity( t, 0, .0277 )
if not b then
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
endif
if b then
set e = AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", GetUnitX(target) + GetRandomReal(8, 160) * Cos(GetRandomReal(0, 2*bj_PI)),GetUnitY(target) + GetRandomReal(8, 160) * Sin(GetRandomReal(0, 2*bj_PI)))
call SetTextTagText(t, "Missed", .023 )
call SetTextTagColor(t, 255, 0, 0, 255 )
elseif LB_InstantKill_Conds(i) then
call KillUnit(target)
call SetTextTagText(t, "Fried", .023 )
call SetTextTagColor(t, 255, 250, 0, 255 )
else
if LB_DoubleDamage_Conds(i) then
call UnitDamageTarget(caster, target, 75 * i, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
call SetTextTagText(t, "Doubled", .023 )
call SetTextTagColor(t, 80, 80, 255, 255 )
endif
call UnitAddAbility(dummy, 'A000')
call UnitAddAbility(dummy, 'A001')
call SetUnitAbilityLevel(dummy, 'A000', 1)
call SetUnitAbilityLevel(dummy, 'A001', 1)
call IssueTargetOrder(dummy, "thunderbolt", target)
call TriggerSleepAction(.5)
call IssueTargetOrder(dummy, "slow", target)
call UnitApplyTimedLife(dummy, 'BTLF', 2)
call UnitDamageTarget(caster, target, 75 * i, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
endif
call DestroyEffect(e)
set caster = null
set target = null
set dummy = null
set e = null
call TriggerSleepAction(2)
call DestroyTextTag(t)
set t = null
endfunction

function InitTrig_Lightning_Bolt takes nothing returns nothing
set gg_trg_Lightning_Bolt = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( gg_trg_Lightning_Bolt, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Lightning_Bolt, Condition( function LightningBolt_Conds ) )
call TriggerAddAction( gg_trg_Lightning_Bolt, function LightningBolt_Acts )
endfunction[/code]
 
You had the wait in there yourself... Just remove it if you don't want that to happen.
I know I had that problem once, but i fixed that problem long time before I decided to post the spell here.
In my code that does not happen, because the unit is first stunned, then takes all the damage it has to take, and only after that it is slowed.
The unit never runs in my code, and I proved that truth several tests.
However it does happen in yours. I will try to see the origin of the problem and see if I can fix it.

Makes no sense, the texttag uses the same code as the others.
Fixed.

There are only 3 chances, and they all are.
Only 3 !? I make no idea how many my code had LoL. Anyway it's a relieve to know.

Oh, and btw, your code has 2 compiling errors.

[jass=It must be an if == 1 because it is a comparison]function LB_DoubleDamage_Conds takes integer level returns boolean
local real chance = 2*level + 2
if level = 1 then
set chance = 0
endif
return GetRandomReal(1, 100) <= chance
endfunction[/code]

[jass=You repeat then 2 times, it must be only 1]function LB_DoNothing_Conds takes integer level returns boolean
local real chance = .25*Pow(level-2,2)
if level < 3 then then
set chance = 0
endif
return GetRandomReal(1, 100) <= chance
endfunction[/code]


EDIT

I know I had that problem once, but i fixed that problem long time before I decided to post the spell here.
In my code that does not happen, because the unit is first stunned, then takes all the damage it has to take, and only after that it is slowed.
The unit never runs in my code, and I proved that truth several tests.
However it does happen in yours. I will try to see the origin of the problem and see if I can fix it.

Yep, as I though, the problem is in your code and not in mine.
I already found the origin of the problem.

The unit has time to run before being double damaged because, you only create the dummy and order it to stun in the final part of your code.
When creating my code I had in consideration the minimum time needed to make the dummy cast the two abilities (that's why I have a 0.5 trigger sleep action in the middle of the code), and the time to create and order the unit (that why it is the first thing being created and ordered even before the damage and the text).
However, in your code, the dummy is created to late.

I tried to fix that but my tentative didn't work so good (the unit got stunned and slowed even if the chance was "miss"), so I must ask for your help to fix your code, because I can't.
I also made an evaluation and now I think I can comment your code. However, even knowing what it does and when, it is far from my capabilities to change it and still make it work.
I guess that the ball is on your side once more.

Btw, how did you find those formulas !? You have to use a special graphic program or something rit !?


EDIT

[jass=Btw, I did a very small optimization to your own optimization (lol). I eradicated Bj's from your code and fixed your syntax mistakes]function LightningBolt_Conds takes nothing returns boolean
return GetSpellAbilityId() == 'A002'
endfunction
//===================================================
function LB_InstantKill_Conds takes integer level returns boolean
return GetRandomReal(1, 100) <= .5*(level-3)
endfunction
//===================================================
function LB_DoubleDamage_Conds takes integer level returns boolean
local real chance = 2*level + 2
if level == 1 then
set chance = 0
endif
return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LB_DoNothing_Conds takes integer level returns boolean
local real chance = .25*Pow(level-2,2)
if level < 3 then
set chance = 0
endif
return GetRandomReal(1, 100) <= chance
endfunction
//===================================================
function LightningBolt_Acts takes nothing returns nothing
local unit caster = GetTriggerUnit()
local unit target = GetSpellTargetUnit()
local integer i = GetUnitAbilityLevel(caster,'A002')
local unit dummy = CreateUnit( GetOwningPlayer(caster), 'h000', GetUnitX(target), GetUnitY(target), 0)
local texttag t = CreateTextTag()
local effect e
local boolean b = LB_DoNothing_Conds(i)
call SetTextTagPosUnit( t, caster, 0 )
call SetTextTagPermanent(t, false)
call SetTextTagVelocity( t, 0, .0277 )
if not b then
set e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", target, "origin")
endif
if b then
set e = AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl", GetUnitX(target) + GetRandomReal(8, 160) * Cos(GetRandomReal(0, 2 * 3.14159)),GetUnitY(target) + GetRandomReal(15, 150) * Sin(GetRandomReal(0, 2* 3.14159)))
call SetTextTagText(t, "Missed", .023 )
call SetTextTagColor(t, 255, 0, 0, 255 )
elseif LB_InstantKill_Conds(i) then
call KillUnit(target)
call SetTextTagText(t, "Fried", .023 )
call SetTextTagColor(t, 255, 250, 0, 255 )
else
if LB_DoubleDamage_Conds(i) then
call UnitDamageTarget(caster, target, 75 * i, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
call SetTextTagText(t, "Doubled", .023 )
call SetTextTagColor(t, 80, 80, 255, 255 )
endif
call UnitAddAbility(dummy, 'A000')
call UnitAddAbility(dummy, 'A001')
call SetUnitAbilityLevel(dummy, 'A000', 1)
call SetUnitAbilityLevel(dummy, 'A001', 1)
call IssueTargetOrder(dummy, "thunderbolt", target)
call TriggerSleepAction(.5)
call IssueTargetOrder(dummy, "slow", target)
call UnitApplyTimedLife(dummy, 'BTLF', 2)
call UnitDamageTarget(caster, target, 75 * i, true, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null)
endif
call DestroyEffect(e)
set caster = null
set target = null
set dummy = null
set e = null
call TriggerSleepAction(2)
call DestroyTextTag(t)
set t = null
endfunction
//==========================================================
function InitTrig_Lightning_Bolt takes nothing returns nothing
local integer index = 0
set gg_trg_Lightning_Bolt = CreateTrigger()
loop
exitwhen index == 16
call TriggerRegisterPlayerUnitEvent(gg_trg_Lightning_Bolt, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index +1
endloop
call TriggerAddCondition( gg_trg_Lightning_Bolt, Condition( function LightningBolt_Conds ) )
call TriggerAddAction( gg_trg_Lightning_Bolt, function LightningBolt_Acts )
endfunction[/code]
 
Last edited:
Yes it does...

20./25. != 20/25, try it yourself.

Whoa!? Unexpected .... I really have to try that.

Also, as for the compiling errors, whoops, I did that on mah mac, so I didn't have a compiler.

I use JassCraft, I can post here for you to download. It is actually a good compiler. But np, I fixed the syntax errors in the post I made.
About the spell, can you fix the errors I reported ? plz ?
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Whoops, not what I meant. I didn't see that was a division, I wanted to say that:

JASS:
local integer i = 2
local real r = 2.
local real sum = i + r


is equal to:

JASS:
local integer i = 2
local real r = 2
local real sum = i + r
 
LOL.... well, when a unit gets hit by the thunder it has a chance of getting double damage.
If that chance is false, no problem, everything works fine.

But if that chance is true, the unit runs away, and only after running it gets stunned. this is the bug I am talking about, a bug that my code does NOT have.

Anyway, please read also the other comments, they explain the bug.

Also, thx for all the help. you will get +rep after this, that's for sure lol !!!

See the edits in my posts in page 2. I made very small changes in your code.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Well, I have no idea what would cause that only upon double damage - look at the code, only a texttag is changed and damage is dealt with the double damage bit.

Oh wait, I think I know what's causing it - the damage from the Double Damage is dealt before the wait, while other damage is dealt afterwards. Just make your Storm Bolt have 10000 missile speed, and make sure the dummy's Art - Cast Backswing and Art - Cast Delay are both set to 0.000, that should fix it.

I did a very small optimization to your own optimization (lol). I eradicated Bj's from your code
Expanding TriggerRegisterAnyUnitEventBJ is the opposite of optimization in almost every circumstance -.-
 
Just make your Storm Bolt have 10000 missile speed, and make sure the dummy's Art - Cast Backswing and Art - Cast Delay are both set to 0.000, that should fix it.
The missile speed is already at maximum speed. I am not sure about the others Art fields, but I will check them as soon as possible.

Expanding TriggerRegisterAnyUnitEventBJ is the opposite of optimization in almost every circumstance -.-
LOL. I though you told me Bj's were evil and slow (except in very rare circumstances).
Anyway, I don't think that replacing that Bj is such a bad idea, it's just a few more lines of code.
I also edited the syntax mistakes you had =P LOL, It took me about 30 secs =P, but I still did it ... just for fun :piru:
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
LOL. I though you told me Bj's were evil and slow (except in very rare circumstances).
Anyway, I don't think that replacing that Bj is such a bad idea, it's just a few more lines of code.
I also edited the syntax mistakes you had =P LOL, It took me about 30 secs =P, but I still did it ... just for fun
They are evil and slower in most cases, but

  • This one will only be called once.
  • The overhead is minimal in such a large call anyways.
  • You also waste a significant amount of map space expanding a big bj like that.
  • Yes, the syntax mistakes were because I edited it without a compiler ;)
 
Mmm I changed some fields and your version steel doesn't work ....
Btw, I can't find "Art - Cast Delay" field in the "Object - Unit Editor", so I can't set it to zero.
Can you tell me where that field is so I can test the spell ?

Oh, Py, I don't know if you know, but in advance I already started making a mini-map to place into the spell section. It will be something like Hero Wars, but with only 1 hero, The hero with the spell.

More news as soon as PP posts the field info.
 
Status
Not open for further replies.
Top