Need Help Optimizing Trigger

CrackUps

New Member
Reaction score
7
Whenever i fire this trigger my FPS drops and does not return to normal

Here's the trigger:
JASS:
function PRMove takes nothing returns nothing
    local timer PRTimer = GetExpiredTimer()
    local unit Caster = GetHandleUnit(PRTimer,"Caster"+I2S(H2I(PRTimer)))
    local unit Phoenix = GetHandleUnit(PRTimer,"Phoenix"+I2S(H2I(PRTimer)))
    local integer DC = GetHandleInt(PRTimer,"DC"+I2S(H2I(PRTimer)))
    local player Owner = GetOwningPlayer(Caster)
    local real z = GetHandleReal(PRTimer,"z"+I2S(H2I(PRTimer)))
    local location loc = GetUnitLoc(Phoenix)
    local real x = GetLocationX(loc) + 20.00 * Cos(z * bj_DEGTORAD)
    local real y = GetLocationY(loc) + 20.00 * Sin(z * bj_DEGTORAD)
    local group DmgTargets = GetHandleGroup(PRTimer, "DT"+I2S(H2I(PRTimer)))
    local group AlreadyDamage = GetHandleGroup(PRTimer, "AD"+I2S(H2I(PRTimer)))
    local integer safety = 0
    local unit Target
    if DC <= 1000 then
        call SetUnitPosition(Phoenix,x,y)
        call SetUnitFacing(Phoenix,z)
        set DC = DC + 20
        call SetHandleInt(PRTimer,"DC"+I2S(H2I(PRTimer)),DC)
        if DmgTargets == null then
            set DmgTargets = CreateGroup()
        endif
        if AlreadyDamage == null then
            set AlreadyDamage = CreateGroup()
        endif
        call GroupEnumUnitsInRangeOfLoc(DmgTargets, GetUnitLoc(Phoenix), 400, null)
        call GroupRemoveGroup(AlreadyDamage, DmgTargets)
        loop
            set Target = FirstOfGroup(DmgTargets)
            if not (IsUnitAlly(Target, GetOwningPlayer(Caster)) == false) and (IsUnitType(Target, UNIT_TYPE_STRUCTURE) == false) then
                    call GroupRemoveUnit(DmgTargets, Target)
                    set Target = FirstOfGroup(DmgTargets)
            else
            exitwhen Target == null or safety > 1000
            call UnitDamageTarget(Caster, Target, GetHeroAgi(Caster, true) * 5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            call GroupAddUnit(AlreadyDamage, Target)
            call GroupRemoveUnit(DmgTargets, Target)
            set safety = safety + 1
            endif
        endloop
        call SetHandleHandle(PRTimer, "DT"+I2S(H2I(PRTimer)), DmgTargets)
        call SetHandleHandle(PRTimer, "AD"+I2S(H2I(PRTimer)), AlreadyDamage)
        set DmgTargets = null
    else
        call SetUnitAnimation(Caster,"attack")
        call SetUnitExploded(Phoenix, true)
        call KillUnit(Phoenix)
        call SetUnitPosition(Caster,x,y)
        call SetUnitFacing(Caster,z)
        call ShowUnit(Caster,true)
        if (GetLocalPlayer() == Owner) then
            call SelectUnit(Caster, true)
        endif
        call DestroyTimer(PRTimer)
        call DestroyGroup(DmgTargets)
        call DestroyGroup(AlreadyDamage)
        call RemoveLocation(loc)
        set DmgTargets = null
        set AlreadyDamage = null
        set PRTimer = null
        set Caster = null
        set Phoenix = null
        set Owner = null
        set loc = null
    endif
endfunction

function PRDelay takes nothing returns nothing
    local timer DelayTimer = GetExpiredTimer()
    local timer PRTimer = CreateTimer()
    local integer DC = 0
    local unit Caster = GetHandleUnit(DelayTimer,"Caster"+I2S(H2I(DelayTimer)))
    local player Owner = GetOwningPlayer(Caster)
    local real x = GetUnitX(Caster)
    local real y = GetUnitY(Caster)
    local real z = GetUnitFacing(Caster)
    local unit Phoenix = CreateUnit(Owner,'hphx',x,y,z)
    call ShowUnit(Caster,false)
    call SetHandleHandle(PRTimer,"Caster"+I2S(H2I(PRTimer)),Caster)
    call SetHandleHandle(PRTimer,"Phoenix"+I2S(H2I(PRTimer)),Phoenix)
    call SetHandleReal(PRTimer,"z"+I2S(H2I(PRTimer)),z)
    call SetHandleInt(PRTimer,"DC"+I2S(H2I(PRTimer)),DC)
    call TimerStart(PRTimer,0.02,true,function PRMove)
    call DestroyTimer(DelayTimer)
    set DelayTimer = null
    set Caster = null
    set Owner = null
    set Phoenix = null
endfunction

function PRSetup takes nothing returns nothing
    local timer DelayTimer = CreateTimer()
    local unit Caster = GetTriggerUnit()
    call SetHandleHandle(DelayTimer,"Caster"+I2S(H2I(DelayTimer)),Caster)
    call TimerStart(DelayTimer,0.20,false,function PRDelay)
    set Caster = null
endfunction

function PRAbilCheck takes nothing returns boolean
    if GetSpellAbilityId() == 'A001' then
        call PRSetup()
    else
    endif
    return true
endfunction

//===========================================================================
function InitTrig_Phoenix_Rush takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function PRAbilCheck ) )
    set t = null
