Some jass questions

Kazuga

Let the game begin...
Reaction score
110
Aha^^ I thought I should write my own type there^^
However I got 5 errors on the same line...
"Cannot convert boolean to real"
"Cannot convert attacktype to boolean"
"Cannot convert damagetype to attacktype"
"Cannot convert weapontype to damagetype"
"Not enough arguments passed to function"

=/

Edit: Ok found the problem, forgot about a real value.
JASS:
function Trig_Lightnings_Func001A takes nothing returns nothing
    call UnitDamageTarget(caster, GetEnumUnit(), 200,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
    endfunction

But no damage is caused atm =/

All these three messages are shown too so the trigger isn't stucked... Either he doesn't know what to damage or he just doesn't call it..
JASS:
    call BJDebugMsg("1")
    set udg_z = GetUnitsInRangeOfLocMatching(500, GetUnitLoc(GetTriggerUnit()), Condition(function Trig_Lightnings_FilterCondition))
    call BJDebugMsg("2")
    call ForGroup( udg_z, function Trig_Lightnings_Func001A )
      call BJDebugMsg("3")


Edit: K the function isn't called (checked with a debug message=/ )
Irritating... it should work, shoudn't it?
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
I feel like really, really stupid asking that question about now xD.

Still post the whole code so we can see all global variables, filter functions, etc.

Edit: Also why is that group a udg_-variable? Use the vJASS globals function instead.
 

Kazuga

Let the game begin...
Reaction score
110
Hm the unit group doesn't want to be declared...

Whole code
JASS:
library HAILInit requires HAIL
//! runtextmacro HAIL_CreateProperty ("Data", "integer", "")
endlibrary
scope Lightnings initializer Lightning
group z
globals
private constant integer raw = 'A001'
unit caster = GetTriggerUnit ()
endglobals
private struct TestStruct
unit dummy
unit caster
unit target
real tx
real ty
timer SlideTimer
endstruct

private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == raw
endfunction
function Trig_Lightnings_FilterCondition takes nothing returns boolean
    
    return GetWidgetLife( GetFilterUnit() ) > 0.405 and IsUnitEnemy( GetFilterUnit(), GetOwningPlayer( GetTriggerUnit() ) ) == true
    
endfunction
function Trig_Lightnings_Func001A takes nothing returns nothing
       call BJDebugMsg("damage1")
    call UnitDamageTarget(caster, GetEnumUnit(), 200,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
       call BJDebugMsg("damage")
   endfunction

private function Effect takes real myX, real myY, unit Target returns nothing
    local real x
    local real y
    local real x2
    local real y2
    local real real1 = 0
    local unit dummy
    
    set x  = myX + 300 * Cos((45)  * bj_DEGTORAD)
    set y  = myY + 300 * Sin((45)  * bj_DEGTORAD)
    set x2 = myX + 300 * Cos((315) * bj_DEGTORAD)
    set y2 = myY + 300 * Sin((315) * bj_DEGTORAD)
    
    call TimedLightning ("CLPB", x2, y2, 0, myX, myY, 0, 2., true, 1, 0)
    call TimedLightning ("CLPB", x, y, 0, myX, myY, 0, 2., true, 1, 0)

    set x  = myX + 300 * Cos((125)  * bj_DEGTORAD)
    set y  = myY + 300 * Sin((125)  * bj_DEGTORAD)
    set x2 = myX + 300 * Cos((225) * bj_DEGTORAD)
    set y2 = myY + 300 * Sin((225) * bj_DEGTORAD)
    
    call TimedLightning ("CLPB", x2, y2, 0, myX, myY, 0, 2., true, 1, 0)
    call TimedLightning ("CLPB", x, y, 0, myX, myY, 0, 2., true, 1, 0)

    call PauseUnit(Target,false)
    set z = GetUnitsInRangeOfLocMatching(500, GetUnitLoc(GetTriggerUnit()), Condition(function Trig_Lightnings_FilterCondition))
    call ForGroup( z, function Trig_Lightnings_Func001A )
  call AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl",myX,myY)  
endfunction



private function Slide takes nothing returns nothing
local TestStruct data = GetData (GetExpiredTimer ())
local real x = GetUnitX(data.dummy)
local real y = GetUnitY(data.dummy)
local real newX
local real newY
local real angle
local real distance
local real real1=45
local real x2 
local real y2 



set data.tx    = GetUnitX(data.target)
set data.ty    = GetUnitY(data.target)
set angle = Atan2(data.ty-y,data.tx-x)
set newX  = x + 10 *Cos(angle)
set newY  = y + 10 *Sin(angle)

call SetUnitPosition(data.dummy,newX,newY)
call AddSpecialEffect("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl",newX,newY)
set distance=SquareRoot( (x-data.tx)*(x-data.tx) + (y-data.ty)*(y-data.ty) )
if distance < 50 then
    call PauseTimer (data.SlideTimer)
    call ResetData (data.SlideTimer)
    call DestroyTimer (data.SlideTimer)
    call PauseUnit (data.target,true)
    call RemoveUnit(data.dummy)
    call data.destroy ()
    call Effect(data.tx, data.ty, data.target)

endif
endfunction


private function Actions takes nothing returns nothing
local TestStruct data = TestStruct.create ()
local unit Unit                    = GetTriggerUnit()
local real real1                   = GetUnitFacing(GetTriggerUnit())

local real x = GetUnitX(GetTriggerUnit())
local real y = GetUnitY(GetTriggerUnit())

local real x2 = x + 300 * Cos((real1+145)*bj_DEGTORAD)
local real y2 = y + 300 * Sin((real1+145)*bj_DEGTORAD)

local real x3 = x + 300 * Cos((real1+180)*bj_DEGTORAD)
local real y3 = y + 300 * Sin((real1+180)*bj_DEGTORAD)

local real x4 = x + 300 * Cos((real1+215)*bj_DEGTORAD)
local real y4 = y + 300 * Sin((real1+215)*bj_DEGTORAD)
local effect special1

set data.SlideTimer = CreateTimer()
set data.target = (GetSpellTargetUnit())
set special1 = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl",x,y)
call TriggerSleepAction (0.1)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x2,y2)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x3,y3)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x4,y4)
call AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl",x,y)
call PauseUnit (Unit, true)

