Spell Molten Matter

GoGo-Boy

You can change this now in User CP
Reaction score
40
GoGo-Boy aka Na_Dann_Ma_GoGo presents: MOLTEN MATTER


JASS: Yes.
vJASS: Yes.
MUI: Yes.
Laggless: Yes.
Leakless: Yes.
JESP: Hopefully, you got to tell me :)
Requires: NewGen Editor, ABCT Credits to Cohadar
The really nice testmap was made by Tinki3 and then edited by me to suit this certain spell testing.

Description:
This is a spell which can be used for dummy spells that are based of stuff that targets a location. A projectile will fly towards the targeted location and deals damage in a radius. While flying the projectile checks units in its range and little projectiles will spread out and target the checked units' location. This however only happens once to each unit. The little projectiles deal a minor damage in a minor radius. If the big projectile is in a certain range to it's impact location it will NOT release any further little balls, since that doesn't make any sense and I had to re-script quite a lot stuff to let the little projectiles fly on while the main one is already exploded.



Tooltip:
The caster throws a chunk of molten matter towards a targeted location. Whenever a units comes within 400 AOE of that liquid mass parts of the matter split and float to the units location (neither the big chunk nor the little chops FOLLOW a unit). On impact the little parts deal 15 * level damage while the big one can cause up to 75 * level damage in a certain radius. The more matter has been split the less damage the greater impact deals. A maximum of 15 matter chops can spread out before the main matter explodes without dealing any damage.

Level 1 - A chunk of molten matter that flies towards the targeted position and loses some matter, that target units. On impact the little chops deal 15 and the big matter ball up to 75 damage.

Level 2 - A chunk of molten matter that flies towards the targeted position and loses some matter, that target units. On impact the little chops deal 30 and the big matter ball up to 150 damage.

Level 3 - A chunk of molten matter that flies towards the targeted position and loses some matter, that target units. On impact the little chops deal 45 and the big matter ball up to 225 damage.

Screenshot:
moltenmatterhx9.jpg

Implantation can be read in an explanation above the trigger.

Here comes the code:
JASS:
scope MoltenMatter

globals
    private constant integer FIREBALL_DUMMY = 'u001' // this dummy model must have the dummy.mdx model to work. It is included in the import manager+
    private constant integer DUMMY_SPELL_ID = 'A000' // enter the correct ability ID of the ability you use
    private constant string EXPLODE_PATH = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl" // model path for the impact effect of the main lavaball
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_UNIVERSAL // the damage type
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_CHAOS // the attack type
    private constant real BIG_BALL_SIZE = 2.1 // the size of the main lavaball
    private constant real SIZE_LOSS = 0.04 // this determinates the size loss of the main ball whenever little ones spread out
    private constant real LITTLE_BALL_SIZE = 0.85 // the size of the spreeding lavaball
    private constant real SPEED = 20  // distance amount the fireballs move per interval
    private constant real LITTLE_SPEED = 20
    private constant integer MAX_BALLS = 15 // determinates the amount of balls that can spread out of the big one, should NOT be set too high because the struct limit might struggle then
    private constant real RADIUS = 400 // this is the radius in which little balls spread out of the main one and fly forwards enemy units
    // better do NOT combine a low LITTLE_SPEED with a hugh RADIUS and high MAX_BALLS because that could end up laggy, since a lot units might be moved in some situations
   
    private constant real BIG_DAMAGE_RADIUS = 300  // the damage radius for the main-impact
    private constant real LITTLE_DAMAGE_RADIUS = 150 // same for the one of the little lavaballs
    private constant real BIG_DAMAGE = 75 // AOE damage dealt on impact by the big lavaball
    private constant real LITTLE_DAMAGE = 15 // the amount of AOE damage dealt by little lavaballs for each ability level (level 3 will deal 45...)
    private constant real FIREBALL_FLIGHT_HEIGHT = 60 // fly high for all lavaballs, looks very well with 60 in my opinion
    
    // please do NOT touch these globals because they're not variables that are made for being configurable rather for improving the performance or provide savety!!
    private constant real SLIDE_PERIOD = 0.035 // interval in which the fireball moves [better don't change because 0.035 is smooth enough]
    private player PLAYER // global player to filter out enemy units because you can't use GetTriggerPlayer/Unit() in filterfunctions that are called in a callback function
    private group CHECK_GROUP // global group that is set in each callback function to ensure an easy filtering of units that are already hit --- similar to PLAYER above
    private group GROUP  = CreateGroup() // a global group to improve performance and perhaps even readability
    private real MaxX // this x-value will prevent the fireball from leaving the map and thus crashing the game [set at MapInit as well]
    private real MinX // " "
    private real MaxY // " same with y "
    private real MinY  // " "