endfunction


Why is this and how can i prevent it?
 

wellwish3r

wishes wells.
Reaction score
52
a unit comes into X range of the Phoenix, deal 5*caster agility to the unit that comes into range.
 
L

Lanan

Guest
That would be so much simpler with GUI i believe, but its just a matter of what way of programming you like the most.
 

shinami

Redirect your complaints to the nearest wall
Reaction score
47
How's it easier in GUI?

You just pick every unit within X of some point, and do Damage Target... Also if i'm correct what you want is for every cast for its damage to increase?

Well then you'd have to set an Integer to get +1 every time you cast it, and then add an action which damages the unit for Real Agility Of Triggering Unit*SpellCastTimeInteger
 

CrackUps

New Member
Reaction score
7
Ok i've created this ability but whenever i run it in game my fps drops and does not return to what it was so for example it drops from 60 to 55 and stays at 55 i cast the ability again and it drops further to 50.

Here's the triggers:
JASS:
function DealDmg takes nothing returns nothing
    local trigger dmg = GetTriggeringTrigger()
    local unit Caster = GetHandleUnit(dmg,"Caster"+I2S(H2I(dmg)))    
    call UnitDamageTarget( Caster, GetTriggerUnit(), 200, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
endfunction

function UnitCheck takes nothing returns boolean
    local trigger dmg = GetTriggeringTrigger()
    local unit Caster = GetHandleUnit(dmg,"Caster"+I2S(H2I(dmg)))
    if IsPlayerAlly(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(Caster)) == false and IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == false then
        call DealDmg()
    endif
    return true
endfunction

function USMove takes nothing returns nothing
    local timer USTimer = GetExpiredTimer()
    local trigger dmg = GetHandleTrigger(USTimer,"dmg"+I2S(H2I(USTimer)))
    local unit Caster = GetHandleUnit(USTimer,"Caster"+I2S(H2I(USTimer)))
    local unit Phoenix = GetHandleUnit(USTimer,"Phoenix"+I2S(H2I(USTimer)))
    local integer DC = GetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)))
    local player Owner = GetOwningPlayer(Caster)
    local real z = GetHandleReal(USTimer,"z"+I2S(H2I(USTimer)))
    local location loc = GetUnitLoc(Phoenix)
    local real x = GetLocationX(loc) + 20.00 * Cos(z * bj_DEGTORAD)
    local real y = GetLocationY(loc) + 20.00 * Sin(z * bj_DEGTORAD)
    local real Dist = GetHandleReal(USTimer,"Dist"+I2S(H2I(USTimer)))
    if DC <= Dist then
        call SetUnitPosition(Phoenix,x,y)
        call SetUnitFacing(Phoenix,z)
        set DC = DC + 20
        call SetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)),DC)
    else
        call SetUnitAnimation(Caster,"attack")
        call SetUnitExploded(Phoenix, true)
        call KillUnit(Phoenix)
        call SetUnitPosition(Caster,x,y)
        call SetUnitFacing(Caster,z)
        call ShowUnit(Caster,true)
        if (GetLocalPlayer() == Owner) then
            call SelectUnit(Caster, true)
        endif
        call DestroyTimer(USTimer)
        call DestroyTrigger(dmg)
    endif
endfunction