call TimedLightning ("CLPB", x, y, 0, x2, y2, 0, 2., true, 1, 0)
call TimedLightning ("CLPB", x, y, 0, x3, y3, 0, 2., true, 1, 0)
call TimedLightning ("CLPB", x, y, 0, x4, y4, 0, 2., true, 1, 0)


call TriggerSleepAction (1)
call DestroyEffect(special1)
set data.dummy = CreateUnit (GetOwningPlayer(Unit),'h001',x,y,0)
call SetUnitPathing(data.dummy, false )
call PauseUnit (Unit, false)
call TimerStart (data.SlideTimer,0.05,true, function Slide)
call SetData (data.SlideTimer, data)
set Unit = null

endfunction


//===========================================================================

private function SafeFilt takes nothing returns boolean
return true
endfunction
private function Lightning takes nothing returns nothing
 local trigger trig = CreateTrigger()
local integer i = 0
loop
    exitwhen i > 15
    call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function SafeFilt))
    set i = i + 1
endloop
 call TriggerAddCondition (trig, Condition (function Conditions ) )
 call TriggerAddAction (trig, function Actions )
 set trig = null
 endfunction

endscope
 

Flare

Stops copies me!
Reaction score
662
Make Effect take another unit argument (so you can pass .caster to Effect) then assign the global caster var to that new unit i.e.

