"Swap" system, is there anything like it ?

Komaqtion

You can change this now in User CP.
Reaction score
469
Hi!

I was just wondering a couple of things about swap systems...

First, is there any out there ? :S

Second, I've already made one here actually, but it's a bit messy atm and I'm not sure if I've got everything it should have :S

Could you take a look ? :eek:

JASS:
library SwapHero initializer Init requires PlayerColors, TimerUtils

    globals
        private constant boolean TIME_LIMIT_ENABLED = true
        private constant real TIME_LIMIT = 30.0
        
        private constant boolean ONE_SWAP_ONLY = true
        
        private constant boolean CHANGE_POS = true
        
        private force f = CreateForce()
        private group g = CreateGroup()
        private boolean array swapped
    endglobals
    
    private struct Heroes
        player target
        player self
        unit own
        timer t
        
        private static method TimeStop takes nothing returns nothing
            local thistype this = GetTimerData( GetExpiredTimer() )
            
            call DisplayTextToPlayer( this.self, 0.0, 0.0, "You've not recieved any answer from the swapping request, and it has therefore been removed !" )
            
            if swapped[GetPlayerId( this.self )] == true then
                call this.destroy()
            else
                set this.target = null
                set this.self = null
                set this.own = null
            endif
            
        endmethod
        
        static method create takes player target, player self, real time returns thistype
            local thistype this = thistype.allocate()
            local unit u
            
            set this.target = target
            set this.self = self
            
            call GroupEnumUnitsOfPlayer( g, self, null )
            
            loop
                set u = FirstOfGroup( g )
                
                exitwhen u == null or IsUnitType( u, UNIT_TYPE_HERO ) == true
            endloop
            
            set this.own = u
            
            if TIME_LIMIT_ENABLED then
                set this.t = NewTimer()
                
                call SetTimerData( this.t, this )
                call TimerStart( this.t, TIME_LIMIT, false, function thistype.TimeStop )
            endif
            
            return this
        endmethod
        
        private method onDestroy takes nothing returns nothing
            set swapped[GetPlayerId( this.self )] = true
        endmethod
        
    endstruct
    
    globals
        private player triggerer
        private Heroes array Data
    endglobals
    
    private function EnumHeroes takes nothing returns boolean
        local unit u = GetEnumUnit()
        local player p = GetOwningPlayer( u )
        
        if IsUnitType( u, UNIT_TYPE_HERO ) == true and p != triggerer then
            call DisplayTextToPlayer( triggerer, 0.0, 0.0, PlayerColoredString( GetPlayerId( p ), GetUnitName( u ) ) + " : " + PlayerColoredString( GetPlayerId( p ), GetPlayerName( p ) ) )
        endif
        
        return false
    endfunction

    private function HeroDisplay takes nothing returns nothing
        local player p = GetEnumPlayer()
        
        call GroupEnumUnitsOfPlayer( g, p, null )
        call ForGroup( g, function EnumHeroes )
    endfunction

    private function SwapList takes nothing returns boolean
        set triggerer = GetTriggerPlayer()
    
        call ForceEnumPlayers( f, null )
        call ForForce( f, function HeroDisplay )
        
        return false
    endfunction
    
    private function SwapHero takes nothing returns boolean
        local string s = GetEventPlayerChatString()
        local string s2 = SubString( s, 6, 8 )
        local integer i = S2I( s2 ) - 1
        local integer i2 = 0
        local integer i3 = 1
        local player targ = Player( i )
        local player self = GetTriggerPlayer()
        local integer tid = GetPlayerId( targ )
        local integer sid = GetPlayerId( self )
        local real x
        local real y
        local real x2
        local real y2
        local unit temp
        
        if SubString( s, 8, 9 ) == " " or SubString( s, 8, 9 ) == "" then
            set s2 = SubString( s, 6, 7 )
            set i = S2I( s2 ) - 1
        endif
        
        if self != targ and self != null and targ != null then
            
            if Heroes ( Data[sid] ).target != Heroes ( Data[tid] ).self and Heroes ( Data[sid] ).self != Heroes ( Data[tid] ).target and ( swapped[sid]!= true or swapped[tid]!= true ) then
                call DisplayTextToPlayer( self, 0.0, 0.0, "You've asked " + PlayerColoredString( tid, GetPlayerName( targ ) ) + " to swap heroes with you..." + "\n" + "Now you'll have to wait for him to accept !" )
                call DisplayTextToPlayer( targ, 0.0, 0.0, PlayerColoredString( sid, GetPlayerName( self ) ) + " wants to swap heroes with you." + "\n" + "Do you accept ?")
            elseif Heroes ( Data[sid] ).target == Heroes ( Data[tid] ).self and Heroes ( Data[sid] ).self == Heroes ( Data[tid] ).target then
                call DisplayTextToPlayer( self, 0.0, 0.0, "You've accepted " + PlayerColoredString( tid, GetPlayerName( targ ) ) + "'s request to swap heroes with you !" + "\n" + "You'll now recieve the new hero !" )
                call DisplayTextToPlayer( targ, 0.0, 0.0, PlayerColoredString( sid, GetPlayerName( self ) ) + " has accepted your offer to swap heroes..." + "\n" + "You'll now recieve the new hero !")
            elseif swapped[sid] == true then
                call DisplayTextToPlayer( self, 0.0, 0.0, "You've already swapped a hero before, and cannot do so twice !" )
            elseif swapped[tid] == true then
                call DisplayTextToPlayer( targ, 0.0, 0.0, "The player you wish to swap heroes with has already swapped before, and cannot do so twice ! Please choose another player to swap with..." )
            endif
            
            if swapped[sid] != true then
            
                if TIME_LIMIT_ENABLED then
                
                    if Data[sid] == 0 then
                        set Data[sid] = Heroes.create( targ, self, TIME_LIMIT )
                    else
                        set Heroes ( Data[sid] ).target = targ
                        set Heroes ( Data[sid] ).self = self
                    endif
                
                else
            
                    if Data[sid] == 0 then
                        set Data[sid] = Heroes.create( targ, self, 0.0 )
                    else
                        set Heroes ( Data[sid] ).target = targ
                        set Heroes ( Data[sid] ).self = self
                    endif
                
                endif
            
            endif
            
        endif
        
        loop
            
            if Heroes( Data[i2] ).self == targ and Heroes( Data[sid] ).target == targ and Heroes ( Data[i2] ).target == self and Heroes( Data[sid] ).self == self then
                
                loop
                    set x = GetUnitX( Heroes( Data[i2] ).own )
                    set y = GetUnitY( Heroes( Data[i2] ).own )
                    
                    call UnitDropItemPoint( Heroes( Data[i2] ).own, UnitItemInSlot( Heroes( Data[i2] ).own, i3 ), x, y )
                    
                    set x = GetUnitX( Heroes( Data[sid] ).own )
                    set y = GetUnitY( Heroes( Data[sid] ).own )
                    
                    call UnitDropItemPoint( Heroes( Data[sid] ).own, UnitItemInSlot( Heroes( Data[sid] ).own, i3 ), x, y )
                    
                    set i3 = i3 + 1
                    
                    exitwhen i3 > 6
                endloop
                
                if CHANGE_POS == true then
                    set x = GetUnitX( Heroes( Data[i2] ).own )
                    set y = GetUnitY( Heroes( Data[i2] ).own )
                    set x2 = GetUnitX( Heroes( Data[sid] ).own )
                    set y2 = GetUnitY( Heroes( Data[sid] ).own )
                    
                    call SetUnitX( Heroes( Data[sid] ).own, x )
                    call SetUnitY( Heroes( Data[sid] ).own, y )
                    
                    call SetUnitX( Heroes( Data[i2] ).own, x2 )
                    call SetUnitY( Heroes( Data[i2] ).own, y2 )
                endif
                
                call SetUnitOwner( Heroes( Data[i2].own ), self, true )
                call SetUnitOwner( Heroes( Data[sid].own ),targ, true )
                
                set temp = Heroes( Data[sid] ).own
                set Heroes ( Data[sid] ).target = null
                set Heroes ( Data[sid] ).self = null
                set Heroes ( Data[sid] ).own = Heroes ( Data[i2] ).own
                set Heroes ( Data[i2] ).target = null
                set Heroes ( Data[i2] ).self = null
                set Heroes ( Data[i2] ).own = temp
                set temp = null
                
                if ONE_SWAP_ONLY == true then
                    call Heroes( Data[sid] ).destroy()
                    call Heroes( Data[i2] ).destroy()
                endif
                
            endif
            
            set i2 = i2 + 1
            
            exitwhen i2 > 11
        endloop
        
        return false
    endfunction
    
    static if DEBUG_MODE then
    
            function sets takes nothing returns nothing
                set Data[1] = Heroes.create( Player( 0 ), Player( 1 ), 0.0 )
            endfunction
            
    endif

    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        
        loop
            call TriggerRegisterPlayerChatEvent( t, Player( i ), "-swap", true )
            
            set i = i + 1
            
            exitwhen i > 11
        endloop
        
        call TriggerAddCondition( t, Condition( function SwapList ) )
        
        set t = CreateTrigger()
        set i = 0
        
        loop
            call TriggerRegisterPlayerChatEvent( t, Player( i ), "-swap ", false )
            
            set i = i + 1
            
            exitwhen i > 11
        endloop
        
        call TriggerAddCondition( t, Condition( function SwapHero ) )
        
        static if DEBUG_MODE then
        
            set t = CreateTrigger()
            
            call TriggerRegisterTimerEvent( t, 0.01, false )
            call TriggerAddAction( t, function sets )
        
        endif
        
    endfunction
    