endglobals


// function to determinate the damage caused by the impact of the hugh lavaball added this to
// the top because some guys wanna might deal in damage in a certain way [e.g. with attributes]
private function Damage takes integer level, real RaiseTo returns real  
    return level * BIG_DAMAGE * Pow(0.95,R2I(RaiseTo))
endfunction

private function LittleDamage takes integer level returns real  
    return level * LITTLE_DAMAGE
endfunction

// filterfunction to filter units around the big lavaball that shall be targeted by little lavaballs
// simply add an extra    "if ..... then " and for sure an "endif" afterwards, if you would like to add something 
private function filt takes nothing returns boolean
        local unit u = GetFilterUnit()
        if IsUnitType(u,UNIT_TYPE_STRUCTURE) != true then
            if GetWidgetLife(u) > 0 then
                if IsUnitInGroup(u,CHECK_GROUP) != true then
                    if IsUnitEnemy(u,PLAYER) then
                        set u = null
                        return true
                    endif
                endif
            endif
        endif
        set u = null
        return false
endfunction

// this function filters out the units that shall be damaged on little and big lava ball impacts
// again add an extra    "if ..... then " and for sure an "endif" afterwards...
private function filtdamager takes nothing returns boolean
        local unit u = GetFilterUnit()
        if IsUnitType(u,UNIT_TYPE_STRUCTURE) != true then
            if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) != true then
                if GetWidgetLife(u) > 0 then
                    if IsUnitEnemy(u,PLAYER) then
                        set u = null
                        return true
                    endif
                endif
            endif
        endif
        set u = null
        return false
endfunction


// ------------> STOP ADAPTING THINGS TO YOUR WISHES FROM HERE ON IF YOU ARE NOT EXPERIENCED ENOUGH!!! <---------


// functin to take care about SetUnitX/Y
private function InMap takes real x, real y returns boolean
    return x >= MinX and x <= MaxX and y >= MinY and y <= MaxY
endfunction

private struct Fireball
    real x
    real y
    real array l_x[MAX_BALLS]     // arrays are used for the little lavaballs the "l_" - prefix means that these arrays are used for the little lavaballs
    real array l_y[MAX_BALLS]
    unit fireball
    unit array ball[MAX_BALLS]
    player owner
    unit caster
    real big_size = BIG_BALL_SIZE
    integer level
    integer ticks
    integer no_more = R2I(BIG_DAMAGE_RADIUS / SPEED) // this is used to prevent little lavaballs from spreading out shortly before the impact, because they were destroyed then anyway...
    integer array l_ticks[MAX_BALLS]
    integer current_balls = 0
    real facing
    real array l_facing[MAX_BALLS]
    group already_hit = CreateGroup()
    
    static method create takes nothing returns Fireball
        local Fireball data = Fireball.allocate()
        local real x
        local real y 
        local location l = GetSpellTargetLoc()
        local real x2 = GetLocationX(l)
        local real y2 = GetLocationY(l)
            set data.caster = GetTriggerUnit()
            set data.x = GetUnitX(data.caster)
            set data.y = GetUnitY(data.caster)
            set x = x2 - data.x
            set y = y2 - data.y 
            set data.owner = GetTriggerPlayer()
            set data.level = GetUnitAbilityLevel(data.caster,GetSpellAbilityId())
            set data.facing = Atan2(y,x)
            set data.fireball = CreateUnit(data.owner,FIREBALL_DUMMY,data.x,data.y,GetUnitFacing(data.caster))
            set data.ticks = R2I(SquareRoot(x * x + y * y) / SPEED)
                call SetUnitFlyHeight(data.fireball,FIREBALL_FLIGHT_HEIGHT,0)
                call SetUnitScale(data.fireball,BIG_BALL_SIZE,BIG_BALL_SIZE,BIG_BALL_SIZE)
                call RemoveLocation(l)
            set l = null
        return data
    endmethod
   
    method onDestroy takes nothing returns nothing
    local integer index = 1
        
        call DestroyGroup(.already_hit)
        call KillUnit(.fireball)
    set .fireball = null
    set .caster = null
       loop
                call KillUnit(.ball[index])
            set .ball[index] = null
            set index = index + 1
            exitwhen index == MAX_BALLS
        endloop  
   endmethod
        