JASS:
function whichcallback takes nothing returns nothing
call UnitDamageTarget((global caster variable), GetEnumUnit(), 200,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
endfunction

function Effect takes unit casterunit, real x, real y, unit target returns nothing
//Declare your locals and such
set (global caster variable) = casterunit
//Get your group
call ForGroup (whichgroup, whichcallback)
endfunction


then refer to (global caster variable) in the group callback. I don't know if you can initialize globals in a global block
 

Kazuga

Let the game begin...
Reaction score
110
I don't see what diffrence that would make=/ Also he thinks that it's a real value for some reason...

"Cannot convert real to unit"
"Cannot convert unit to real"
Not enough arguments passed into function"

Code:
JASS:
library HAILInit requires HAIL
//! runtextmacro HAIL_CreateProperty ("Data", "integer", "")
endlibrary
scope Lightnings initializer Lightning

globals
group z
private constant integer raw = 'A001'
real damage = 200
unit caster = GetTriggerUnit ()
endglobals
private struct TestStruct
unit dummy
unit target
real tx
real ty
timer SlideTimer
endstruct

private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == raw
endfunction
function Trig_Lightnings_FilterCondition takes nothing returns boolean
    
    return GetWidgetLife( GetFilterUnit() ) > 0.405 and IsUnitEnemy( GetFilterUnit(), GetOwningPlayer( GetTriggerUnit() ) ) == true
    
endfunction
function Trig_Lightnings_Func001A takes nothing returns nothing
    call BJDebugMsg("damage1")
    call UnitDamageTarget(caster, GetEnumUnit(), damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
    call BJDebugMsg("damage")
   endfunction

private function Effect takes unit casterunit, real myX, real myY, unit Target returns nothing
    local real x
    local real y
    local real x2
    local real y2
    local real real1 = 0
    local unit dummy
    
    set caster = casterunit
    
    set x  = myX + 300 * Cos((45)  * bj_DEGTORAD)
    set y  = myY + 300 * Sin((45)  * bj_DEGTORAD)
    set x2 = myX + 300 * Cos((315) * bj_DEGTORAD)
    set y2 = myY + 300 * Sin((315) * bj_DEGTORAD)
    
    call TimedLightning ("CLPB", x2, y2, 0, myX, myY, 0, 2., true, 1, 0)
    call TimedLightning ("CLPB", x, y, 0, myX, myY, 0, 2., true, 1, 0)

    set x  = myX + 300 * Cos((125)  * bj_DEGTORAD)
    set y  = myY + 300 * Sin((125)  * bj_DEGTORAD)
    set x2 = myX + 300 * Cos((225) * bj_DEGTORAD)
    set y2 = myY + 300 * Sin((225) * bj_DEGTORAD)
    
    call TimedLightning ("CLPB", x2, y2, 0, myX, myY, 0, 2., true, 1, 0)
    call TimedLightning ("CLPB", x, y, 0, myX, myY, 0, 2., true, 1, 0)

    call PauseUnit(Target,false)

    set z = GetUnitsInRangeOfLocMatching(500, GetUnitLoc(GetTriggerUnit()), Condition(function Trig_Lightnings_FilterCondition))
    call ForGroup( z, function Trig_Lightnings_Func001A )
  call AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl",myX,myY)  
endfunction



private function Slide takes nothing returns nothing
local TestStruct data = GetData (GetExpiredTimer ())
local real x = GetUnitX(data.dummy)
local real y = GetUnitY(data.dummy)
local real newX
local real newY
local real angle
local real distance
local real real1=45
local real x2 
local real y2 



set data.tx    = GetUnitX(data.target)
set data.ty    = GetUnitY(data.target)
set angle = Atan2(data.ty-y,data.tx-x)
set newX  = x + 10 *Cos(angle)
set newY  = y + 10 *Sin(angle)

call SetUnitPosition(data.dummy,newX,newY)
set distance=SquareRoot( (x-data.tx)*(x-data.tx) + (y-data.ty)*(y-data.ty) )
if distance < 20 then
    call PauseTimer (data.SlideTimer)
    call ResetData (data.SlideTimer)
    call DestroyTimer (data.SlideTimer)
    call PauseUnit (data.target,true)
    call RemoveUnit(data.dummy)
    call data.destroy ()
    call Effect(data.tx, data.ty, data.target)

endif
endfunction


private function Actions takes nothing returns nothing
local TestStruct data = TestStruct.create ()
local unit Unit                    = GetTriggerUnit()
local real real1                   = GetUnitFacing(GetTriggerUnit())

local real x = GetUnitX(GetTriggerUnit())
local real y = GetUnitY(GetTriggerUnit())

local real x2 = x + 300 * Cos((real1+145)*bj_DEGTORAD)
local real y2 = y + 300 * Sin((real1+145)*bj_DEGTORAD)

local real x3 = x + 300 * Cos((real1+180)*bj_DEGTORAD)
local real y3 = y + 300 * Sin((real1+180)*bj_DEGTORAD)

local real x4 = x + 300 * Cos((real1+215)*bj_DEGTORAD)
local real y4 = y + 300 * Sin((real1+215)*bj_DEGTORAD)
local effect special1

set data.SlideTimer = CreateTimer()
set data.target = (GetSpellTargetUnit())
set special1 = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl",x,y)
call TriggerSleepAction (0.1)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x2,y2)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x3,y3)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x4,y4)
call AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl",x,y)
call PauseUnit (Unit, true)

call TimedLightning ("CLPB", x, y, 0, x2, y2, 0, 2., true, 1, 0)
call TimedLightning ("CLPB", x, y, 0, x3, y3, 0, 2., true, 1, 0)
call TimedLightning ("CLPB", x, y, 0, x4, y4, 0, 2., true, 1, 0)