endlibrary


So, this will basicall list all heroes and the owning players by typing:
"-swap"

And when you then want to swap, you'll type:
"-swap X" (X - Is the number of the player you want to swap with (GUI range, from 1 - 12))

And then you have to wait for him to accept by typing "-swap yourplayernumber"...

Anything I've missed here ? :S

Third, Will this be useful ? :S
(I'd think so, as I made this by *request from this thread:
http://www.thehelper.net/forums/showthread.php?t=140752)

* By "request", I mean that I saw that he needed it, so I tried to make it XD

Fourth, Have I done it "The right way" ? XD
I mean, I haven't done this from a very wierd approach or concept, right ? :S

Here's a Demo Map, and the system is under the category "Own Systems" and is called "Swap" (Oddly enough :p)
 

Attachments

  • Helping Out 2.w3x
    176.1 KB · Views: 305

Komaqtion

You can change this now in User CP.
Reaction score
469
Just gonna bump this, since I haven't really gotten any help yet...

I really need help with this since I'm just hoping I've done it correctly so far :S
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Hellu ?!

What's wrong !!!!????
Why can't I get any help ?!

Please, if there's some information you're missing, I'll try to provide it to you...
 

quraji

zap
Reaction score
144
Please, if there's some information you're missing, I'll try to provide it to you...

How about, what do you need help with? :p

Is there something wrong with just changing the owners of both heroes to the other player, then changing their position? I didn't really look at the code much, but it seems overcomplicated.

Anyways, I saw (I think) that you were not swapping items, but I think they'd be part of the swap, wouldn't they? What if we're swapping a caster hero and a melee hero? All the spellcasting items I have will be useless for my new fighter :(
I guess you should add a config variable for swapping items.
 

Komaqtion

You can change this now in User CP.
Reaction score
469
How about, what do you need help with? :p

Well, it might not be help exactly, but I want someone to review it, and see if there are any flawes in it (Though I'm unsure if it actually works, as I can't seem to test it correctly... :() or something you want added or if, as you said, it's overcomplicated, help me change it to work better...

I've now added so that the item will get swapped too (They were just dropped on the ground before :p)

JASS:
library SwapHero initializer Init requires PlayerColors, TimerUtils

    globals
        private constant boolean TIME_LIMIT_ENABLED = true
        private constant real TIME_LIMIT = 30.0
        
        private constant boolean ONE_SWAP_ONLY = true
        
        private constant boolean CHANGE_POS = true
        
        private force f = CreateForce()
        private group g = CreateGroup()
        private boolean array swapped
    endglobals
    
    private struct Heroes
        player target
        player self
        unit own
        timer t
        
        private static method TimeStop takes nothing returns nothing
            local thistype this = GetTimerData( GetExpiredTimer() )
            
            call DisplayTextToPlayer( this.self, 0.0, 0.0, "You've not recieved any answer from the swapping request, and it has therefore been removed !" )
            
            if swapped[GetPlayerId( this.self )] == true then
                call this.destroy()
            else
                set this.target = null
                set this.self = null
                set this.own = null
            endif
            
        endmethod
        
        static method create takes player target, player self, real time returns thistype
            local thistype this = thistype.allocate()
            local unit u
            
            set this.target = target
            set this.self = self
            
            call GroupEnumUnitsOfPlayer( g, self, null )
            
            loop
                set u = FirstOfGroup( g )
                
                exitwhen u == null or IsUnitType( u, UNIT_TYPE_HERO ) == true
            endloop
            
            set this.own = u
            
            if TIME_LIMIT_ENABLED then
                set this.t = NewTimer()
                
                call SetTimerData( this.t, this )
                call TimerStart( this.t, TIME_LIMIT, false, function thistype.TimeStop )
            endif
            
            return this
        endmethod
        
        private method onDestroy takes nothing returns nothing
            set swapped[GetPlayerId( this.self )] = true
        endmethod
        
    endstruct
    
    globals
        private player triggerer
        private Heroes array Data
    endglobals
    
    private function EnumHeroes takes nothing returns boolean
        local unit u = GetEnumUnit()
        local player p = GetOwningPlayer( u )
        
        if IsUnitType( u, UNIT_TYPE_HERO ) == true and p != triggerer then
            call DisplayTextToPlayer( triggerer, 0.0, 0.0, PlayerColoredString( GetPlayerId( p ), GetUnitName( u ) ) + " : " + PlayerColoredString( GetPlayerId( p ), GetPlayerName( p ) ) )
        endif
        
        return false
    endfunction

    private function HeroDisplay takes nothing returns nothing
        local player p = GetEnumPlayer()
        
        call GroupEnumUnitsOfPlayer( g, p, null )
        call ForGroup( g, function EnumHeroes )
    endfunction

    private function SwapList takes nothing returns boolean
        set triggerer = GetTriggerPlayer()
    
        call ForceEnumPlayers( f, null )
        call ForForce( f, function HeroDisplay )
        
        return false
    endfunction
    
    private function SwapHero takes nothing returns boolean
        local string s = GetEventPlayerChatString()
        local string s2 = SubString( s, 6, 8 )
        local integer i = S2I( s2 ) - 1
        local integer i2 = 0
        local integer i3 = 0
        local player targ = Player( i )
        local player self = GetTriggerPlayer()
        local integer tid = GetPlayerId( targ )
        local integer sid = GetPlayerId( self )
        local real x
        local real y
        local real x2
        local real y2
        local unit temp
        local item array it1
        local item array it2
        
        if SubString( s, 8, 9 ) == " " or SubString( s, 8, 9 ) == "" then
            set s2 = SubString( s, 6, 7 )
            set i = S2I( s2 ) - 1
        endif
        
        if self != targ and self != null and targ != null then
            
            if Heroes ( Data[sid] ).target != Heroes ( Data[tid] ).self and Heroes ( Data[sid] ).self != Heroes ( Data[tid] ).target and ( swapped[sid]!= true or swapped[tid]!= true ) then
                call DisplayTextToPlayer( self, 0.0, 0.0, "You've asked " + PlayerColoredString( tid, GetPlayerName( targ ) ) + " to swap heroes with you..." + "\n" + "Now you'll have to wait for him to accept !" )
                call DisplayTextToPlayer( targ, 0.0, 0.0, PlayerColoredString( sid, GetPlayerName( self ) ) + " wants to swap heroes with you." + "\n" + "Do you accept ?")
            elseif Heroes ( Data[sid] ).target == Heroes ( Data[tid] ).self and Heroes ( Data[sid] ).self == Heroes ( Data[tid] ).target then
                call DisplayTextToPlayer( self, 0.0, 0.0, "You've accepted " + PlayerColoredString( tid, GetPlayerName( targ ) ) + "'s request to swap heroes with you !" + "\n" + "You'll now recieve the new hero !" )
                call DisplayTextToPlayer( targ, 0.0, 0.0, PlayerColoredString( sid, GetPlayerName( self ) ) + " has accepted your offer to swap heroes..." + "\n" + "You'll now recieve the new hero !")
            elseif swapped[sid] == true then
                call DisplayTextToPlayer( self, 0.0, 0.0, "You've already swapped a hero before, and cannot do so twice !" )
            elseif swapped[tid] == true then
                call DisplayTextToPlayer( targ, 0.0, 0.0, "The player you wish to swap heroes with has already swapped before, and cannot do so twice ! Please choose another player to swap with..." )
            endif
            
            if swapped[sid] != true then
            
                if TIME_LIMIT_ENABLED then
                
                    if Data[sid] == 0 then
                        set Data[sid] = Heroes.create( targ, self, TIME_LIMIT )
                    else
                        set Heroes ( Data[sid] ).target = targ
                        set Heroes ( Data[sid] ).self = self
                    endif
                
                else
            
                    if Data[sid] == 0 then
                        set Data[sid] = Heroes.create( targ, self, 0.0 )
                    else
                        set Heroes ( Data[sid] ).target = targ
                        set Heroes ( Data[sid] ).self = self
                    endif
                
                endif
            
            endif
            
        endif
        
        loop
            
            if Heroes( Data[i2] ).self == targ and Heroes( Data[sid] ).target == targ and Heroes ( Data[i2] ).target == self and Heroes( Data[sid] ).self == self then
                
                loop
                    set x = GetUnitX( Heroes( Data[i2] ).own )
                    set y = GetUnitY( Heroes( Data[i2] ).own )
                    set it1[i3] = UnitItemInSlot( Heroes( Data[i2] ).own, i3 )
                    
                    call UnitDropItemPoint( Heroes( Data[i2] ).own, it1[i3], x, y )
                    
                    set x = GetUnitX( Heroes( Data[sid] ).own )
                    set y = GetUnitY( Heroes( Data[sid] ).own )
                    set it2[i3] = UnitItemInSlot( Heroes( Data[sid] ).own, i3 )
                    
                    call UnitDropItemPoint( Heroes( Data[sid] ).own, it1[i3], x, y )
                    call UnitAddItem( Heroes( Data[sid] ).own, it1[i3] )
                    call UnitAddItem( Heroes( Data[i2] ).own, it2[i3] )
                    
                    set i3 = i3 + 1
                    
                    exitwhen i3 > 6
                endloop
                
                if CHANGE_POS == true then
                    set x = GetUnitX( Heroes( Data[i2] ).own )
                    set y = GetUnitY( Heroes( Data[i2] ).own )
                    set x2 = GetUnitX( Heroes( Data[sid] ).own )
                    set y2 = GetUnitY( Heroes( Data[sid] ).own )
                    
                    call SetUnitX( Heroes( Data[sid] ).own, x )
                    call SetUnitY( Heroes( Data[sid] ).own, y )
                    
                    call SetUnitX( Heroes( Data[i2] ).own, x2 )
                    call SetUnitY( Heroes( Data[i2] ).own, y2 )
                endif
                
                call SetUnitOwner( Heroes( Data[i2].own ), self, true )
                call SetUnitOwner( Heroes( Data[sid].own ),targ, true )
                
                set temp = Heroes( Data[sid] ).own
                set Heroes ( Data[sid] ).target = null
                set Heroes ( Data[sid] ).self = null
                set Heroes ( Data[sid] ).own = Heroes ( Data[i2] ).own
                set Heroes ( Data[i2] ).target = null
                set Heroes ( Data[i2] ).self = null
                set Heroes ( Data[i2] ).own = temp
                set temp = null
                
                if ONE_SWAP_ONLY == true then
                    call Heroes( Data[sid] ).destroy()
                    call Heroes( Data[i2] ).destroy()
                endif
                
            endif
            
            set i2 = i2 + 1
            
            exitwhen i2 > 11
        endloop
        
        return false
    endfunction
    
    static if DEBUG_MODE then
    
            function sets takes nothing returns nothing
                set Data[1] = Heroes.create( Player( 0 ), Player( 1 ), 0.0 )
                
                call BJDebugMsg( "Created !" )
            endfunction
            
    endif

    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        
        loop
            call TriggerRegisterPlayerChatEvent( t, Player( i ), "-swap", true )
            
            set i = i + 1
            
            exitwhen i > 11
        endloop
        
        call TriggerAddCondition( t, Condition( function SwapList ) )
        
        set t = CreateTrigger()
        set i = 0
        
        loop
            call TriggerRegisterPlayerChatEvent( t, Player( i ), "-swap ", false )
            
            set i = i + 1
            
            exitwhen i > 11
        endloop
        
        call TriggerAddCondition( t, Condition( function SwapHero ) )
        
        static if DEBUG_MODE then
        
            set t = CreateTrigger()
            
            call TriggerRegisterTimerEvent( t, 0.01, false )
            call TriggerAddAction( t, function sets )
        
        endif
        
    endfunction
    
endlibrary


And again, I'm unsure if it actually works :S
Any1 wanna test it ? :eek:
 

Komaqtion

You can change this now in User CP.
Reaction score
469
I'm sorry but I will bump this again... :(

I really just want to make it work correctly :(

Please, if you see any flawes or if this code can be reduced to some extent, let me know ! :D
 

nabbig2

New Member
Reaction score
43
I tried the demo map, and I disabled and enabled the trigger System, and it gave two errors.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • 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 The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      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