endstruct

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == DUMMY_SPELL_ID
endfunction

private function Callback takes nothing returns boolean
local Fireball data = ABCT_GetData()
local unit victim
local real x = data.x + SPEED * Cos(data.facing)
local real y = data.y + SPEED * Sin(data.facing)
local real l_x
local real l_y
local integer index = 0
local unit ball
    set PLAYER = data.owner
    set CHECK_GROUP = data.already_hit
    
        if data.current_balls <= MAX_BALLS then 
        
            if data.ticks >= data.no_more then 
                call GroupEnumUnitsInRange(GROUP,data.x,data.y,RADIUS,Filter(function filt))

                loop
                    set victim = FirstOfGroup(GROUP)
                    set index = data.current_balls
                        exitwhen victim == null // exitwhen victim == null means that the group is empty. That's why I don't use GroupClear()... but does it work without leaking that way??
                        set data.current_balls = data.current_balls + 1
                        set index = index + 1
                        set data.ball[index] = CreateUnit(data.owner,FIREBALL_DUMMY,data.x,data.y,bj_UNIT_FACING)
                        set data.big_size = data.big_size - SIZE_LOSS
                        set l_x = GetUnitX(victim) - data.x
                        set l_y = GetUnitY(victim) - data.y
                        set data.l_x[index] = data.x
                        set data.l_y[index] = data.y
                        set data.l_facing[index] = Atan2(l_y,l_x)                
                        set data.l_ticks[index] = R2I(SquareRoot(l_x *l_x + l_y * l_y) / LITTLE_SPEED)
                            call GroupRemoveUnit(GROUP,victim) // unit removing
                            call GroupAddUnit(data.already_hit,victim)                        
                            call SetUnitFlyHeight(data.ball[index],FIREBALL_FLIGHT_HEIGHT,0)
                            call SetUnitScale(data.ball[index],LITTLE_BALL_SIZE,LITTLE_BALL_SIZE,LITTLE_BALL_SIZE)
                endloop           
            endif 
        
        set index = 1    
        loop
        
            exitwhen index >  data.current_balls
            if GetWidgetLife(data.ball[index]) >= 0.406 then 
                if data.l_ticks[index] >= 1 then 
                    set data.l_x[index] = data.l_x[index] + LITTLE_SPEED * Cos(data.l_facing[index])
                    set data.l_y[index] = data.l_y[index] + LITTLE_SPEED * Sin(data.l_facing[index])
                    if InMap(data.l_x[index],data.l_y[index]) then
                        call SetUnitX(data.ball[index],data.l_x[index])
                        call SetUnitY(data.ball[index],data.l_y[index])
                    endif
                    set data.l_ticks[index] = data.l_ticks[index] - 1
                else 
                        

                    call GroupEnumUnitsInRange(GROUP,data.l_x[index],data.l_y[index],LITTLE_DAMAGE_RADIUS,Filter(function filtdamager))
        
                    loop
                            set victim = FirstOfGroup(GROUP)
                            exitwhen victim == null
                                call GroupRemoveUnit(GROUP,victim)
                                call UnitDamageTarget(data.caster,victim,LittleDamage(data.level),false,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE_WHOKNOWS)
                    endloop
                    call KillUnit(data.ball[index])
                endif 
                endif 
                    set index = index + 1
        endloop
        
                if InMap(x,y) then
                    call SetUnitX(data.fireball,x)
                    call SetUnitY(data.fireball,y)
                endif
                
                call SetUnitScale(data.fireball,data.big_size,data.big_size,data.big_size)
                    set data.x = x
                    set data.y = y
                    set data.ticks = data.ticks - 1
                    
                if data.ticks <= 0 then 
                
                       
                    call GroupEnumUnitsInRange(GROUP,data.x,data.y,BIG_DAMAGE_RADIUS,Filter(function filtdamager))
                                
                    loop
                        set victim = FirstOfGroup(GROUP)
                        exitwhen victim == null
                    
                            call GroupRemoveUnit(GROUP,victim)
                            call UnitDamageTarget(data.caster,victim,Damage(data.level,R2I(data.current_balls)),false,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE_WHOKNOWS)
                    endloop
                    call DestroyEffect(AddSpecialEffect(EXPLODE_PATH,GetUnitX(data.fireball),GetUnitY(data.fireball)))
                    
            set ball = null
                    call data.destroy()
                    
                return true
                
                endif
    
                    set ball = null
                return false
         

        endif 
            call data.destroy()
        return true