function USDelay takes nothing returns nothing
    local timer DelayTimer = GetExpiredTimer()
    local timer USTimer = CreateTimer()
    local trigger dmg = CreateTrigger()
    local integer DC = 0
    local unit Caster = GetHandleUnit(DelayTimer,"Caster"+I2S(H2I(DelayTimer)))
    local player Owner = GetOwningPlayer(Caster)
    local real x = GetUnitX(Caster)
    local real y = GetUnitY(Caster)
    local real z = GetUnitFacing(Caster)
    local unit Phoenix = CreateUnit(Owner,'hphx',x,y,z)
    local real Dist = GetHandleReal(DelayTimer,"Dist"+I2S(H2I(DelayTimer)))
    call ShowUnit(Caster,false)
    call SetHandleHandle(USTimer,"dmg"+I2S(H2I(USTimer)),dmg)
    call SetHandleReal(USTimer,"Dist"+I2S(H2I(USTimer)),Dist)
    call SetHandleHandle(USTimer,"Caster"+I2S(H2I(USTimer)),Caster)
    call SetHandleHandle(dmg,"Caster"+I2S(H2I(dmg)),Caster) 
    call SetHandleHandle(USTimer,"Phoenix"+I2S(H2I(USTimer)),Phoenix)
    call SetHandleReal(USTimer,"z"+I2S(H2I(USTimer)),z)
    call SetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)),DC)
    call DestroyTimer(DelayTimer)
    call TimerStart(USTimer,0.02,true,function USMove)
    call TriggerRegisterUnitInRangeSimple( dmg, 300.00, Phoenix )
    call TriggerAddCondition(dmg, Condition(function UnitCheck) )
endfunction

function USSetup takes nothing returns nothing
    local timer DelayTimer = CreateTimer()
    local integer DC = 0
    local unit Caster = GetTriggerUnit()
    local player Owner = GetOwningPlayer(Caster)
    local location locA = GetUnitLoc(Caster)
    local location locB = GetSpellTargetLoc()
    local real Dist = DistanceBetweenPoints(locA,locB)
    call SetHandleReal(DelayTimer,"Dist"+I2S(H2I(DelayTimer)),Dist)
    call SetHandleHandle(DelayTimer,"Caster"+I2S(H2I(DelayTimer)),Caster)
    call TimerStart(DelayTimer,0.20,false,function USDelay)
endfunction

function USAbilCheck takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        call USSetup()
    endif
    return true
endfunction

//===========================================================================
function InitTrig_Ultimate_Sacrifice takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    local integer index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( t, Condition( function USAbilCheck ) )
    set t = null
endfunction


Help me please:thup:
 

saw792

Is known to say things. That is all.
Reaction score
280
JASS:
function USFilter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetTriggerPlayer()) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false)
endfunction

function USMove takes nothing returns nothing
    local timer USTimer = GetExpiredTimer()
    local unit Caster = GetHandleUnit(USTimer,"Caster"+I2S(H2I(USTimer)))
    local unit Phoenix = GetHandleUnit(USTimer,"Phoenix"+I2S(H2I(USTimer)))
    local integer DC = GetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)))
    local player Owner = GetOwningPlayer(Caster)
    local real z = GetHandleReal(USTimer,"z"+I2S(H2I(USTimer)))
    local location loc = GetUnitLoc(Phoenix)
    local real x = GetLocationX(loc) + 20.00 * Cos(z * bj_DEGTORAD)
    local real y = GetLocationY(loc) + 20.00 * Sin(z * bj_DEGTORAD)
    local group d = GetHandleGroup(USTimer, "d"+I2S(H2I(USTimer)))
    local group g = CreateGroup()
    local integer safety = 0
    local unit f
    if DC <= 1000 then
        call SetUnitPosition(Phoenix,x,y)
        call SetUnitFacing(Phoenix,z)
        set DC = DC + 20
        call SetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)),DC)
        if d == null then
            set d = CreateGroup()
        endif
        call GroupEnumUnitsInRange(g, x, y, 400, Condition(function USFilter))
        call GroupRemoveGroup(g, d)
        loop
            set f = FirstOfGroup(g)
            exitwhen f == null or safety > 1000
            call UnitDamageTarget(Caster, f, GetHeroAgi(Caster, true) * 5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            call GroupAddUnit(d, f)
            call GroupRemoveUnit(g, f)
            set safety = safety + 1
        endloop
        call SetHandleHandle(USTimer, "d"+I2S(H2I(USTimer)), d)
        call DestroyGroup(g)
        set g = null
    else
        call SetUnitAnimation(Caster,"attack")
        call SetUnitExploded(Phoenix, true)
        call KillUnit(Phoenix)
        call SetUnitPosition(Caster,x,y)
        call SetUnitFacing(Caster,z)
        call ShowUnit(Caster,true)
        if (GetLocalPlayer() == Owner) then
            call SelectUnit(Caster, true)
        endif
        call DestroyTimer(USTimer)
        call DestroyGroup(d)
        call RemoveLocation(loc)
        set d = null
        set USTimer = null
        set Caster = null
        set Phoenix = null
        set Owner = null
        set loc = null
    endif
endfunction

function USDelay takes nothing returns nothing
    local timer DelayTimer = GetExpiredTimer()
    local timer USTimer = CreateTimer()
    local integer DC = 0
    local unit Caster = GetHandleUnit(DelayTimer,"Caster"+I2S(H2I(DelayTimer)))
    local player Owner = GetOwningPlayer(Caster)
    local real x = GetUnitX(Caster)
    local real y = GetUnitY(Caster)
    local real z = GetUnitFacing(Caster)
    local unit Phoenix = CreateUnit(Owner,'h000',x,y,z)
    call ShowUnit(Caster,false)
    call SetHandleHandle(USTimer,"Caster"+I2S(H2I(USTimer)),Caster)
    call SetHandleHandle(USTimer,"Phoenix"+I2S(H2I(USTimer)),Phoenix)
    call SetHandleReal(USTimer,"z"+I2S(H2I(USTimer)),z)
    call SetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)),DC)
    call TimerStart(USTimer,0.02,true,function USMove)
    call DestroyTimer(DelayTimer)
    set DelayTimer = null
    set Caster = null
    set Owner = null
    set Phoenix = null
