This spell stops functioning normally...

Cidzero

Imma firin mah lazer!!!1!1
Reaction score
39
[del]As the title says, my jass spell I'm working on stops after some 30+ uses. And I'm having trouble finding the exact cause...I am still relatively new to JASS...so any help would be appreciated. According to the debugger, it is unable to allocate a new id for the struct then causing it to die when trying to destroy a null object. The units still manage to get created at the right angle some how.[/del]

My spell is my favorite off of Diablo 2, Ice Orb, I had to make it myself, I never found one so far to be the same as Diablo 2's.

JASS:
// Used ideas from the Frost Sphere by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor and used functions from Vex's Caster System
// Made this one a self contained orb and closer to that of the original Diablo 2
// This is all hand written by me, only copied and pasted Caster System's functions
// Cidzero
scope IceOrb
    
    globals
        private constant gamecache cache = InitGameCache("IceOrb")
        // These are all you need to change to make the orb go further faster or different end effect
        private constant integer DumID = 'd000' // Must use the dummy.mdl
        private constant integer SpellID = 'A000' // Your Spell
        private constant integer ColdID = 'A003' // Your cold spell (base it off shadow strike, 0 cost, 0 cooldown, 0 casting time, 0 damage, no animation, your buff choice)
        private constant real maxOrbDist = 1200
        private constant real maxBoltDist = 800
        private constant real OrbSpeed = 5
        private constant real BoltSpeed = 10
        private constant real orbDmg = 0.1
        private constant real boltDmg = 15
        private constant real specialAngle = 35.0
        private constant real height = 50.0
        private constant real periodicCheck = 0.02
        private constant real spawnRate = 0.10
        private constant real boltHitRadius = 50.0
        private constant real orbHitRadius = 100.0
        private constant real orbSize = 1.00
        private constant real boltSize = 0.50
        private constant string orbMdl = "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl"
        private constant string boltMdl = "Abilities\\Weapons\\LichMissile\\LichMissile.mdl"
        private unit tu = null
        private real tl = 0
    endglobals
//=================== Some functions from Vex's Caster System =========================\\      
    private function H2I takes handle h returns integer
        return h
        return 0
    endfunction
  
    private function HS takes handle i returns string
        return I2S(H2I(i))
    endfunction
//=================== Checks the spell being casted =========================\\ 
    private function Conditions takes nothing returns boolean
        return (GetSpellAbilityId()==SpellID)
    endfunction
//=================== This checks to make sure the unit is not immune to magic (From Vex's Caster System) =========================\\    
    private function IsUnitNotImmun takes unit c,unit u returns boolean
        return ((c!=u) and not (IsUnitType(u,UNIT_TYPE_STRUCTURE)==true) and not (IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)==true) and (IsUnitEnemy(u, GetOwningPlayer(c))==true) and ((GetUnitState(u,UNIT_STATE_LIFE)>0.00)==true))
    endfunction
    
    private function notDead takes nothing returns boolean
        return (not (IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==true) and not (IsUnitType(GetFilterUnit(),UNIT_TYPE_MAGIC_IMMUNE)==true) and ((GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>0.00)==true))
    endfunction
//=================== The struct =========================\\  
    private struct Missile
        unit missile
        real angle
        real dist
        real special
        real stime
        real ttime
        real lvl
        real x1
        real x2
        real y1
        real y2
        effect mdl
        timer t
        boolean hit
        boolean d
        
        method make takes real x, real y, real a,real h, real s, string m, player p, real l returns nothing
            set this.missile = CreateUnit(p,DumID,x,y,a)
            call UnitAddAbility(this.missile,ColdID)
            call SetUnitAbilityLevel(this.missile,ColdID,R2I(l))
            call SetUnitFlyHeight(this.missile,h,0)
            set this.mdl = AddSpecialEffectTarget(m,this.missile,"chest")
            call SetUnitScale(this.missile,s,s,s)
            set this.angle = a
            set this.dist = 0
            set this.special = 0
            set this.stime = 0
            set this.ttime = 0
            set this.lvl = l
            set this.hit = false
            set this.d = false
            set this.t = CreateTimer()
            call StoreInteger(cache,HS(this.t),"missile",this)
        endmethod
        
        method move takes real speed returns nothing
            set this.x1 = GetUnitX(this.missile)
            set this.y1 = GetUnitY(this.missile)
            set this.x2 = this.x1+speed*Cos(this.angle*bj_DEGTORAD)
            set this.y2 = this.y1+speed*Sin(this.angle*bj_DEGTORAD)
            if (RectContainsCoords(bj_mapInitialPlayableArea,this.x2,this.y2)==false) then
                set this.d = true
            else
                call SetUnitX(this.missile,this.x2)
                call SetUnitY(this.missile,this.y2)
                set this.dist = this.dist+speed
            endif
        endmethod
        
        method remove takes nothing returns nothing
            call RemoveUnit(this.missile)
            set this.missile = null
            call DestroyEffect(this.mdl)
            set this.mdl = null
            call PauseTimer(this.t)
            call FlushStoredMission(cache,HS(this.t))
            call DestroyTimer(this.t)
            set this.t = null
            call this.destroy()
        endmethod
    endstruct
//=================== This tells the bolts what to damage =========================\\    
    private function dmgTrgBolt takes nothing returns nothing
        local unit t = tu
        local real l = tl
        local unit u = GetEnumUnit()
        if IsUnitNotImmun(t,u) then
            call UnitDamageTarget(t,u,(l*boltDmg),false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_COLD,null)
            call IssueTargetOrder(t,"shadowstrike",u)
            call StoreBoolean(cache,HS(t),"hit",true)
        endif
        set u = null
        set t = null
    endfunction