call TriggerSleepAction (1)
call DestroyEffect(special1)
set data.dummy = CreateUnit (GetOwningPlayer(Unit),'h001',x,y,0)
call SetUnitPathing(data.dummy, false )
call PauseUnit (Unit, false)
call TimerStart (data.SlideTimer,0.05,true, function Slide)
call SetData (data.SlideTimer, data)
set Unit = null

endfunction


//===========================================================================

private function SafeFilt takes nothing returns boolean
return true
endfunction
private function Lightning takes nothing returns nothing
 local trigger trig = CreateTrigger()
local integer i = 0
loop
    exitwhen i > 15
    call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function SafeFilt))
    set i = i + 1
endloop
 call TriggerAddCondition (trig, Condition (function Conditions ) )
 call TriggerAddAction (trig, function Actions )
 set trig = null
 endfunction

endscope
 

Artificial

Without Intelligence
Reaction score
326
Well, you are calling it in the Slide function like this:
JASS:
call Effect(data.tx, data.ty, data.target)
It's arguments are unit, real, real, unit. You ain't giving the first unit. :p
 

Kazuga

Let the game begin...
Reaction score
110
Hm... when I try to do the same in the call function I get syntax error:
JASS:
    call Effect(unit casterunit, data.tx, data.ty, data.target)

Why is it so hard to pick every unit in a unit group and do some actions? =/
 

Larcenist

REP: Respect, Envy, Prosperity?
Reaction score
211
JASS:
 call Effect(unit casterunit, data.tx, data.ty, data.target)


Should be

JASS:
 call Effect(casterunit, data.tx, data.ty, data.target)
 

Kazuga

Let the game begin...
Reaction score
110
Ah ok, well I think I will try something else... That was what Flare suggested but I don't really quite get how it would make it work =/

There has to be some way to do this in?
(Problem is that the pick every unit in unit group and do actions code doesn't work, the function isn't called still there is no errors)
JASS:

library HAILInit requires HAIL
//! runtextmacro HAIL_CreateProperty ("Data", "integer", "")
endlibrary
scope Lightnings initializer Lightning

globals
group z
private constant integer raw = 'A001'
real damage = 200
unit caster = GetTriggerUnit ()
endglobals
private struct TestStruct
unit dummy
unit target
real tx
real ty
timer SlideTimer
endstruct

private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == raw
endfunction
function Trig_Lightnings_FilterCondition takes nothing returns boolean
    
    return GetWidgetLife( GetFilterUnit() ) > 0.405 and IsUnitEnemy( GetFilterUnit(), GetOwningPlayer( GetTriggerUnit() ) ) == true
    