endfunction

function USSetup takes nothing returns nothing
    local timer DelayTimer = CreateTimer()
    local integer DC = 0
    local unit Caster = GetTriggerUnit()
    call SetHandleHandle(DelayTimer,"Caster"+I2S(H2I(DelayTimer)),Caster)
    call TimerStart(DelayTimer,0.20,false,function USDelay)
    set Caster = null
endfunction

function USAbilCheck takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        call USSetup()
    endif
    return true
endfunction

//===========================================================================
function InitTrig_Ultimate_Sacrifice takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function USAbilCheck ) )
    set t = null
endfunction


Here you go. If I've missed some part of it tell me. I also removed a fair few leaks in there too.
 

saw792

Is known to say things. That is all.
Reaction score
280
Check your other thread in the main world editor forum. I fixed all those things for you, and added the damage in a much better way.

EDIT: Wow you have so many variables in there you don't use... you don't use DC or Owner at all in USSetup, and you don't use your trigger variables in UnitCheck and DealDmg. I've probably missed more you haven't used also. There is absolutely no reason to complicate things by creating another trigger here though.
 

CrackUps

New Member
Reaction score
7
Yeah i'm still new to Jass this is pretty much the first spell i've made,

>Also you're not removing any locations nor nulling any handles. Fix these things and see the result afterwards.

how do i null the handles? for example do you mean like SetHandleHandle(USTimer,"Owner",null) ?
 

CrackUps

New Member
Reaction score
7
It damages allies, every 0.02 it's dealing damage to everyone within 400 range including the same unit more then once:( would you be able to have a look at the code again? Oh and it still seems to drop my fps without it returning to normal:(
 

saw792