//=================== This tells the orb what to damage =========================\\    
    private function dmgTrgOrb takes nothing returns nothing
        local unit t = tu
        local real l = tl
        local unit u = GetEnumUnit()
        if IsUnitNotImmun(t,u) then
            call UnitDamageTarget(t,u,(l*orbDmg),false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_COLD,null)
            call IssueTargetOrder(t,"shadowstrike",u)
        endif
        set u = null
        set t = null
    endfunction
//=================== This Controls the Bolts =========================\\
    private function BoltMotion takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local Missile bolt = GetStoredInteger(cache,HS(t),"missile")
        local group g = CreateGroup()
        call bolt.move(BoltSpeed)
        
        call GroupEnumUnitsInRange(g,bolt.x2,bolt.y2,boltHitRadius,Condition(function notDead))
        if (CountUnitsInGroup(g)>0) then
            set tu = bolt.missile
            set tl = bolt.lvl
            call ForGroup(g,function dmgTrgBolt)
            set bolt.hit = GetStoredBoolean(cache,HS(bolt.missile),"hit")
            call FlushStoredMission(cache,HS(bolt.missile))
        endif
        call DestroyGroup(g)
        set g = null
        
        if ((bolt.dist>=maxBoltDist) or bolt.hit or bolt.d) then
            call bolt.remove()
        else
            call TimerStart(t,periodicCheck,false,function BoltMotion)
        endif
        set t = null
    endfunction
//=================== Creates a Bolt without constantly making a Missile =========================\\      
    private function CreateBolt takes real x, real y, real a,real h, real s, string m, player p, real l returns nothing
            local Missile bolt = Missile.create()
            call bolt.make(x,y,a,h,s,m,p,l)
            call TimerStart(bolt.t,0,false,function BoltMotion)
    endfunction
//=================== The final boom as seen in Diablo 2 =========================\\      
    private function Final takes real x, real y, player p, real l returns nothing
        local real c = 1
        loop
            exitwhen (c>24)
            call CreateBolt(x,y,(c*15.0),height,boltSize,boltMdl,p,l)
            set c = c + 1
        endloop
    endfunction
//=================== This controls the orb =========================\\      
    private function IceOrbMotion takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local Missile sphere = GetStoredInteger(cache,HS(t),"missile")
        local group g = CreateGroup()
        
        call sphere.move(OrbSpeed)
        
        call GroupEnumUnitsInRange(g,sphere.x2,sphere.y2,orbHitRadius,Condition(function notDead))
        if (CountUnitsInGroup(g)>0) then
            set tu = sphere.missile
            set tl = sphere.lvl
            call ForGroup(g,function dmgTrgOrb)
        endif
        call DestroyGroup(g)
        set g = null
        
        if (sphere.dist>=maxOrbDist or sphere.d) then
            call Final(sphere.x2,sphere.y2,GetOwningPlayer(sphere.missile),sphere.lvl)
            call sphere.remove()
        elseif (sphere.ttime>=sphere.stime) then
            set sphere.stime = sphere.stime + spawnRate
            set sphere.ttime = sphere.ttime + periodicCheck
            set sphere.special = sphere.special + 1
            call CreateBolt(sphere.x2,sphere.y2,(sphere.special*specialAngle+sphere.angle),height,boltSize,boltMdl,GetOwningPlayer(sphere.missile),sphere.lvl)
            call TimerStart(t,periodicCheck,false,function IceOrbMotion)
        else
            set sphere.ttime = sphere.ttime + periodicCheck
            call TimerStart(t,periodicCheck,false,function IceOrbMotion)
        endif
        set t = null
    endfunction
//=================== Starts it all right here =========================\\          
    private function IceOrbActions takes nothing returns nothing
        local real cx
        local real cy
        local real tx
        local real ty
        local Missile sphere = Missile.create()
        
        set cx = GetUnitX(GetTriggerUnit())
        set cy = GetUnitY(GetTriggerUnit())
        set tx = GetLocationX(GetSpellTargetLoc())
        set ty = GetLocationY(GetSpellTargetLoc())
        call sphere.make(cx,cy,(bj_RADTODEG*Atan2(ty-cy,tx-cx)),height,orbSize,orbMdl,GetOwningPlayer(GetTriggerUnit()),I2R(GetUnitAbilityLevel(GetTriggerUnit(),SpellID)))
        set sphere.stime = spawnRate
        call TimerStart(sphere.t,0,false,function IceOrbMotion)
    endfunction