endfunction
function Trig_Lightnings_Func001A takes nothing returns nothing
    call BJDebugMsg("damage1")
    call UnitDamageTarget(caster, GetEnumUnit(), damage,true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
    call BJDebugMsg("damage")
   endfunction

private function Effect takes real myX, real myY, unit Target returns nothing
    local real x
    local real y
    local real x2
    local real y2
    local real real1 = 0
    local unit dummy
    
    
    set x  = myX + 300 * Cos((45)  * bj_DEGTORAD)
    set y  = myY + 300 * Sin((45)  * bj_DEGTORAD)
    set x2 = myX + 300 * Cos((315) * bj_DEGTORAD)
    set y2 = myY + 300 * Sin((315) * bj_DEGTORAD)
    
    call TimedLightning ("CLPB", x2, y2, 0, myX, myY, 0, 2., true, 1, 0)
    call TimedLightning ("CLPB", x, y, 0, myX, myY, 0, 2., true, 1, 0)

    set x  = myX + 300 * Cos((125)  * bj_DEGTORAD)
    set y  = myY + 300 * Sin((125)  * bj_DEGTORAD)
    set x2 = myX + 300 * Cos((225) * bj_DEGTORAD)
    set y2 = myY + 300 * Sin((225) * bj_DEGTORAD)
    
    call TimedLightning ("CLPB", x2, y2, 0, myX, myY, 0, 2., true, 1, 0)
    call TimedLightning ("CLPB", x, y, 0, myX, myY, 0, 2., true, 1, 0)

    call PauseUnit(Target,false)

    set z = GetUnitsInRangeOfLocMatching(500, GetUnitLoc(GetTriggerUnit()), Condition(function Trig_Lightnings_FilterCondition))
    call ForGroup( z, function Trig_Lightnings_Func001A )
  call AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl",myX,myY)  
endfunction



private function Slide takes nothing returns nothing
local TestStruct data = GetData (GetExpiredTimer ())
local real x = GetUnitX(data.dummy)
local real y = GetUnitY(data.dummy)
local real newX
local real newY
local real angle
local real distance
local real real1=45
local real x2 
local real y2 



set data.tx    = GetUnitX(data.target)
set data.ty    = GetUnitY(data.target)
set angle = Atan2(data.ty-y,data.tx-x)
set newX  = x + 10 *Cos(angle)
set newY  = y + 10 *Sin(angle)

call SetUnitPosition(data.dummy,newX,newY)
set distance=SquareRoot( (x-data.tx)*(x-data.tx) + (y-data.ty)*(y-data.ty) )
if distance < 20 then
    call PauseTimer (data.SlideTimer)
    call ResetData (data.SlideTimer)
    call DestroyTimer (data.SlideTimer)
    call PauseUnit (data.target,true)
    call RemoveUnit(data.dummy)
    call data.destroy ()
    call Effect( data.tx, data.ty, data.target)

endif
endfunction


private function Actions takes nothing returns nothing
local TestStruct data = TestStruct.create ()
local unit Unit                    = GetTriggerUnit()
local real real1                   = GetUnitFacing(GetTriggerUnit())

local real x = GetUnitX(GetTriggerUnit())
local real y = GetUnitY(GetTriggerUnit())

local real x2 = x + 300 * Cos((real1+145)*bj_DEGTORAD)
local real y2 = y + 300 * Sin((real1+145)*bj_DEGTORAD)

local real x3 = x + 300 * Cos((real1+180)*bj_DEGTORAD)
local real y3 = y + 300 * Sin((real1+180)*bj_DEGTORAD)

local real x4 = x + 300 * Cos((real1+215)*bj_DEGTORAD)
local real y4 = y + 300 * Sin((real1+215)*bj_DEGTORAD)
local effect special1

set data.SlideTimer = CreateTimer()
set data.target = (GetSpellTargetUnit())
set special1 = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl",x,y)
call TriggerSleepAction (0.1)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x2,y2)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x3,y3)
call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",x4,y4)
call AddSpecialEffect("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl",x,y)
call PauseUnit (Unit, true)

call TimedLightning ("CLPB", x, y, 0, x2, y2, 0, 2., true, 1, 0)
call TimedLightning ("CLPB", x, y, 0, x3, y3, 0, 2., true, 1, 0)
call TimedLightning ("CLPB", x, y, 0, x4, y4, 0, 2., true, 1, 0)


call TriggerSleepAction (1)
call DestroyEffect(special1)
set data.dummy = CreateUnit (GetOwningPlayer(Unit),'h001',x,y,0)
call SetUnitPathing(data.dummy, false )
call PauseUnit (Unit, false)
call TimerStart (data.SlideTimer,0.05,true, function Slide)
call SetData (data.SlideTimer, data)
set Unit = null

endfunction


//===========================================================================

private function SafeFilt takes nothing returns boolean
return true
endfunction
private function Lightning takes nothing returns nothing
 local trigger trig = CreateTrigger()
local integer i = 0
loop
    exitwhen i > 15
    call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function SafeFilt))
    set i = i + 1
endloop
 call TriggerAddCondition (trig, Condition (function Conditions ) )
 call TriggerAddAction (trig, function Actions )
 set trig = null
 endfunction

endscope
 

Flare

Stops copies me!
Reaction score
662
OK then. Just before you call Effect, set data.caster to a global unit variable.

In your group filter, change the IsUnitEnemy (GetFilterUnit (), GetOwningPlayer (GetTriggerUnit ()) to
JASS:
IsUnitEnemy (GetFilterUnit (), GetOwningPlayer (globalunitvar))
//Just replace globalunitvar with (your global unit variable)


Then use (global unit variable) in the group callback function.

I think the group isn't working because of the fact that you are using GetTriggerUnit, and grouping the units in Effect (which doesnt have a triggering unit)

I don't see what diffrence that would make=/ Also he thinks that it's a real value for some reason...

The idea was to be able to pass the struct unit to the Effect function, then use it from there because I thought there was a wait in Effect (which would've fucked up the MUI, unless the function took a second unit argument)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top