endfunction

private function Actions takes nothing returns nothing
local Fireball data = Fireball.create()

    call ABCT_Start(function Callback, data, SLIDE_PERIOD)
endfunction

public function InitTrig takes nothing returns nothing
local trigger trig = CreateTrigger()
 
    set MinX = GetRectMinX(bj_mapInitialPlayableArea) + 100
    set MaxX = GetRectMaxX(bj_mapInitialPlayableArea) - 100
    set MinY = GetRectMinY(bj_mapInitialPlayableArea) + 100
    set MaxY = GetRectMaxY(bj_mapInitialPlayableArea) - 100
        call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(trig, Condition(function Conditions))
        call TriggerAddAction(trig, function Actions)

endfunction

endscope

Changelog: Replaced GetUnitState(...) > 0 with GetWidgetLife(..) > 0
Remove an unnecessary timer and a global group is now used for all the loop stuff I do

Have fun testing it and please comment and critique me!! Probable this spell can be improved and yet does leak!

Give Credits!

PS: My first spell I submitted and in case my English isn't very well excuse me ^^
 

Attachments

  • Spell Molten Matter.w3x
    60.3 KB · Views: 510
Didn't read through the entire code, but:
JASS:
private function filt takes nothing returns boolean
        local unit u = GetFilterUnit()
        if IsUnitType(u,UNIT_TYPE_STRUCTURE) != true then
            if GetUnitState(u,UNIT_STATE_LIFE) > 0 then
                if IsUnitInGroup(u,CHECK_GROUP) != true then
                    if IsUnitEnemy(u,PLAYER) then
                        set u = null
                        return true
                    endif
                endif
            endif
        endif
        set u = null
        return false
endfunction


Can be changed to:
JASS:
private function filt takes nothing returns boolean
        local unit u = GetFilterUnit()
        return IsUnitType(u,UNIT_TYPE_STRUCTURE) != true and GetUnitState(u,UNIT_STATE_LIFE) > 0 and IsUnitInGroup(u,CHECK_GROUP) != true and IsUnitEnemy(u,PLAYER)
       // set u = null << you won't be able to null because of the return.
endfunction


And

JASS:
private function filtdamager takes nothing returns boolean
        local unit u = GetFilterUnit()
        if IsUnitType(u,UNIT_TYPE_STRUCTURE) != true then
            if IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) != true then
                if GetUnitState(u,UNIT_STATE_LIFE) > 0 then
                    if IsUnitEnemy(u,PLAYER) then
                        set u = null
                        return true
                    endif
                endif
            endif
        endif
        set u = null
        return false
endfunction


Can be changed to:
JASS:
private function filtdamager takes nothing returns boolean
        local unit u = GetFilterUnit()
        return IsUnitType(u,UNIT_TYPE_STRUCTURE) != true and IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) != true and GetUnitState(u,UNIT_STATE_LIFE) > 0 and IsUnitEnemy(u,PLAYER)
        //set u = null << Same as the first function. Can't null because of return.
endfunction


Edit: The Nulling would be pointless though, so if you want to null the unit, you would need a simple If. Not a massive one like you had :p

You could do:
JASS:
private function filtdamager takes nothing returns boolean
        local unit u = GetFilterUnit()
        if IsUnitType(u,UNIT_TYPE_STRUCTURE) != true and IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) != true and GetUnitState(u,UNIT_STATE_LIFE) > 0 and IsUnitEnemy(u,PLAYER) then
             set u = null
             return true
        endif 
        set u = null
        return false
endfunction
 
Great job on the coding and neat spell.

In Romek's example, you need to null, so you can probably just use a bj global or use filter unit.

JASS:
    private constant integer MAX_BALLS = 15 // determinates the amount of balls that can spread out of the big one, should NOT be set too high because the struct limit might struggle then


This just made my day. :p
 
This spell is pretty cool... good work with the coding too, looks pretty clean. The only thing that i could point out is the filter functions you are using, but that has already been addressed by Romek. One more thing though, wouldn't it be better to use GetWidgetLife(GetFilterUnit())>.405 in your filters/functions rather than GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>0? I remember reading and being told that GetWidget... is better for efficiency etc..
 
