anchor.diff:  		return FAILED_UNFASTEN
   	return SUCCESSFUL_UNFASTEN
   
  -/obj/proc/default_unfasten_wrench(mob/user, obj/item/I, time = 20) //try to unwrench an object in a WONDERFUL DYNAMIC WAY
  -	if(!(flags_1 & NODECONSTRUCT_1) && I.tool_behaviour == TOOL_WRENCH)
  -		var/turf/ground = get_turf(src)
  -		if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src))
  -			to_chat(user, span_notice("You fail to secure [src]."))
  -			return CANT_UNFASTEN
  -		var/can_be_unfasten = can_be_unfasten_wrench(user)
  -		if(!can_be_unfasten || can_be_unfasten == FAILED_UNFASTEN)
  -			return can_be_unfasten
  -		if(time)
  -			to_chat(user, span_notice("You begin [anchored ? "un" : ""]securing [src]..."))
  -		I.play_tool_sound(src, 50)
  -		var/prev_anchored = anchored
  -		//as long as we're the same anchored state and we're either on a floor or are anchored, toggle our anchored state
  -		if(I.use_tool(src, user, time, extra_checks = CALLBACK(src, .proc/unfasten_wrench_check, prev_anchored, user)))
  -			if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src))
  -				to_chat(user, span_notice("You fail to secure [src]."))
  -				return CANT_UNFASTEN
  -			to_chat(user, span_notice("You [anchored ? "un" : ""]secure [src]."))
  -			set_anchored(!anchored)
  -			playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
  -			SEND_SIGNAL(src, COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH, anchored)
  -			return SUCCESSFUL_UNFASTEN
  +/obj/proc/default_unfasten_wrench(mob/user, obj/item/wrench, time = 20) //try to unwrench an object in a WONDERFUL DYNAMIC WAY
  +	if((flags_1 & NODECONSTRUCT_1) || wrench.tool_behaviour != TOOL_WRENCH)
  +		return CANT_UNFASTEN
  +
  +	var/turf/ground = get_turf(src)
  +	if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src))
  +		to_chat(user, span_notice("You fail to secure [src]."))
  +		return CANT_UNFASTEN
  +	var/can_be_unfasten = can_be_unfasten_wrench(user)
  +	if(!can_be_unfasten || can_be_unfasten == FAILED_UNFASTEN)
  +		return can_be_unfasten
  +	if(time)
  +		to_chat(user, span_notice("You begin [anchored ? "un" : ""]securing [src]..."))
  +	wrench.play_tool_sound(src, 50)
  +	var/prev_anchored = anchored
  +	//as long as we're the same anchored state and we're either on a floor or are anchored, toggle our anchored state
  +	if(!wrench.use_tool(src, user, time, extra_checks = CALLBACK(src, .proc/unfasten_wrench_check, prev_anchored, user)))
   		return FAILED_UNFASTEN
  -	return CANT_UNFASTEN
  +	if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src))
  +		to_chat(user, span_notice("You fail to secure [src]."))
  +		return CANT_UNFASTEN
  +	to_chat(user, span_notice("You [anchored ? "un" : ""]secure [src]."))
  +	set_anchored(!anchored)
  +	playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
  +	SEND_SIGNAL(src, COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH, anchored)
  +	return SUCCESSFUL_UNFASTEN
   
   /obj/proc/unfasten_wrench_check(prev_anchored, mob/user) //for the do_after, this checks if unfastening conditions are still valid
   	if(anchored != prev_anchored)
  
positive.code: 		return FALSE
  	return TRUE
  
  /obj/machinery/proc/exchange_parts(mob/user, obj/item/storage/part_replacer/W)
  	if(!istype(W))
  		return FALSE
  	if((flags_1 & NODECONSTRUCT_1) && !W.works_from_distance)
  		return FALSE
  	var/shouldplaysound = 0
  	if(component_parts)
  		if(panel_open || W.works_from_distance)
  			var/obj/item/circuitboard/machine/CB = locate(/obj/item/circuitboard/machine) in component_parts
  			var/required_type
  			if(W.works_from_distance)
  				to_chat(user, display_parts(user))
  			if(!CB)
  				return FALSE
  			for(var/obj/item/A in component_parts)
  				for(var/design_type in CB.req_components)
  					if(ispath(A.type, design_type))
  						required_type = design_type
  						break
  				for(var/obj/item/B in W.contents)
  					if(istype(B, required_type) && istype(A, required_type))
  						// If it's a corrupt or rigged cell, attempting to send it through Bluespace could have unforeseen consequences.
  						if(istype(B, /obj/item/stock_parts/cell) && W.works_from_distance)
  							var/obj/item/stock_parts/cell/checked_cell = B
  							// If it's rigged or corrupted, max the charge. Then explode it.
  							if(checked_cell.rigged || checked_cell.corrupted)
  								checked_cell.charge = checked_cell.maxcharge
  								checked_cell.explode()
  						if(B.get_part_rating() > A.get_part_rating())
  							if(istype(B,/obj/item/stack)) //conveniently this will mean A is also a stack and I will kill the first person to prove me wrong
  								var/obj/item/stack/SA = A
  								var/obj/item/stack/SB = B
  								var/used_amt = SA.get_amount()
  								if(!SB.use(used_amt))
  									continue //if we don't have the exact amount to replace we don't
  								var/obj/item/stack/SN = new SB.merge_type(null,used_amt)
  								component_parts += SN
  							else
  								if(SEND_SIGNAL(W, COMSIG_TRY_STORAGE_TAKE, B, src))
  									component_parts += B
  									B.forceMove(src)
  							SEND_SIGNAL(W, COMSIG_TRY_STORAGE_INSERT, A, null, null, TRUE)
  							component_parts -= A
  							to_chat(user, span_notice("[capitalize(A.name)] replaced with [B.name]."))
  							shouldplaysound = 1 //Only play the sound when parts are actually replaced!
  							break
  			RefreshParts()
  		else
  			to_chat(user, display_parts(user))
  		if(shouldplaysound)
  			W.play_rped_sound()
  		return TRUE
  	return FALSE
  
  /obj/machinery/proc/display_parts(mob/user)
  	. = list()
  
negative.code: 
  ///Called when the value of `machine_stat` changes, so we can react to it.
  /obj/machinery/proc/on_set_machine_stat(old_value)
  	//From off to on.
  	if((old_value & (NOPOWER|BROKEN|MAINT)) && !(machine_stat & (NOPOWER|BROKEN|MAINT)))
  		set_is_operational(TRUE)
  		return
  	//From on to off.
  	if(machine_stat & (NOPOWER|BROKEN|MAINT))
  		set_is_operational(FALSE)
  
  
  