Is known to say things. That is all.
Reaction score
280
JASS:
function USMove takes nothing returns nothing
    local timer USTimer = GetExpiredTimer()
    local unit Caster = GetHandleUnit(USTimer,"Caster"+I2S(H2I(USTimer)))
    local unit Phoenix = GetHandleUnit(USTimer,"Phoenix"+I2S(H2I(USTimer)))
    local integer DC = GetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)))
    local player Owner = GetOwningPlayer(Caster)
    local real z = GetHandleReal(USTimer,"z"+I2S(H2I(USTimer)))
    local location loc = GetUnitLoc(Phoenix)
    local real x = GetLocationX(loc) + 20.00 * Cos(z * bj_DEGTORAD)
    local real y = GetLocationY(loc) + 20.00 * Sin(z * bj_DEGTORAD)
    local group d = GetHandleGroup(USTimer, "d"+I2S(H2I(USTimer)))
    local group g = CreateGroup()
    local integer safety = 0
    local unit f
    if DC <= 1000 then
        call SetUnitPosition(Phoenix,x,y)
        call SetUnitFacing(Phoenix,z)
        set DC = DC + 20
        call SetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)),DC)
        if d == null then
            set d = CreateGroup()
        endif
        call GroupEnumUnitsInRange(g, x, y, 400, null)
        call GroupRemoveGroup(d, g)
        loop
            set f = FirstOfGroup(g)
            if not (IsUnitEnemy(f, GetOwningPlayer(Caster)) and (IsUnitType(f, UNIT_TYPE_STRUCTURE) == false)) then
              call GroupRemoveUnit(g,f)
              set f = FirstOfGroup(g)
            else
              exitwhen f == null or safety > 1000
              call UnitDamageTarget(Caster, f, GetHeroAgi(Caster, true) * 5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
              call GroupAddUnit(d, f)
              call GroupRemoveUnit(g, f)
              set safety = safety + 1
            endif
        endloop
        call SetHandleHandle(USTimer, "d"+I2S(H2I(USTimer)), d)
        call DestroyGroup(g)
        set g = null
    else
        call SetUnitAnimation(Caster,"attack")
        call SetUnitExploded(Phoenix, true)
        call KillUnit(Phoenix)
        call SetUnitPosition(Caster,x,y)
        call SetUnitFacing(Caster,z)
        call ShowUnit(Caster,true)
        if (GetLocalPlayer() == Owner) then
            call SelectUnit(Caster, true)
        endif
        call DestroyTimer(USTimer)
        call DestroyGroup(d)
        call RemoveLocation(loc)
        set d = null
        set USTimer = null
        set Caster = null
        set Phoenix = null
        set Owner = null
        set loc = null
    endif
endfunction

function USDelay takes nothing returns nothing
    local timer DelayTimer = GetExpiredTimer()
    local timer USTimer = CreateTimer()
    local integer DC = 0
    local unit Caster = GetHandleUnit(DelayTimer,"Caster"+I2S(H2I(DelayTimer)))
    local player Owner = GetOwningPlayer(Caster)
    local real x = GetUnitX(Caster)
    local real y = GetUnitY(Caster)
    local real z = GetUnitFacing(Caster)
    local unit Phoenix = CreateUnit(GetOwningPlayer(Caster),'h000',x,y,z)
    call ShowUnit(Caster,false)
    call SetHandleHandle(USTimer,"Caster"+I2S(H2I(USTimer)),Caster)
    call SetHandleHandle(USTimer,"Phoenix"+I2S(H2I(USTimer)),Phoenix)
    call SetHandleReal(USTimer,"z"+I2S(H2I(USTimer)),z)
    call SetHandleInt(USTimer,"DC"+I2S(H2I(USTimer)),DC)
    call TimerStart(USTimer,0.02,true,function USMove)
    call DestroyTimer(DelayTimer)
    set DelayTimer = null
    set Caster = null
    set Owner = null
    set Phoenix = null
endfunction

function USSetup takes nothing returns nothing
    local timer DelayTimer = CreateTimer()
    local integer DC = 0
    local unit Caster = GetTriggerUnit()
    call SetHandleHandle(DelayTimer,"Caster"+I2S(H2I(DelayTimer)),Caster)
    call TimerStart(DelayTimer,0.20,false,function USDelay)
    set Caster = null
endfunction

function USAbilCheck takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        call USSetup()
    endif
    return true
endfunction

//===========================================================================
function InitTrig_Ultimate_Sacrifice takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function USAbilCheck ) )
    set t = null
endfunction


Hehe I actually tested this one. It works. There were two problems with it: I had the groups in the wrong order in the GroupRemoveGroup function, and the the filter function for GroupEnumUnitsInRange was using GetTriggerUnit(), which was returning null after that time.

Nulling the handles is shown in what I have done in my trigger. At the bottom of triggers with handle locals I have set <handle> = null. This prevents leaks from references no longer needed. You only need to null handles, not integers, reals, booleans, or anything else that doesn't extend a handle. Handles should be nulled AFTER you use RemoveLocation / DestroyGroup etc, if necessary.

One exception to this, do not null a timer variable in the function that starts the timer. This causes strange bugs on occasion.
 

CrackUps

New Member
Reaction score
7
Yeah i have edited my trigger now thanks to you it gives me my desired result:) except i still have the same FPS problem whats wrong? is it just my crappy pc? lol
 

saw792

Is known to say things. That is all.
Reaction score
280
It worked fine when I tested it. No fps drop at all. Are there any other triggers running when this is running?
 

CrackUps

New Member
Reaction score
7
Nah most likely my pc then thanks alot for your help:thup: It gets to a point that when i cast it enough times the game becomes unplayable lol i'm looking at upgrading my pc soon anyway so should be fine:D

[Edit]It seems like its just my map i put it into a new map and it worked fine no FPS issue i can't find the problem with my map though and whats causing it to lag:confused:
 

saw792

Is known to say things. That is all.
Reaction score
280
That would be a leak issue, seeing as it is building up progressively. Try my trigger?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top