This spell is pretty cool... good work with the coding too, looks pretty clean. The only thing that i could point out is the filter functions you are using, but that has already been addressed by Romek. One more thing though, wouldn't it be better to use GetWidgetLife(GetFilterUnit())>.405 in your filters/functions rather than GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE)>0? I remember reading and being told that GetWidget... is better for efficiency etc..

Thanks and for the GetWidgetLife thing... I didn't really know about it. I went over the bj way to find the right function and hence used GetUnitState. Will change that azap thanks :)

And thanks to Romek and PurgeandFire as well for feedback,
but I will NOT put my filters into one line. I know most people prefer having a very, very long line instead of a code block, but I'm not one of them. When I look at the filter block I can clearly see every condition at once while when inlining I had to scroll to the right side which is the worst thing on earth!! (isn't it? ;) )
And there isn't any speed difference between if ... then and "and"s anyway I think.

JASS:
private constant integer MAX_BALLS = 15 // determinates the amount of
balls that can spread out of the big one, should NOT be set too high because the struct limit might struggle then


This just made my day.

Hmm you're right lol :D
 
JASS:
integer no_more = R2I(BIG_DAMAGE_RADIUS / SPEED) // this is used to pretend little lavaballs from spreading out shortly before the impact, because they were destroyed then anyway...

...Used to pretend? Should this be prevent?

JASS:
private function Actions takes nothing returns nothing
local Fireball data = Fireball.create()
local timer t = CreateTimer()
call ABCT_Start(function Callback, data, SLIDE_PERIOD)
    set t = null
endfunction

You make and null the timer, why? It's not used in this function...

Overall, this is a very cool spell.
 
Yes it should be prevent and I really don't need the timer. I made it like this because cohadar did is as well in his ABCT test map... so when I was learning I overtook it and thought that ABCT attaches the struct to the timer (however :p). But I tested and it works without. Thanks.

Edit: I also now use a global group for my GroupEnum calls because creating and destroying the group is then unnecessary. I'm yet not sure whether it leaks the way it is... but my question wasn't yet answered in the JASS thread.
 
For your global group, could you not just use:
JASS:
private group GROUP = CreateGroup()

instead of leaving it as nothing, then setting it to a struct variable?
That way there would be no need for the struct group:
JASS:
group already_hit = CreateGroup()

I'm pretty sure that it would still work the same. I'm not sure, i may be wrong here.

Other then that though, this spell seems very nice. Good Work :)
 
First of all you can NOT use function calls to initially set globals to a value. That's why do that at trigger initialization... same for the map border values as you can see.

And I don't know what you mean with my struct group "already_hit". I create it once and it is used for the MUI.
Every unit can be hit by little lavaballs from DIFFERENT greater lavaballs, at least once.
 
Haha, my bad, didn't really read your InitTrig properly :p

Anywho, just out of curiosity, why can you not use CreateGroup() to set the global group? As i have seen it done in numerous MUI spells in the past...

Once again, Great spell :)
 
I've enjoyed the screeny, gj

Lol and thanks.

Anywho, just out of curiosity, why can you not use CreateGroup() to set the global group? As i have seen it done in numerous MUI spells in the past...

Hmmm seems like you're right. I was sure sure that I've been reading something about being unable to use function calls for instant global declaring. And it didn't work for MaxX = GetRectMaxX(bj_mapInitialPlayableArea). But looks like create group can be used (perhaps because you don't need to give it arguments??). Thanks for that, gonna fix it.

Once again, Great spell

Double thanks^^.
 