//====================== You know what this is ============================\\
    public function InitTrig takes nothing returns nothing
        local trigger FrozenOrb = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(FrozenOrb,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(FrozenOrb,Condition(function Conditions))
        call TriggerAddAction(FrozenOrb,function IceOrbActions)
    endfunction
endscope


Btw I looked at Diablo 2's Ice Orb over and over to verify - It is not random. They spawn at a set angle of 35, 50, 55, or any other angle that does not hit 360 normally, and it spawns according to the orb's direction.
 

Steel

Software Engineer
Reaction score
109
Sounds like you are overloading some data there...

You have to remember structs are just an array of globals, so if you don't properly recycle the array you will hit the limit.

call Missle.destroy(bolt)
I don't see a custom defined method for your destroy.

I could be wrong though, someone else have a few bits they'd like to chime in with?
 

Vexorian

Why no custom sig?
Reaction score
187
To eliminate struct related issues, compile using debug mode and test again.

don't see a custom defined method for your destroy.
It's not like he needs one....
 

Steel

Software Engineer
Reaction score
109
Right, but it looks like somethings going wrong there Vex. The array isn't getting recycled for whatever reason.
 

Cidzero

Imma firin mah lazer!!!1!1
Reaction score
39
Did that, tells me Cannot Allocate ID for Object of Type (my struct)

Then after it fails to allocate, it fails to destroy the non-created structs.

I don't see what is causing this issue...or what I can do to fix it.

I removed the Bolt Spawning function and added it properly to the Orb Control function (still works), but it only delayed the big stop.
 

Vexorian

Why no custom sig?
Reaction score
187
You are always creating a bolt missile, even when you don't actually need it, so there are a lot of missile objects you never get to ever attach to a timer and never get destroyed.
 

Cidzero

Imma firin mah lazer!!!1!1
Reaction score
39
Huh...didn't know it created a struct even without .create()

So I put bolt missiles creation in a function that has to be called.
+rep for Vex ^_^

[del]Would this ultimately solve the problem? Or did I do something else?
I have tested, I lagged myself to hell by doign 30 bolts within 30 seconds, so many units, but it never came up with the error so atm I think this worked...but just incase can somebody check the code?[/del]
 

Vexorian

Why no custom sig?
Reaction score
187
Huh...didn't know it created a struct even without .create()

No, you were using .create unnecessarily.

It is not a good idea to remove the previous code in the original post should have posted the new code in a reply.

, I had to make it myself,
I wouldn't really say this is totally true, the basic algorithm structure of the spell looks very familiar to me not to mention some names.
 

Cidzero

Imma firin mah lazer!!!1!1
Reaction score
39
"I had to" means, I WANTED TO (caps for how much i wanted to). I couldn't resist trying to make one myself ^_^ Using Hanky's as a template by looking at his ideas seeing how they worked and figuring out if they were necessary to do this spell. The timers and cache are the biggest thing I saw from his that worked out perfect.

I'm one of those people that doesn't like just using ppl's stuff, I rather try and make what I need.

And about updating the code rather than posting a reply with it...I was thinking about saving space.
 

Sooda

Diversity enchants
Reaction score
318
I think you are missing from method 'make' mandatory 'Missile.allocate()' method call. If you would use BJDebugMsg before storing 'this' as a integer to game cache and display I2S(this) it would appear on screen always as 1. Your problem should be that method 'make' doesn't give unique struct id.
Right one (if you want you can try that allocate() method on 'this' too):
JASS:
        method make takes real x, real y, real a,real h, real s, string m, player p, real l returns nothing
            local Missile data = Missile.allocate()
            
            set data.missile = CreateUnit(p,DumID,x,y,a)
            call UnitAddAbility(data.missile,ColdID)
            call SetUnitAbilityLevel(data.missile,ColdID,R2I(l))
            call SetUnitFlyHeight(data.missile,h,0)
            set data.mdl = AddSpecialEffectTarget(m,this.missile,"chest")
            call SetUnitScale(data.missile,s,s,s)
            set data.angle = a
            set data.dist = 0
            set data.special = 0
            set data.stime = 0
            set data.ttime = 0
            set data.lvl = l
            set data.hit = false
            set data.d = false
            set data.t = CreateTimer()
            call BJDebugMsg("Missile struct id is: " + I2S(data))
            call StoreInteger(cache,HS(data.t),"missile",data)
        endmethod
 

Vexorian

Why no custom sig?
Reaction score
187
I'm one of those people that doesn't like just using ppl's stuff, I rather try and make what I need.

I did not say you shouldn't (although NIH is a bad idea) I am just saying that a lot of the code didn't sound original to me, can you tell me more about this Hanky guy? I want to see his implementation... Just saying some stuff in the code sounds very familiar to me.

And about updating the code rather than posting a reply with it...I was thinking about saving space.
I am sure thehelper appreciates the outstanding kilobyte you saved them... Just saying that it will confuse people... for example look at Sooda's attempt to fix the already fixed code.

BTW sooda, you are quite wrong. Mandatory allocate(), what?
 

Cidzero

Imma firin mah lazer!!!1!1
Reaction score
39
Sorry if I sounded like I was attacking you with that "I'm one of those people", I was just letting you know a little more about as to why I "had to" make, understanding the person helps understand their actions :p

The space wasn't memory...it was reading space...

And the code I looked at is:
Frost Sphere -
JASS:
//Frost Sphere by Hanky aka OrkOfMordor aka MDZ-OrkOfMordor

//Constants
scope FrostSphere

  globals
     private constant integer SpellId='A005'
     private constant integer BuffSpellId='A006'
     private constant string BuffOrder="berserk"
     private constant real PerSecondCreate=0.1
     private constant integer DummyId='e000'
     private constant real SphereSpeed=10.00
     private constant real MissileSpeed=15.00
     private constant real PeriodicTime=0.03
     private constant real TurnSpeed=45.00
     private constant real MissileDistance=1000.00
     private constant real MaxSphereDistance=2000.00
     private constant string MissileMdl="Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl"
     private constant string MissileAttackPoint="chest"
     private constant string SMissileMdl="Abilities\\Weapons\\LichMissile\\LichMissile.mdl"
     private constant string ExplMissileMdl="Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
     private constant string ExplSphereMdl="Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl"
     private constant string SMissileAttackPoint="chest"
     private constant string MCode="FS_MissileHit"
  endglobals

  private constant function FS_MissileDamage takes integer lvl returns integer
     return 90*lvl+5
  endfunction

  //conditions

  private function Trig_Frost_Sphere_Conditions takes nothing returns boolean
      return GetSpellAbilityId()==SpellId
  endfunction

  //actions

  private function FS_DamageOfMissile takes nothing returns nothing
     local unit caster  =I2U(GetStoredInteger(GC(),MCode,"c"))
     local unit missile =I2U(GetStoredInteger(GC(),MCode,"m"))
     local unit u       =GetEnumUnit()
        if IsUnitNotImmun(caster,u) and missile!=u then
             call UnitAddAbility(u,BuffSpellId)
             call IssueImmediateOrder(u,BuffOrder)
             call UnitRemoveAbility(u,BuffSpellId)
             call UnitDamageTarget(caster,u,I2R(FS_MissileDamage(GetUnitAbilityLevel(caster,SpellId))),true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
        endif
     set caster =null
     set missile=null
     set u      =null
  endfunction

  function FS_MissileHit takes nothing returns nothing
     local unit caster  =tc
     local unit missile =tm

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

     local group g      =GetUnitsInRange(120,x,y,null,true)
     local effect gfx   =I2E(GetStoredInteger(GC(),HS(missile),"gfx"))

     if CountUnitsInGroup(g)>0 then
     call StoreInteger(GC(),MCode,"c",H2I(caster))
     call StoreInteger(GC(),MCode,"M",H2I(missile))
     call ForGroup(g,function FS_DamageOfMissile)
     call FlushStoredMission(GC(),MCode)
     endif

     call E2Null(AddSpecialEffect(ExplMissileMdl,x,y),1)

     call DestroyEffect(gfx)
     call AB_DestroyGroup(g)
     
     call FlushStoredMission(GC(),HS(missile))
     call RemoveUnit(missile)
     set caster=null
  endfunction

  private struct FrostSphereDatas
    unit sphere
    unit caster
    effect gfx
    real circ
    real angl
    real tdis
    real ttim
  endstruct

  private function FrostSphereMotion takes nothing returns nothing
    local timer t       =GetExpiredTimer()
    local FrostSphereDatas datas=GetStoredInteger(GC(),HS(t),"datas")

    local unit missile  =null
    local real mx       =0
    local real my       =0
    local real ux       =0
    local real uy       =0
    local effect mgfx

    call VUnitPolarXY(datas.sphere,SphereSpeed,datas.angl)
    set datas.tdis=SphereSpeed+datas.tdis

    set ux=GetUnitX(datas.sphere)
    set uy=GetUnitY(datas.sphere)

    if datas.ttim>PerSecondCreate and datas.tdis<=MaxSphereDistance then
         set datas.ttim=0
         call DestroyEffect(datas.gfx)
         set datas.gfx=AddSpecialEffectTarget(MissileMdl,datas.sphere,MissileAttackPoint)
         set datas.circ=datas.circ+TurnSpeed

         set mx=ux+MissileDistance*Cos(datas.circ*bj_DEGTORAD)
         set my=uy+MissileDistance*Sin(datas.circ*bj_DEGTORAD)
 
         set missile=CreateUnit(GetOwningPlayer(datas.caster),DummyId,ux,uy,A2PXY(ux,uy,mx,my))
         set mgfx=AddSpecialEffectTarget(SMissileMdl,missile,SMissileAttackPoint)

         call LaunchNormalCollisionMissileAtPointEx(datas.caster,missile,ux,uy,0,mx,my,MissileSpeed,90,MCode)

         call StoreInteger(GC(),HS(missile),"gfx",H2I(mgfx))
       elseif datas.ttim<=PerSecondCreate then
         set datas.ttim=datas.ttim+PeriodicTime
    endif

    if datas.tdis>MaxSphereDistance then
      call DestroyEffect(AddSpecialEffect(ExplSphereMdl,ux,uy))
      call DestroyEffect(AddSpecialEffect(MissileMdl,ux,uy))
      call DestroyEffect(datas.gfx)
      call RemoveUnit(datas.sphere)
      call FrostSphereDatas.destroy(datas)
      call FlushStoredMission(GC(),HS(t))
      call AB_DestroyTimer(t)
    else
      call TimerStart(t,PeriodicTime,false,function FrostSphereMotion)
      set t=null
    endif
  endfunction

  private function Trig_Frost_Sphere_Actions takes nothing returns nothing
    local timer t       =CreateTimer()
    local location loc  =GetSpellTargetLoc()

    local FrostSphereDatas datas=FrostSphereDatas.create()
    local unit u        =GetTriggerUnit()
    local real x        =GetUnitX(u)
    local real y        =GetUnitY(u)
    local real lx       =GetLocationX(loc)
    local real ly       =GetLocationY(loc)

    local real angle    =A2PXY(x,y,lx,ly)

    local unit sphere   =CreateUnit(Player(14),DummyId,x,y,angle)
    local effect gfx    =AddSpecialEffectTarget(MissileMdl,sphere,MissileAttackPoint)
    
    call TimerStart(t,0,false,function FrostSphereMotion)

    call SetUnitX(sphere,x)
    call SetUnitY(sphere,y)

    set datas.gfx=gfx
    set datas.sphere=sphere
    set datas.caster=u
    set datas.angl=angle
    set datas.circ=0
    set datas.tdis=0
    set datas.ttim=0
    call StoreInteger(GC(),HS(t),"datas",datas)

    call RemoveLocation(loc)
    set t=null
  endfunction

//===========================================================================
function InitTrig_Frost_Sphere takes nothing returns nothing
    set gg_trg_Frost_Sphere = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Frost_Sphere, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Frost_Sphere, Condition( function Trig_Frost_Sphere_Conditions ) )
    call TriggerAddAction( gg_trg_Frost_Sphere, function Trig_Frost_Sphere_Actions )
endfunction
endscope

The Rest (the very bottom you'll find the functions he uses for the missiles)
JASS:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//All functions are made by OrkOfMordor aka Hanky aka MDZ-OrkOfMordor!                                                   //
//                                                                                                                       //
// Thanx to Vexorian for his JassNewGenPack (download the modificated editor at: <a href="http://www.wc3campaigns.net" target="_blank" class="link link--external" rel="nofollow ugc noopener">www.wc3campaigns.net</a>)!                  //
//                                                                                                                       //
// This Spellpack uses:                                                                                                  //
//  - JassNewGenPack                                                                                                     //
//  - some Systems from OrkOfMordor aka Hanky aka MDZ-OrkOfMordor                                                        //
//                                                                                                                       //
// To use this spellpack you need:                                                                                       //
//  - JassNewGenPack                                                                                                     //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function H2I takes handle h returns integer
return h
return 0
endfunction

function I2T takes integer i returns trigger
return i
return null
endfunction

function I2F takes integer i returns fogmodifier
return i
return null
endfunction

function I2Bo takes integer i returns boolexpr
return i
return null
endfunction

function I2G takes integer i returns group
return i
return null
endfunction

function I2Tx takes integer i returns texttag
return i
return null
endfunction

function I2U takes integer i returns unit
return i
return null
endfunction

function I2E takes integer i returns effect
    return i
    return null
endfunction

function I2L takes integer i returns location
    return i
    return null
endfunction

function I2It takes integer i returns item
    return i
    return null
endfunction

function I2Li takes integer i returns lightning
return i
return null
endfunction

function I2B takes integer i returns button
    return i
    return null
endfunction

function I2Ti takes integer i returns timer
    return i
    return null
endfunction

globals
     gamecache cache=InitGameCache(&quot;cache&quot;)
     unit tu=null
     unit tc=null
     unit tm=null
     unit tv=null
endglobals

//========================================================================================================
//Main Functions

function GC takes nothing returns gamecache
    return cache
endfunction

function CalculateMaxMotionTime takes real distance,real speed,real periodictime returns real
    return distance/speed*periodictime
endfunction

function HS takes handle i returns string
    return I2S(H2I(i))
endfunction

function AB_DestroyTrigger takes trigger trig returns nothing
  if trig!=null then
    call TriggerClearActions(trig)
    call TriggerClearConditions(trig)
    call DestroyTrigger(trig)
  endif
endfunction

function AB_DestroyTimer takes timer t returns nothing
  if t!=null then
     call PauseTimer(t)
     call DestroyTimer(t)
  endif
endfunction

function AB_DestroyGroup takes group g returns nothing
  if g!=null then
     call GroupClear(g)
     call DestroyGroup(g)
  endif
endfunction

function AB_DialogDestroy takes dialog log returns nothing
  if log!=null then
     call DialogClear(log)
     call DialogDestroy(log)
  endif
endfunction

function AB_DestroyMultiboard takes multiboard lb returns nothing
  if lb!=null then
     call MultiboardClear(lb)
     call DestroyMultiboard(lb)
  endif
endfunction

function U2Death takes nothing returns nothing
local timer t = GetExpiredTimer()
call RemoveUnit(I2U(GetStoredInteger(GC(),I2S(H2I(t)),&quot;u&quot;)))
call FlushStoredMission(GC(),I2S(H2I(t)))
call AB_DestroyTimer(t)
endfunction

function U2Null takes unit u,real duration returns nothing
local timer t = CreateTimer()
call TimerStart(t,duration,false,function U2Death)
call StoreInteger(GC(),I2S(H2I(t)),&quot;u&quot;,H2I(u))
set t = null
endfunction

function T2Death takes nothing returns nothing
local timer t = GetExpiredTimer()
if I2T(GetStoredInteger(GC(),I2S(H2I(t)),&quot;t&quot;))!=null then
call DestroyTrigger(I2T(GetStoredInteger(GC(),I2S(H2I(t)),&quot;t&quot;)))
endif
call FlushStoredMission(GC(),I2S(H2I(t)))
call AB_DestroyTimer(t)
endfunction

function T2Null takes trigger tt,real duration returns nothing
local timer t = CreateTimer()
call TimerStart(t,duration,false,function T2Death)
call StoreInteger(GC(),I2S(H2I(t)),&quot;t&quot;,H2I(tt))
set t = null
endfunction

function E2Death takes nothing returns nothing
local timer t = GetExpiredTimer()
call DestroyEffect(I2E(GetStoredInteger(GC(),I2S(H2I(t)),&quot;e&quot;)))
call FlushStoredMission(GC(),I2S(H2I(t)))
call AB_DestroyTimer(t)
endfunction

function E2Null takes effect e,real duration returns nothing
local timer t = CreateTimer()
call TimerStart(t,duration,false,function E2Death)
call StoreInteger(GC(),I2S(H2I(t)),&quot;e&quot;,H2I(e))
set t = null
endfunction

function L2Death takes nothing returns nothing
local timer t = GetExpiredTimer()
call DestroyLightning(I2Li(GetStoredInteger(GC(),I2S(H2I(t)),&quot;l&quot;)))
call FlushStoredMission(GC(),I2S(H2I(t)))
call AB_DestroyTimer(t)
endfunction

function L2Null takes lightning l,real duration returns nothing
local timer t = CreateTimer()
call TimerStart(t,duration,false,function L2Death)
call StoreInteger(GC(),I2S(H2I(t)),&quot;l&quot;,H2I(l))
set t = null
endfunction

function TT2Death takes nothing returns nothing
local timer t = GetExpiredTimer()
call DestroyTextTag(I2Tx(GetStoredInteger(GC(),I2S(H2I(t)),&quot;tt&quot;)))
call FlushStoredMission(GC(),I2S(H2I(t)))
call AB_DestroyTimer(t)
endfunction

function TT2Null takes texttag tt,real duration returns nothing
local timer t = CreateTimer()
call TimerStart(t,duration,false,function L2Death)
call StoreInteger(GC(),I2S(H2I(t)),&quot;tt&quot;,H2I(tt))
set t = null
endfunction

function VUnitPolarXY takes unit u,real distance,real angle returns nothing
    local real x=GetUnitX(u)+distance*Cos(angle*3.14159/180)
    local real y=GetUnitY(u)+distance*Sin(angle*3.14159/180)
    if RectContainsCoords(bj_mapInitialPlayableArea,x,y) then
    call SetUnitX(u,x)
    call SetUnitY(u,y)
    endif
endfunction

function SUnitPolarXY takes unit u,real distance,real angle returns nothing
    local real x=GetUnitX(u)+distance*Cos(angle*3.14159/180)
    local real y=GetUnitY(u)+distance*Sin(angle*3.14159/180)
    if RectContainsCoords(bj_mapInitialPlayableArea,x,y) then
    call SetUnitPosition(u,x,y)
    endif
endfunction

function GetUnitPolX takes unit u,real distance,real angle returns real
    local real x=GetUnitX(u)+distance*Cos(angle*3.14159/180)
    return x
endfunction

function GetPolX takes real x,real distance,real angle returns real
    return x+distance*Cos(angle*3.14159/180)
endfunction

function GetUnitPolY takes unit u,real distance,real angle returns real
    local real y=GetUnitY(u)+distance*Sin(angle*3.14159/180)
    return y
endfunction

function GetPolY takes real y,real distance,real angle returns real
    return y+distance*Sin(angle*3.14159/180)
endfunction

function GetTime2Distance takes real distance,real speed,real periodictime returns real
    return distance/speed*periodictime
endfunction

function D2PXY takes real xA,real yA,real xB,real yB returns real
    local real dx = xB - xA
    local real dy = yB - yA
    return SquareRoot(dx * dx + dy * dy)
endfunction

function TerrainDeformationRippleXY takes real duration, boolean limitNeg, real x,real y, real startRadius, real endRadius, real depth, real wavePeriod, real waveWidth returns terraindeformation
    local real spaceWave
    local real timeWave
    local real radiusRatio

    if (endRadius &lt;= 0 or waveWidth &lt;= 0 or wavePeriod &lt;= 0) then
        return null
    endif

    set timeWave = 2.0 * duration / wavePeriod
    set spaceWave = 2.0 * endRadius / waveWidth
    set radiusRatio = startRadius / endRadius

    set bj_lastCreatedTerrainDeformation = TerrainDeformRipple(x,y, endRadius, depth, R2I(duration * 1000), 1, spaceWave, timeWave, radiusRatio, limitNeg)
    return bj_lastCreatedTerrainDeformation
endfunction

function GetFlyParabelEx takes real x1,real y1,real z,real maxtime,real temptime,real maxheight,real speed,real x2,real y2,real x3,real y3 returns real
    local real tdist = D2PXY(x1,y1,x2,y2) / maxtime * speed
    local location l1 = Location(x1,y1)
    local real z1
    local real z2
    local real zxy
    set z1 = GetLocationZ(l1)+z
    call MoveLocation(l1,x2,y2)
    set z2 = GetLocationZ(l1)
    call MoveLocation(l1,x3,y3)
    set zxy = (GetLocationZ(l1)-z1) / D2PXY(x1,y1,x3,y3)
    call RemoveLocation(l1)
    return maxheight - maxheight / maxtime / maxtime * 4 * (temptime-maxtime/2) * (temptime-maxtime/2) + temptime / speed * tdist * zxy + z1 - z2
endfunction

function CreateTextTagXY takes string s,real x,real y,real zOffset,real size,real red,real green,real blue,real transparency returns texttag
    set bj_lastCreatedTextTag=CreateTextTag()
    call SetTextTagText(bj_lastCreatedTextTag,s,size*0.023/10)
    call SetTextTagPos(bj_lastCreatedTextTag,x,y,zOffset)
    call SetTextTagColor(bj_lastCreatedTextTag,PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
    return bj_lastCreatedTextTag
endfunction

function CreateZ takes real x,real y returns real
  local location o = Location(x,y)
  local real z = GetLocationZ(o)
  call RemoveLocation(o)
  return z
endfunction

function GetUnitsInRange takes real radius,real x,real y,boolexpr filter,boolean wantdestroy returns group
    local group g = CreateGroup()
    call GroupEnumUnitsInRange(g,x,y,radius,filter)
    if wantdestroy then
    call DestroyBoolExpr(filter)
    endif
    set filter=null
    return g
endfunction

function A2PXY takes real xA,real yA,real xB,real yB returns real
    return bj_RADTODEG * Atan2(yB - yA, xB - xA)
endfunction

scope CountDestructable
  globals
     private rect dat_prove=null
  endglobals

  private function CountDestructableInRange_Rect takes nothing returns rect
    if dat_prove==null then
        set dat_prove=Rect(0,0,0,0)
    endif
  return dat_prove
  endfunction

  private function EnumCountDestructables takes nothing returns nothing
    if GetDestructableLife(GetEnumDestructable())&gt;0 then
        set bj_forLoopAIndex=bj_forLoopAIndex+1
    endif
  endfunction

  function CountDestructableInRangeOfXY takes real x,real y,real range returns integer
    call SetRect(CountDestructableInRange_Rect(),x-range,y-range,x+range,y+range)
    set bj_forLoopAIndex=0
    call EnumDestructablesInRect(CountDestructableInRange_Rect(),null,function EnumCountDestructables)
    return bj_forLoopAIndex
  endfunction
endscope

function IsUnitNotImmun takes unit c,unit u returns boolean
    if c!=u and not IsUnitType(u,UNIT_TYPE_STRUCTURE) and not IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(u, GetOwningPlayer(c)) and GetUnitState(u,UNIT_STATE_LIFE) &gt; 0.00 then
        return true
    endif
return false
endfunction

constant function BugUse_FlyAbility takes nothing returns integer
    return &#039;Amrf&#039;
endfunction

function BugUse_AddFlyAbility takes unit u returns nothing
    call UnitAddAbility(u,BugUse_FlyAbility())
    call UnitRemoveAbility(u,BugUse_FlyAbility())
endfunction

//================================================================================================
//Passiv - Damage Skill
//================================================================================================
scope DamageSkill
private struct DSDat
    trigger GetDamage
    trigger GetOrder
    unit attacker
    timer t
endstruct

private function DamageTrig_Conds takes nothing returns boolean
    local DSDat datas        =GetStoredInteger(GC(),HS(GetTriggeringTrigger()),&quot;datas&quot;)
    return GetEventDamageSource()==datas.attacker
endfunction

function DestroyDamageTrig_Vars takes trigger tt returns nothing
    local DSDat datas       =GetStoredInteger(GC(),HS(tt),&quot;datas&quot;)

    call FlushStoredMission(GC(),HS(datas.GetDamage))
    call FlushStoredMission(GC(),HS(datas.GetOrder))
    call FlushStoredMission(GC(),HS(datas.t))

    call AB_DestroyTrigger(datas.GetDamage)
    call AB_DestroyTrigger(datas.GetOrder)
    call AB_DestroyTimer(datas.t)

    call DSDat.destroy(datas)
endfunction

private function TimerDestroy_DamageTrigger takes nothing returns nothing
    local DSDat datas       =GetStoredInteger(GC(),HS(GetExpiredTimer()),&quot;datas&quot;)

    call FlushStoredMission(GC(),HS(datas.GetDamage))
    call FlushStoredMission(GC(),HS(datas.GetOrder))
    call FlushStoredMission(GC(),HS(datas.t))

    call AB_DestroyTrigger(datas.GetDamage)
    call AB_DestroyTrigger(datas.GetOrder)
    call AB_DestroyTimer(datas.t)

    call DSDat.destroy(datas)
endfunction

private function TriggerDestroy_DamageTrigger takes nothing returns nothing
    local DSDat datas       =GetStoredInteger(GC(),HS(GetTriggeringTrigger()),&quot;datas&quot;)

    call FlushStoredMission(GC(),HS(datas.GetDamage))
    call FlushStoredMission(GC(),HS(datas.GetOrder))
    call FlushStoredMission(GC(),HS(datas.t))

    call AB_DestroyTrigger(datas.GetDamage)
    call AB_DestroyTrigger(datas.GetOrder)
    call AB_DestroyTimer(datas.t)

    call DSDat.destroy(datas)
endfunction

function Add_DamageTrigger takes unit attacked,real duration,unit attacker,code func returns nothing
    local DSDat datas        =DSDat.create()

    //Init
    set datas.GetDamage=CreateTrigger()
    set datas.GetOrder=CreateTrigger()
    set datas.t=CreateTimer()
    set datas.attacker=attacker

    //Storing
    call StoreInteger(GC(),HS(datas.GetDamage),&quot;datas&quot;,datas)
    call StoreInteger(GC(),HS(datas.GetOrder),&quot;datas&quot;,datas)
    call StoreInteger(GC(),HS(datas.t),&quot;datas&quot;,datas)

    //Trigger Settings
    call TriggerAddAction(datas.GetDamage,func)
    call TriggerAddCondition(datas.GetDamage,Condition(function DamageTrig_Conds))
    call TriggerRegisterUnitEvent(datas.GetDamage,attacked,EVENT_UNIT_DAMAGED)

    call TriggerAddAction(datas.GetOrder,function TriggerDestroy_DamageTrigger)
    call TriggerRegisterUnitEvent(datas.GetOrder,attacker, EVENT_UNIT_ISSUED_ORDER )

    //Timer Start
    call TimerStart(datas.t,duration,false,function TimerDestroy_DamageTrigger)
endfunction
endscope

//Motion System
scope MotionSystem
globals
   trigger motionsystem=null
   group motiongroup=null
   private constant string code=&quot;EnumAddTo_CollisionMissileGroup&quot;
   private constant real MinChaseRange=10.00
   private constant real MovementPerOfMissile=0.03
endglobals

private struct MotionDatas
   real x1
   real y1
   real x3
   real y3
   real endh
   real begh
   real speed
   real tt
   real h
   real range
   real Zrate
   
   unit target
   unit attacker
   
   string endfunc
   integer mode
endstruct

private function EnumAddTo_CollisionMissileGroup takes nothing returns nothing
    local unit caster=tc
    local unit u=GetEnumUnit()
    local group g    =I2G(GetStoredInteger(GC(),code,&quot;group&quot;))
      if IsUnitNotImmun(caster,u) and tu!=u then
         call GroupAddUnit(g,u)
      endif
    set g=null
    set caster=null
    set u=null
endfunction

function RemoveUnitFromMissileGroup takes unit u returns nothing
    if IsUnitInGroup(u,motiongroup) then
     call GroupRemoveUnit(motiongroup,u)
       if CountUnitsInGroup(motiongroup)&lt;=0 then
        call AB_DestroyGroup(motiongroup)
        call AB_DestroyTrigger(motionsystem)
        set motionsystem=null
       endif
    endif
endfunction

function EnumObjects_Motion takes nothing returns nothing
    local unit u          =GetEnumUnit()
    local MotionDatas MD  =GetStoredInteger(GC(),&quot;MD&quot;+HS(u),&quot;MotionDatas&quot;)
    local real distance   =D2PXY(MD.x1,MD.y1,MD.x3,MD.y3)
    local real angle      =A2PXY(MD.x1,MD.y1,MD.x3,MD.y3)
    local real curv
    local group coll
    
    set MD.tt=MD.tt+MovementPerOfMissile
    
    if MD.mode==1 then
        if MD.tt&lt;distance/MD.speed*MovementPerOfMissile then
            call VUnitPolarXY(u,MD.speed,angle)
              if MD.begh!=MD.endh then
                set curv=GetFlyParabelEx(MD.x1,MD.y1,MD.begh,distance/MD.speed*MovementPerOfMissile,MD.tt,MD.endh,MD.speed,GetUnitX(u),GetUnitY(u),MD.x3,MD.y3)
              else
                set curv=MD.begh
              endif
        call BugUse_AddFlyAbility(u)
        call SetUnitFlyHeight(u,curv,0)
       else
        call RemoveUnitFromMissileGroup(u)
        call MotionDatas.destroy(MD)
        call FlushStoredMission(GC(),&quot;MD&quot;+HS(u))
       endif
    endif

    if MD.mode==2 then
        set distance=D2PXY(GetUnitX(u),GetUnitY(u),GetUnitX(MD.target),GetUnitY(MD.target))
        
        if distance&gt;MinChaseRange and GetUnitState(u,UNIT_STATE_LIFE) &gt; 0.00 then
           set angle   =A2PXY(GetUnitX(u),GetUnitY(u),GetUnitX(MD.target),GetUnitY(MD.target))
           call VUnitPolarXY(u,MD.speed,angle)
           call BugUse_AddFlyAbility(u)
           call SetUnitFlyHeight(u,MD.h,MD.Zrate)
        else
         call FlushStoredMission(GC(),&quot;MD&quot;+HS(u))
          if MD.endfunc!=&quot;&quot; then
              set tv=MD.target
              set tm=u
              set tc=MD.attacker
              call ExecuteFunc(MD.endfunc)
          endif
         call RemoveUnitFromMissileGroup(u)
        call MotionDatas.destroy(MD)
       endif
    endif

    if MD.mode==3 then
         set tu=GetEnumUnit()
         call StoreInteger(GC(),code,&quot;group&quot;,H2I(CreateGroup()))
         set tc=MD.attacker
         set coll=GetUnitsInRange(MD.range,GetUnitX(u),GetUnitY(u),null,true)
         call ForGroup(coll,function EnumAddTo_CollisionMissileGroup)
         call AB_DestroyGroup(coll)
         set coll=I2G(GetStoredInteger(GC(),code,&quot;group&quot;))
         call FlushStoredMission(GC(),code)
             if MD.tt&lt;distance/MD.speed*MovementPerOfMissile and CountUnitsInGroup(coll)&lt;=0 then
                 call VUnitPolarXY(u,MD.speed,angle)
                 call BugUse_AddFlyAbility(u)
                 call SetUnitFlyHeight(u,MD.h,0)
             else
               call FlushStoredMission(GC(),&quot;MD&quot;+HS(u))
                 if MD.endfunc!=&quot;&quot; then
                     set tm=GetEnumUnit()
                     set tc=MD.attacker
                     call ExecuteFunc(MD.endfunc)
                 endif
               call RemoveUnitFromMissileGroup(u) 
               call MotionDatas.destroy(MD)
             endif
          call AB_DestroyGroup(coll)
     endif

  set u=null
endfunction

function MotionSystem takes nothing returns nothing
   if CountUnitsInGroup(motiongroup)&gt;0 then
    call ForGroup(motiongroup,function EnumObjects_Motion)
   endif
endfunction

function AddUnitToMissileGroup takes unit u returns nothing
    if not IsUnitInGroup(u,motiongroup) then
         if motionsystem==null then
           set motiongroup=CreateGroup()
           set motionsystem=CreateTrigger()
           call TriggerRegisterTimerEventPeriodic( motionsystem, MovementPerOfMissile )
           call TriggerAddAction( motionsystem, function MotionSystem )
     endif
     call GroupAddUnit(motiongroup,u)
    endif    
endfunction

function LaunchMissileAtPointEx takes unit u,real x1,real y1,real begh,real endh,real x3,real y3,real speed returns nothing
    local MotionDatas MD  =MotionDatas.create()
    
    set MD.tt        =0
    set MD.begh      =begh
    set MD.endh      =endh
    set MD.x1        =x1
    set MD.y1        =y1
    set MD.x3        =x3
    set MD.y3        =y3
    set MD.speed     =speed
    set MD.mode      =1
    
    call SetUnitPosition(u,x1,y1)
    call AddUnitToMissileGroup(u)
    call StoreInteger(GC(),&quot;MD&quot;+HS(u),&quot;MotionDatas&quot;,MD)
endfunction

function LaunchNormalChaseMissileAtPointEx takes unit attacker,unit missile,real x1,real y1,real h,unit victim,real speed,real Zrate,string colfunc returns nothing
    local MotionDatas MD  =MotionDatas.create()
    
    set MD.tt        =0
    set MD.h         =h
    set MD.attacker  =attacker
    set MD.target    =victim
    set MD.speed     =speed
    set MD.endfunc   =colfunc
    set MD.mode      =2
    set MD.Zrate      =Zrate
    
    call SetUnitPosition(missile,x1,y1)
    call AddUnitToMissileGroup(missile)
    call StoreInteger(GC(),&quot;MD&quot;+HS(missile),&quot;MotionDatas&quot;,MD)
endfunction

function LaunchNormalCollisionMissileAtPointEx takes unit attacker,unit missile,real x1,real y1,real h,real x3,real y3,real speed,real range,string colfunc returns nothing
    local MotionDatas MD  =MotionDatas.create()
    
    set MD.tt         =0
    set MD.attacker   =attacker
    set MD.h          =h
    set MD.x1         =x1
    set MD.y1         =y1
    set MD.x3         =x3
    set MD.y3         =y3
    set MD.range      =range
    set MD.speed      =speed
    set MD.endfunc    =colfunc
    set MD.mode       =3
    
    call SetUnitPosition(missile,x1,y1)
    call AddUnitToMissileGroup(missile)
    call StoreInteger(GC(),&quot;MD&quot;+HS(missile),&quot;MotionDatas&quot;,MD)
endfunction
endscope

I didn't steal anything...^_^ (The code is from a spell map from Hiveworkshop.com, SpellPackForNgO.w3x)
 

Terrabull

Veteran Member (Done that)
Reaction score
38
The space wasn't memory...it was reading space...

We all have page down keys, and if you are really worried about that, drop it into spoiler tags. Plus, if someone in the future has the same problem as you and does a search, he can't see the before and after code, so it might hinder his learning.
 

Cidzero

Imma firin mah lazer!!!1!1
Reaction score
39
We all have page down keys, and if you are really worried about that, drop it into spoiler tags. Plus, if someone in the future has the same problem as you and does a search, he can't see the before and after code, so it might hinder his learning.

I'm just a wierd guy. And good point...ofc if they're like me, they still don't understand the problem fully.
 

Sooda

Diversity enchants
Reaction score
318
> BTW sooda, you are quite wrong. Mandatory allocate(), what?

allocate() is mentioned in TH' s Struct tutorial by Andrewgosu, thought without that it doesn't work. I believe you because you made vJASS. What is purpose of allocate() then?
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top