Ahh finally thanks! I'm working on my structure... next one will hopefully be cleaner :s
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    alternatively if you not making at least 23 an hour you could work in an Aldi warehouse
  • Varine Varine:
    Yeah I've been thinking about using AI for shit. I'm on vacation next week so I'm going to spend some time reorganizing everything and getting all my shit back in order
  • Varine Varine:
    lol I technically make less than 23 right now because I'm on salary and am there all the time, but it's a lot more than a normal wage still. I also have a meeting soon to renegotiate my pay because I want about a 25% increase to account for what I'm actually doing or a re-evaluation of our duties so that that my responsibilities are more in line with my pay. Depending on how that goes I'm prepared to give notice and move on, I don't mind taking less money so I'd have time for the rest of my life, but I'd rather they just fucking pay me enough to justify the commitment on my end. Plus right now I hold pretty much all the cards since I'm the only one actually qualified for my position.
    +1
  • Varine Varine:
    The other chef was there before me and got his position by virtue of being the only adult when the old general manager got married and didn't want to deal with the kitchen all the time, and happened to be in the position when the GM quit. New GM is fine with front of house but doesn't know enough about the kitchen side to really do anything or notice that I'm the one primarily maintaining it. Last time I left they hired like 3 people to replace me and there was still a noticeable drop in quality, so I got offered like 6 dollars an hour more and a pretty significant summer bonus to come back
  • Varine Varine:
    So honestly even if I leave I think it would last a couple of months until it's obvious that I am not exactly replaceable and then I would be in an even better position.
  • Varine Varine:
    But as of right now I have two other job offers that are reasonably close to what my hourly equivalency would be, and I would probably have more time for my other projects. The gap would be pretty easy to fill up if I had time to do my side jobs. I use to do some catering and private events, personal lessons, consultations, ect, and I charge like 120 an hour for those. But they aren't consistent enough for a full time job, too small of a town. And I'm not allowed to move for another year until my probation is over
  • Varine Varine:
    I guess I could get it transferred, but that seems like a hassle.
  • Varine Varine:
    Plus I have a storage room full of broken consoles I need to fix. I need to build a little reflow oven so I can manufacture some mod chips still, but it'll get there.
    +1
  • Varine Varine:
    I would like to get out of cooking in general at some point in the next ten years, but for the time being I can make decent money and pump that into savings. I've been taking some engineering classes online, but those aren't exactly career oriented at the moment, but I think getting into electronic or computer engineering of some sort would be ideal. I'm just going to keep taking some classes here and there until there's one that I am really into.
    +2
  • The Helper The Helper:
    There is money in fixing and reselling consoles. Problem is people know that so they are doing it
  • The Helper The Helper:
    If you can find a source of broken consoles though you can make money fixing them - sometimes some big money
  • Varine Varine:
    I was buying them on Ebay, but it's pretty competitive, so more recently I've just been telling the thrift stores to call me and I will come take all their electronics they can't sell. I've volunteered there before and people use them like a dump sometimes, and so they just have a massive amount of broken shit they throw away
  • Varine Varine:
    The local GoodWill was pretty into it, surprisingly the animal shelter store was not. The lady I talked to there seemed to think I was trying to steal stuff or something, she wasn't very nice about it. Like I'm just trying to stop you having to throw a bunch of electronics away, if you can sell it great. I'd probably pay you for the broken shit too if you wanted
  • Varine Varine:
    Then I make posts on Facebook yard sale pages sometimes saying I want your old electronics, but Facebook being Facebook people on there are also wary about why I want it, then want a bunch of money like it's going to be very worth it
  • Varine Varine:
    Sooner than later I'm going to get my archives business going a little more. I need some office space that is kind of hard to get at the moment, but without it, I have to be like "Yeah so go ahead and just leave your family heirlooms and hundred year old photographs here at my shitty apartment and give me a thousand dollars, and next month I'll give you a thumb drive. I promise I'll take care of them!"
    +1
  • Varine Varine:
    I can do some things with them at their home, but when people have thousands of slides and very delicate newspaper clippings and things, not really practical. I
  • Varine Varine:
    I would be there for days, even with my camera set up slides can take a long time, and if they want perfect captures I really need to use my scanners that are professionally made for that. My camera rig works well for what it is, but for enlargements and things it's not as good.
  • Varine Varine:
    I've only had a couple clients with that so far, though. I don't have a website or anything yet though.
  • Varine Varine:
    Console repair can be worthwhile, but it's also not a thing I can do at scale in my house. I just don't have room for the equipment. I need an office that I can segregate out for archival and then electronic restoration.
  • Varine Varine:
    But in order for that to be real, I need more time, and for more time I need to work less, and to work less I need a different job, and for a different job I need more money to fall back on so that I can make enough to just pay like, rent and utilities and use my savings to find these projects
    +1
  • Varine Varine:
    Another couple years. I just need to take it slow and it'll get there.
  • jonas jonas:
    any chance to get that stolen money back?
  • jonas jonas:
    Maybe you can do console repair just as a side thing, especially if there's so much competition business might be slow. Or do you need a lot of special equipment for that?
  • jonas jonas:
    I recently bought a used sauna and the preowner told me some component is broken, I took a look and it was just a burnt fuse, really cheap to fix. I was real proud of my self since I usually have two left hands for this kinda stuff :p
  • tom_mai78101 tom_mai78101:
    I am still playing Shapez 2. What an awful thing to happen, Varine, and hopefully everything has been sorted out soon. Always use multi-factor authentication whenever you have the opportunity to do so.

      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