<commit_before>////////////////////////
// CLOCKWORK MACHINES //
////////////////////////
//not-actually-machines

/obj/structure/clockwork/powered
	var/obj/machinery/power/apc/target_apc
	var/active = FALSE
	var/needs_power = TRUE
	var/active_icon = null //icon_state while process() is being called
	var/inactive_icon = null //icon_state while process() isn't being called

/obj/structure/clockwork/powered/examine(mob/user)
	..()
	if(is_servant_of_ratvar(user) || isobserver(user))
		var/powered = total_accessable_power()
		user << "<span class='[powered ? "brass":"alloy"]'>It has access to [powered == INFINITY ? "INFINITY":"[powered]"]W of power.</span>"

/obj/structure/clockwork/powered/Destroy()
	SSfastprocess.processing -= src
	SSobj.processing -= src
	return ..()

/obj/structure/clockwork/powered/process()
	var/powered = total_accessable_power()
	return powered == PROCESS_KILL ? 25 : powered //make sure we don't accidentally return the arbitrary PROCESS_KILL define

/obj/structure/clockwork/powered/proc/toggle(fast_process, mob/living/user)
	if(user)
		if(!is_servant_of_ratvar(user))
			return 0
		user.visible_message("<span class='notice'>[user] [active ? "dis" : "en"]ables [src].</span>", "<span class='brass'>You [active ? "dis" : "en"]able [src].</span>")
	active = !active
	if(active)
		icon_state = active_icon
		if(fast_process)
			SSfastprocess.processing |= src
		else
			SSobj.processing |= src
	else
		icon_state = inactive_icon
		SSfastprocess.processing -= src
		SSobj.processing -= src


/obj/structure/clockwork/powered/proc/total_accessable_power() //how much power we have and can use
	if(!needs_power || ratvar_awakens)
		return INFINITY //oh yeah we've got power why'd you ask

	var/power = 0
	power += accessable_apc_power()
	power += accessable_sigil_power()
	return power

/obj/structure/clockwork/powered/proc/accessable_apc_power()
	var/power = 0
	var/area/A = get_area(src)
	var/area/targetAPCA
	for(var/obj/machinery/power/apc/APC in apcs_list)
		var/area/APCA = get_area(APC)
		if(APCA == A)
			target_apc = APC
	if(target_apc)
		targetAPCA = get_area(target_apc)
		if(targetAPCA != A)
			target_apc = null
		else if(target_apc.cell)
			var/apccharge = target_apc.cell.charge
			if(apccharge >= 50)
				power += apccharge
	return power

/obj/structure/clockwork/powered/proc/accessable_sigil_power()
	var/power = 0
	for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
		power += T.power_charge
	return power


/obj/structure/clockwork/powered/proc/try_use_power(amount) //try to use an amount of power
	if(!needs_power || ratvar_awakens)
		return 1
	if(amount <= 0)
		return 0
	var/power = total_accessable_power()
	if(!power || power < amount)
		return 0
	return use_power(amount)

/obj/structure/clockwork/powered/proc/use_power(amount) //we've made sure we had power, so now we use it
	var/sigilpower = accessable_sigil_power()
	var/list/sigils_in_range = list()
	for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
		sigils_in_range |= T
	while(sigilpower && amount >= 50)
		for(var/S in sigils_in_range)
			var/obj/effect/clockwork/sigil/transmission/T = S
			if(amount >= 50 && T.modify_charge(50))
				sigilpower -= 50
				amount -= 50
	var/apcpower = accessable_apc_power()
	while(apcpower >= 50 && amount >= 50)
		if(target_apc.cell.use(50))
			apcpower -= 50
			amount -= 50
			target_apc.update()
			target_apc.update_icon()
		else
			apcpower = 0
	if(amount)
		return 0
	else
		return 1

/obj/structure/clockwork/powered/proc/return_power(amount) //returns a given amount of power to all nearby sigils
	if(amount <= 0)
		return 0
	var/list/sigils_in_range = list()
	for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
		sigils_in_range |= T
	if(!sigils_in_range.len)
		return 0
	while(amount >= 50)
		for(var/S in sigils_in_range)
			var/obj/effect/clockwork/sigil/transmission/T = S
			if(amount >= 50 && T.modify_charge(-50))
				amount -= 50
	return 1


/obj/structure/clockwork/powered/mending_motor //Mending motor: A prism that consumes replicant alloy to repair nearby mechanical servants at a quick rate.
	name = "mending motor"
	desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
	clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
	icon_state = "mending_motor_inactive"
	active_icon = "mending_motor"
	inactive_icon = "mending_motor_inactive"
	construction_value = 20
	max_health = 150
	health = 150
	break_message = "<span class='warning'>The prism collapses with a heavy thud!</span>"
	debris = list(/obj/item/clockwork/alloy_shards, /obj/item/clockwork/component/vanguard_cogwheel)
	var/stored_alloy = 0 //250W = 1 alloy
	var/max_alloy = 50000
	var/mob_cost = 200
	var/structure_cost = 250
	var/cyborg_cost = 300

/obj/structure/clockwork/powered/mending_motor/prefilled
	stored_alloy = 5000 //starts with 20 alloy

/obj/structure/clockwork/powered/mending_motor/total_accessable_power()
	. = ..()
	if(. != INFINITY)
		. += accessable_alloy_power()

/obj/structure/clockwork/powered/mending_motor/proc/accessable_alloy_power()
	return stored_alloy

/obj/structure/clockwork/powered/mending_motor/use_power(amount)
	var/alloypower = accessable_alloy_power()
	while(alloypower >= 50 && amount >= 50)
		stored_alloy -= 50
		alloypower -= 50
		amount -= 50
	return ..()

/obj/structure/clockwork/powered/mending_motor/examine(mob/user)
	..()
	if(is_servant_of_ratvar(user) || isobserver(user))
		user << "<span class='alloy'>It has [stored_alloy*0.004]/[max_alloy*0.004] units of replicant alloy, which is equivalent to [stored_alloy]W/[max_alloy]W of power.</span>"
		user << "<span class='inathneq_small'>It requires [mob_cost]W to heal clockwork mobs, [structure_cost]W for clockwork structures, and [cyborg_cost]W for cyborgs.</span>"

/obj/structure/clockwork/powered/mending_motor/process()
	if(!..())
		visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
		toggle()
		return
	for(var/atom/movable/M in range(5, src))
		if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder))
			var/mob/living/simple_animal/hostile/clockwork/marauder/E = M
			if((E.health == E.maxHealth && !E.fatigue) || E.stat)
				continue
			if(!try_use_power(mob_cost))
				break
			E.adjustBruteLoss(-E.maxHealth) //Instant because marauders don't usually take health damage
			E.fatigue = max(0, E.fatigue - 15)
		else if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
			var/mob/living/simple_animal/hostile/clockwork/W = M
			if(W.health == W.maxHealth || W.stat)
				continue
			if(!try_use_power(mob_cost))
				break
			W.adjustBruteLoss(-15)
		else if(istype(M, /obj/structure/clockwork))
			var/obj/structure/clockwork/C = M
			if(C.health == C.max_health)
				continue
			if(!try_use_power(structure_cost))
				break
			C.health = min(C.health + 15, C.max_health)
		else if(issilicon(M))
			var/mob/living/silicon/S = M
			if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
				continue
			if(!try_use_power(cyborg_cost))
				break
			S.adjustBruteLoss(-15)
			S.adjustFireLoss(-15)
	return 1

/obj/structure/clockwork/powered/mending_motor/attack_hand(mob/living/user)
	if(user.canUseTopic(src, BE_CLOSE))
		if(!total_accessable_power() >= 300)
			user << "<span class='warning'>[src] needs more power or replicant alloy to function!</span>"
			return 0
		toggle(0, user)

/obj/structure/clockwork/powered/mending_motor/attackby(obj/item/I, mob/user, params)
	if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user))
		if(stored_alloy + 2500 > max_alloy)
			user << "<span class='warning'>[src] is too full to accept any more alloy!</span>"
			return 0
		user.whisper("Genafzhgr vagb jngre.")
		user.visible_message("<span class='notice'>[user] liquifies [I] and pours it onto [src].</span>", \
		"<span class='notice'>You liquify [src] and pour it onto [src], transferring the alloy into its reserves.</span>")
		stored_alloy = stored_alloy + 2500
		user.drop_item()
		qdel(I)
		return 1
	else
		return ..()



/obj/structure/clockwork/powered/mania_motor //Mania motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs.
	name = "mania motor"
	desc = "A pair of antenna with what appear to be sockets around the base. It reminds you of an antlion."
	clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing hallucinations and brain damage as long as it remains powered."
	icon_state = "mania_motor_inactive"
	active_icon = "mania_motor"
	inactive_icon = "mania_motor_inactive"
	construction_value = 20
	max_health = 80
	health = 80
	break_message = "<span class='warning'>The antenna break off, leaving a pile of shards!</span>"
	debris = list(/obj/item/clockwork/alloy_shards, /obj/item/clockwork/component/guvax_capacitor/antennae)
	var/mania_cost = 150
	var/convert_attempt_cost = 150
	var/convert_cost = 300

	var/mania_messages = list("\"Tb ahgf.\"", "\"Gnxr n penpx ng penml.\"", "\"Znxr n ovq sbe vafnavgl.\"", "\"Trg xbbxl.\"", "\"Zbir gbjneqf znavn.\"", "\"Orpbzr orjvyqrerq.\"", "\"Jnk jvyq.\"", \
	"\"Tb ebhaq gur oraq.\"", "\"Ynaq va yhanpl.\"", "\"Gel qrzragvn.\"", "\"Fgevir gb trg n fperj ybbfr.\"")
	var/compel_messages = list("\"Pbzr pybfre.\"", "\"Nccebnpu gur genafzvggre.\"", "\"Gbhpu gur nagraanr.\"", "\"V nyjnlf unir gb qrny jvgu vqvbgf. Zbir gbjneqf gur znavn zbgbe.\"", \
	"\"Nqinapr sbejneq naq cynpr lbhe urnq orgjrra gur nagraanr - gung'f nyy vg'f tbbq sbe.\"", "\"Vs lbh jrer fznegre, lbh'q or bire urer nyernql.\"", "\"Zbir SBEJNEQ, lbh sbby.\"")
	var/convert_messages = list("\"Lbh jba'g qb. Tb gb fyrrc juvyr V gryy gurfr avgjvgf ubj gb pbaireg lbh.\"", "\"Lbh ner vafhssvpvrag. V zhfg vafgehpg gurfr vqvbgf va gur neg bs pbairefvba.\"", \
	"\"Bu, bs pbhefr, fbzrbar jr pna'g pbaireg. Gurfr freinagf ner sbbyf.\"", "\"Ubj uneq vf vg gb hfr n Fvtvy, naljnl? Nyy vg gnxrf vf qenttvat fbzrbar bagb vg.\"", \
	"\"Ubj qb gurl snvy gb hfr n Fvtvy bs Npprffvba, naljnl?\"", "\"Jul vf vg gung nyy freinagf ner guvf varcg?\"", "\"Vg'f abg yvxryl lbh'yy or fghpx urer ybat.\"")


/obj/structure/clockwork/powered/mania_motor/examine(mob/user)
	..()
	if(is_servant_of_ratvar(user) || isobserver(user))
		user << "<span class='sevtug_small'>It requires [mania_cost]W to run, and [convert_attempt_cost + convert_cost]W to convert humans adjecent to it.</span>"

/obj/structure/clockwork/powered/mania_motor/process()
	var/turf/T = get_turf(src)
	if(!..())
		visible_message("<span class='warning'>[src] hums loudly, then the sockets at its base fall dark!</span>")
		playsound(T, 'sound/effects/screech.ogg', 40, 1)
		toggle(0)
		return
	if(try_use_power(mania_cost))
		var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
		for(var/mob/living/carbon/human/H in range(10, src))
			if(!is_servant_of_ratvar(H) && !H.null_rod_check())
				var/distance = get_dist(T, get_turf(H))
				var/falloff_distance = (110) - distance * 10
				var/sound_distance = falloff_distance * 0.4
				var/targetbrainloss = H.getBrainLoss()
				var/targethallu = H.hallucination
				var/targetdruggy = H.druggy
				if(distance >= 4 && prob(falloff_distance))
					H << "<span class='sevtug_small'>[pick(mania_messages)]</span>"
				H.playsound_local(T, hum, sound_distance, 1)
				switch(distance)
					if(2 to 3)
						if(prob(falloff_distance))
							if(prob(falloff_distance))
								H << "<span class='sevtug_small'>[pick(mania_messages)]</span>"
							else
								H << "<span class='sevtug'>[pick(compel_messages)]</span>"
						if(targetbrainloss <= 70)
							H.adjustBrainLoss(70 - targetbrainloss) //got too close had brain eaten
						if(targetdruggy <= 150)
							H.adjust_drugginess(10)
						if(targethallu <= 150)
							H.hallucination += 10
					if(4 to 5)
						if(targetbrainloss <= 50)
							H.adjustBrainLoss(5)
						if(targetdruggy <= 120)
							H.adjust_drugginess(10)
						if(targethallu <= 120)
							H.hallucination += 10
					if(6 to 7)
						if(targetbrainloss <= 30)
							H.adjustBrainLoss(2)
						if(prob(falloff_distance) && targetdruggy <= 90)
							H.adjust_drugginess(10)
						else if(targethallu <= 90)
							H.hallucination += 10
					if(8 to 9)
						if(H.getBrainLoss() <= 10)
							H.adjustBrainLoss(1)
						if(prob(falloff_distance) && targetdruggy <= 60)
							H.adjust_drugginess(5)
						else if(targethallu <= 60)
							H.hallucination += 5
					if(10 to INFINITY)
						if(prob(falloff_distance) && targetdruggy <= 30)
							H.adjust_drugginess(5)
						else if(targethallu <= 30)
							H.hallucination += 5
					else //if it's a distance of 1 or they're on top of it(how'd they get on top of it???)
						if(try_use_power(convert_attempt_cost))
							if(is_eligible_servant(H) && try_use_power(convert_cost))
								H << "<span class='sevtug'>\"Lbh ner zvar-naq-uvf, abj.\"</span>"
								add_servant_of_ratvar(H)
							else if(!H.stat)
								if(targetbrainloss >= H.maxHealth)
									H.Paralyse(5)
									H << "<span class='sevtug'>[pick(convert_messages)]</span>"
								else
									H.adjustBrainLoss(100)
									H.visible_message("<span class='warning'>[H] reaches out and touches [src].</span>", "<span class='sevtug'>You touch [src] involuntarily.</span>")
						else
							visible_message("<span class='warning'>[src]'s antennae fizzle quietly.</span>")
							playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)

			if(is_servant_of_ratvar(H) && (H.getBrainLoss() || H.hallucination || H.druggy)) //not an else so that newly converted servants are healed of the damage it inflicts
				H.adjustBrainLoss(-H.getBrainLoss()) //heals servants of braindamage, hallucination, and druggy
				H.hallucination = 0
				H.adjust_drugginess(-H.druggy)
	else
		visible_message("<span class='warning'>[src] hums loudly, then the sockets at its base fall dark!</span>")
		playsound(src, 'sound/effects/screech.ogg', 40, 1)
		toggle(0)

/obj/structure/clockwork/powered/mania_motor/attack_hand(mob/living/user)
	if(user.canUseTopic(src, BE_CLOSE))
		if(!total_accessable_power() >= mania_cost)
			user << "<span class='warning'>[src] needs more power to function!</span>"
			return 0
		toggle(0, user)



/obj/structure/clockwork/powered/interdiction_lens //Interdiction lens: A powerful artifact that constantly disrupts electronics but, if it fails to find something to disrupt, turns off.
	name = "interdiction lens"
	desc = "An ominous, double-pronged brass totem. There's a strange gemstone clasped between the pincers."
	clockwork_desc = "A powerful totem that constantly disrupts nearby electronics and funnels power into nearby Sigils of Transmission."
	icon_state = "interdiction_lens"
	construction_value = 25
	active_icon = "interdiction_lens_active"
	inactive_icon = "interdiction_lens"
	break_message = "<span class='warning'>The lens flares a blinding violet before shattering!</span>"
	break_sound = 'sound/effects/Glassbr3.ogg'
	var/recharging = 0 //world.time when the lens was last used
	var/recharge_time = 1200 //if it drains no power and affects no objects, it turns off for two minutes
	var/disabled = FALSE //if it's actually usable
	var/interdiction_range = 14 //how large an area it drains and disables in
	var/disrupt_cost = 100 //how much power to use when disabling an object

/obj/structure/clockwork/powered/interdiction_lens/examine(mob/user)
	..()
	user << "<span class='[recharging > world.time ? "nezbere_small":"brass"]'>Its gemstone [recharging > world.time ? "has been breached by writhing tendrils of blackness that cover the totem" \
	: "vibrates in place and thrums with power"].</span>"
	if(is_servant_of_ratvar(user) || isobserver(user))
		user << "<span class='nezbere_small'>It requires [disrupt_cost]W of power for each nearby disruptable electronic.</span>"
		user << "<span class='nezbere_small'>If it fails to both drain any power and disrupt any electronics, it will disable itself for [round(recharge_time/600, 1)] minutes.</span>"

/obj/structure/clockwork/powered/interdiction_lens/toggle(fast_process, mob/living/user)
	..()
	if(active)
		SetLuminosity(4,2)
	else
		SetLuminosity(0)

/obj/structure/clockwork/powered/interdiction_lens/attack_hand(mob/living/user)
	if(user.canUseTopic(src, BE_CLOSE))
		if(disabled)
			user << "<span class='warning'>As you place your hand on the gemstone, cold tendrils of black matter crawl up your arm. You quickly pull back.</span>"
			return 0
		if(!total_accessable_power() >= disrupt_cost)
			user << "<span class='warning'>[src] needs more power to function!</span>"
			return 0
		toggle(0, user)

/obj/structure/clockwork/powered/interdiction_lens/process()
	if(recharging > world.time)
		return
	if(disabled)
		visible_message("<span class='warning'>The writhing tendrils return to the gemstone, which begins to glow with power!</span>")
		flick("[initial(icon_state)]_recharged", src)
		disabled = FALSE
		toggle(0)
	else
		var/successfulprocess = FALSE
		var/power_drained = 0
		var/list/atoms_to_test = list()
		for(var/atom/movable/M in urange(interdiction_range, src))
			atoms_to_test |= M
		for(var/M in atoms_to_test)
			if(istype(M, /obj/machinery/power/apc))
				var/obj/machinery/power/apc/A = M
				if(A.cell && A.cell.charge)
					successfulprocess = TRUE
					playsound(A, "sparks", 50, 1)
					flick("apc-spark", A)
					power_drained += min(A.cell.charge, 100)
					A.cell.charge = max(0, A.cell.charge - 100)
					if(!A.cell.charge && !A.shorted)
						A.shorted = 1
						A.visible_message("<span class='warning'>The [A.name]'s screen blurs with static.</span>")
					A.update()
					A.update_icon()
			else if(istype(M, /obj/machinery/power/smes))
				var/obj/machinery/power/smes/S = M
				if(S.charge)
					successfulprocess = TRUE
					power_drained += min(S.charge, 500)
					S.charge = max(0, S.charge - 50000) //SMES units contain too much power and could run an interdiction lens basically forever, or provide power forever
					if(!S.charge && !S.panel_open)
						S.panel_open = TRUE
						S.icon_state = "[initial(S.icon_state)]-o"
						var/datum/effect_system/spark_spread/spks = new(get_turf(S))
						spks.set_up(10, 0, get_turf(S))
						spks.start()
						S.visible_message("<span class='warning'>[S]'s panel flies open with a flurry of sparks.</span>")
					S.update_icon()
			else if(isrobot(M))
				var/mob/living/silicon/robot/R = M
				if(!is_servant_of_ratvar(R) && R.cell && R.cell.charge)
					successfulprocess = TRUE
					power_drained += min(R.cell.charge, 200)
					R.cell.charge = max(0, R.cell.charge - 200)
					R << "<span class='warning'>ERROR: Power loss detected!</span>"
					var/datum/effect_system/spark_spread/spks = new(get_turf(R))
					spks.set_up(3, 0, get_turf(R))
					spks.start()
		if(!return_power(power_drained) || power_drained < 50) //failed to return power drained or too little power to return
			successfulprocess = FALSE
		if(try_use_power(disrupt_cost) && total_accessable_power() >= disrupt_cost) //if we can disable at least one object
			playsound(src, 'sound/items/PSHOOM.ogg', 50, 1, interdiction_range-7, 1)
			for(var/M in atoms_to_test)
				if(ismob(M))
					flash_color(M, flash_color="#EE54DE", flash_time=5)
				else if(istype(M, /obj/machinery/light)) //cosmetic light flickering
					var/obj/machinery/light/L = M
					if(L.on)
						playsound(L, 'sound/effects/light_flicker.ogg', 50, 1)
						L.flicker(3)
				if(istype(M, /obj/machinery/camera))
					var/obj/machinery/camera/C = M
					if(C.isEmpProof() || !C.status)
						continue
					successfulprocess = TRUE
					if(C.emped)
						continue
					if(!try_use_power(disrupt_cost))
						break
					C.emp_act(1)
				else if(istype(M, /obj/item/device/radio))
					var/obj/item/device/radio/O = M
					successfulprocess = TRUE<commit_msg>Interdiction Lenses no longer cause color flash<commit_after>////////////////////////
// CLOCKWORK MACHINES //
////////////////////////
//not-actually-machines

/obj/structure/clockwork/powered
	var/obj/machinery/power/apc/target_apc
	var/active = FALSE
	var/needs_power = TRUE
	var/active_icon = null //icon_state while process() is being called
	var/inactive_icon = null //icon_state while process() isn't being called

/obj/structure/clockwork/powered/examine(mob/user)
	..()
	if(is_servant_of_ratvar(user) || isobserver(user))
		var/powered = total_accessable_power()
		user << "<span class='[powered ? "brass":"alloy"]'>It has access to [powered == INFINITY ? "INFINITY":"[powered]"]W of power.</span>"

/obj/structure/clockwork/powered/Destroy()
	SSfastprocess.processing -= src
	SSobj.processing -= src
	return ..()

/obj/structure/clockwork/powered/process()
	var/powered = total_accessable_power()
	return powered == PROCESS_KILL ? 25 : powered //make sure we don't accidentally return the arbitrary PROCESS_KILL define

/obj/structure/clockwork/powered/proc/toggle(fast_process, mob/living/user)
	if(user)
		if(!is_servant_of_ratvar(user))
			return 0
		user.visible_message("<span class='notice'>[user] [active ? "dis" : "en"]ables [src].</span>", "<span class='brass'>You [active ? "dis" : "en"]able [src].</span>")
	active = !active
	if(active)
		icon_state = active_icon
		if(fast_process)
			SSfastprocess.processing |= src
		else
			SSobj.processing |= src
	else
		icon_state = inactive_icon
		SSfastprocess.processing -= src
		SSobj.processing -= src


/obj/structure/clockwork/powered/proc/total_accessable_power() //how much power we have and can use
	if(!needs_power || ratvar_awakens)
		return INFINITY //oh yeah we've got power why'd you ask

	var/power = 0
	power += accessable_apc_power()
	power += accessable_sigil_power()
	return power

/obj/structure/clockwork/powered/proc/accessable_apc_power()
	var/power = 0
	var/area/A = get_area(src)
	var/area/targetAPCA
	for(var/obj/machinery/power/apc/APC in apcs_list)
		var/area/APCA = get_area(APC)
		if(APCA == A)
			target_apc = APC
	if(target_apc)
		targetAPCA = get_area(target_apc)
		if(targetAPCA != A)
			target_apc = null
		else if(target_apc.cell)
			var/apccharge = target_apc.cell.charge
			if(apccharge >= 50)
				power += apccharge
	return power

/obj/structure/clockwork/powered/proc/accessable_sigil_power()
	var/power = 0
	for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
		power += T.power_charge
	return power


/obj/structure/clockwork/powered/proc/try_use_power(amount) //try to use an amount of power
	if(!needs_power || ratvar_awakens)
		return 1
	if(amount <= 0)
		return 0
	var/power = total_accessable_power()
	if(!power || power < amount)
		return 0
	return use_power(amount)

/obj/structure/clockwork/powered/proc/use_power(amount) //we've made sure we had power, so now we use it
	var/sigilpower = accessable_sigil_power()
	var/list/sigils_in_range = list()
	for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
		sigils_in_range |= T
	while(sigilpower && amount >= 50)
		for(var/S in sigils_in_range)
			var/obj/effect/clockwork/sigil/transmission/T = S
			if(amount >= 50 && T.modify_charge(50))
				sigilpower -= 50
				amount -= 50
	var/apcpower = accessable_apc_power()
	while(apcpower >= 50 && amount >= 50)
		if(target_apc.cell.use(50))
			apcpower -= 50
			amount -= 50
			target_apc.update()
			target_apc.update_icon()
		else
			apcpower = 0
	if(amount)
		return 0
	else
		return 1

/obj/structure/clockwork/powered/proc/return_power(amount) //returns a given amount of power to all nearby sigils
	if(amount <= 0)
		return 0
	var/list/sigils_in_range = list()
	for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
		sigils_in_range |= T
	if(!sigils_in_range.len)
		return 0
	while(amount >= 50)
		for(var/S in sigils_in_range)
			var/obj/effect/clockwork/sigil/transmission/T = S
			if(amount >= 50 && T.modify_charge(-50))
				amount -= 50
	return 1


/obj/structure/clockwork/powered/mending_motor //Mending motor: A prism that consumes replicant alloy to repair nearby mechanical servants at a quick rate.
	name = "mending motor"
	desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
	clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
	icon_state = "mending_motor_inactive"
	active_icon = "mending_motor"
	inactive_icon = "mending_motor_inactive"
	construction_value = 20
	max_health = 150
	health = 150
	break_message = "<span class='warning'>The prism collapses with a heavy thud!</span>"
	debris = list(/obj/item/clockwork/alloy_shards, /obj/item/clockwork/component/vanguard_cogwheel)
	var/stored_alloy = 0 //250W = 1 alloy
	var/max_alloy = 50000
	var/mob_cost = 200
	var/structure_cost = 250
	var/cyborg_cost = 300

/obj/structure/clockwork/powered/mending_motor/prefilled
	stored_alloy = 5000 //starts with 20 alloy

/obj/structure/clockwork/powered/mending_motor/total_accessable_power()
	. = ..()
	if(. != INFINITY)
		. += accessable_alloy_power()

/obj/structure/clockwork/powered/mending_motor/proc/accessable_alloy_power()
	return stored_alloy

/obj/structure/clockwork/powered/mending_motor/use_power(amount)
	var/alloypower = accessable_alloy_power()
	while(alloypower >= 50 && amount >= 50)
		stored_alloy -= 50
		alloypower -= 50
		amount -= 50
	return ..()

/obj/structure/clockwork/powered/mending_motor/examine(mob/user)
	..()
	if(is_servant_of_ratvar(user) || isobserver(user))
		user << "<span class='alloy'>It has [stored_alloy*0.004]/[max_alloy*0.004] units of replicant alloy, which is equivalent to [stored_alloy]W/[max_alloy]W of power.</span>"
		user << "<span class='inathneq_small'>It requires [mob_cost]W to heal clockwork mobs, [structure_cost]W for clockwork structures, and [cyborg_cost]W for cyborgs.</span>"

/obj/structure/clockwork/powered/mending_motor/process()
	if(!..())
		visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
		toggle()
		return
	for(var/atom/movable/M in range(5, src))
		if(istype(M, /mob/living/simple_animal/hostile/clockwork/marauder))
			var/mob/living/simple_animal/hostile/clockwork/marauder/E = M
			if((E.health == E.maxHealth && !E.fatigue) || E.stat)
				continue
			if(!try_use_power(mob_cost))
				break
			E.adjustBruteLoss(-E.maxHealth) //Instant because marauders don't usually take health damage
			E.fatigue = max(0, E.fatigue - 15)
		else if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
			var/mob/living/simple_animal/hostile/clockwork/W = M
			if(W.health == W.maxHealth || W.stat)
				continue
			if(!try_use_power(mob_cost))
				break
			W.adjustBruteLoss(-15)
		else if(istype(M, /obj/structure/clockwork))
			var/obj/structure/clockwork/C = M
			if(C.health == C.max_health)
				continue
			if(!try_use_power(structure_cost))
				break
			C.health = min(C.health + 15, C.max_health)
		else if(issilicon(M))
			var/mob/living/silicon/S = M
			if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
				continue
			if(!try_use_power(cyborg_cost))
				break
			S.adjustBruteLoss(-15)
			S.adjustFireLoss(-15)
	return 1

/obj/structure/clockwork/powered/mending_motor/attack_hand(mob/living/user)
	if(user.canUseTopic(src, BE_CLOSE))
		if(!total_accessable_power() >= 300)
			user << "<span class='warning'>[src] needs more power or replicant alloy to function!</span>"
			return 0
		toggle(0, user)

/obj/structure/clockwork/powered/mending_motor/attackby(obj/item/I, mob/user, params)
	if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user))
		if(stored_alloy + 2500 > max_alloy)
			user << "<span class='warning'>[src] is too full to accept any more alloy!</span>"
			return 0
		user.whisper("Genafzhgr vagb jngre.")
		user.visible_message("<span class='notice'>[user] liquifies [I] and pours it onto [src].</span>", \
		"<span class='notice'>You liquify [src] and pour it onto [src], transferring the alloy into its reserves.</span>")
		stored_alloy = stored_alloy + 2500
		user.drop_item()
		qdel(I)
		return 1
	else
		return ..()



/obj/structure/clockwork/powered/mania_motor //Mania motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs.
	name = "<NAME>"
	desc = "A pair of antenna with what appear to be sockets around the base. It reminds you of an antlion."
	clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing hallucinations and brain damage as long as it remains powered."
	icon_state = "mania_motor_inactive"
	active_icon = "mania_motor"
	inactive_icon = "mania_motor_inactive"
	construction_value = 20
	max_health = 80
	health = 80
	break_message = "<span class='warning'>The antenna break off, leaving a pile of shards!</span>"
	debris = list(/obj/item/clockwork/alloy_shards, /obj/item/clockwork/component/guvax_capacitor/antennae)
	var/mania_cost = 150
	var/convert_attempt_cost = 150
	var/convert_cost = 300

	var/mania_messages = list("\"Tb ahgf.\"", "\"Gnxr n penpx ng penml.\"", "\"Znxr n ovq sbe vafnavgl.\"", "\"Trg xbbxl.\"", "\"Zbir gbjneqf znavn.\"", "\"Orpbzr orjvyqrerq.\"", "\"Jnk jvyq.\"", \
	"\"Tb ebhaq gur oraq.\"", "\"Ynaq va yhanpl.\"", "\"Gel qrzragvn.\"", "\"Fgevir gb trg n fperj ybbfr.\"")
	var/compel_messages = list("\"Pbzr pybfre.\"", "\"Nccebnpu gur genafzvggre.\"", "\"Gbhpu gur nagraanr.\"", "\"V nyjnlf unir gb qrny jvgu vqvbgf. Zbir gbjneqf gur znavn zbgbe.\"", \
	"\"Nqinapr sbejneq naq cynpr lbhe urnq orgjrra gur nagraanr - gung'f nyy vg'f tbbq sbe.\"", "\"Vs lbh jrer fznegre, lbh'q or bire urer nyernql.\"", "\"Zbir SBEJNEQ, lbh sbby.\"")
	var/convert_messages = list("\"Lbh jba'g qb. Tb gb fyrrc juvyr V gryy gurfr avgjvgf ubj gb pbaireg lbh.\"", "\"Lbh ner vafhssvpvrag. V zhfg vafgehpg gurfr vqvbgf va gur neg bs pbairefvba.\"", \
	"\"Bu, bs pbhefr, fbzrbar jr pna'g pbaireg. Gurfr freinagf ner sbbyf.\"", "\"Ubj uneq vf vg gb hfr n Fvtvy, naljnl? Nyy vg gnxrf vf qenttvat fbzrbar bagb vg.\"", \
	"\"Ubj qb gurl snvy gb hfr n Fvtvy bs Npprffvba, naljnl?\"", "\"Jul vf vg gung nyy freinagf ner guvf varcg?\"", "\"Vg'f abg yvxryl lbh'yy or fghpx urer ybat.\"")


/obj/structure/clockwork/powered/mania_motor/examine(mob/user)
	..()
	if(is_servant_of_ratvar(user) || isobserver(user))
		user << "<span class='sevtug_small'>It requires [mania_cost]W to run, and [convert_attempt_cost + convert_cost]W to convert humans adjecent to it.</span>"

/obj/structure/clockwork/powered/mania_motor/process()
	var/turf/T = get_turf(src)
	if(!..())
		visible_message("<span class='warning'>[src] hums loudly, then the sockets at its base fall dark!</span>")
		playsound(T, 'sound/effects/screech.ogg', 40, 1)
		toggle(0)
		return
	if(try_use_power(mania_cost))
		var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
		for(var/mob/living/carbon/human/H in range(10, src))
			if(!is_servant_of_ratvar(H) && !H.null_rod_check())
				var/distance = get_dist(T, get_turf(H))
				var/falloff_distance = (110) - distance * 10
				var/sound_distance = falloff_distance * 0.4
				var/targetbrainloss = H.getBrainLoss()
				var/targethallu = H.hallucination
				var/targetdruggy = H.druggy
				if(distance >= 4 && prob(falloff_distance))
					H << "<span class='sevtug_small'>[pick(mania_messages)]</span>"
				H.playsound_local(T, hum, sound_distance, 1)
				switch(distance)
					if(2 to 3)
						if(prob(falloff_distance))
							if(prob(falloff_distance))
								H << "<span class='sevtug_small'>[pick(mania_messages)]</span>"
							else
								H << "<span class='sevtug'>[pick(compel_messages)]</span>"
						if(targetbrainloss <= 70)
							H.adjustBrainLoss(70 - targetbrainloss) //got too close had brain eaten
						if(targetdruggy <= 150)
							H.adjust_drugginess(10)
						if(targethallu <= 150)
							H.hallucination += 10
					if(4 to 5)
						if(targetbrainloss <= 50)
							H.adjustBrainLoss(5)
						if(targetdruggy <= 120)
							H.adjust_drugginess(10)
						if(targethallu <= 120)
							H.hallucination += 10
					if(6 to 7)
						if(targetbrainloss <= 30)
							H.adjustBrainLoss(2)
						if(prob(falloff_distance) && targetdruggy <= 90)
							H.adjust_drugginess(10)
						else if(targethallu <= 90)
							H.hallucination += 10
					if(8 to 9)
						if(H.getBrainLoss() <= 10)
							H.adjustBrainLoss(1)
						if(prob(falloff_distance) && targetdruggy <= 60)
							H.adjust_drugginess(5)
						else if(targethallu <= 60)
							H.hallucination += 5
					if(10 to INFINITY)
						if(prob(falloff_distance) && targetdruggy <= 30)
							H.adjust_drugginess(5)
						else if(targethallu <= 30)
							H.hallucination += 5
					else //if it's a distance of 1 or they're on top of it(how'd they get on top of it???)
						if(try_use_power(convert_attempt_cost))
							if(is_eligible_servant(H) && try_use_power(convert_cost))
								H << "<span class='sevtug'>\"Lbh ner zvar-naq-uvf, abj.\"</span>"
								add_servant_of_ratvar(H)
							else if(!H.stat)
								if(targetbrainloss >= H.maxHealth)
									H.Paralyse(5)
									H << "<span class='sevtug'>[pick(convert_messages)]</span>"
								else
									H.adjustBrainLoss(100)
									H.visible_message("<span class='warning'>[H] reaches out and touches [src].</span>", "<span class='sevtug'>You touch [src] involuntarily.</span>")
						else
							visible_message("<span class='warning'>[src]'s antennae fizzle quietly.</span>")
							playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)

			if(is_servant_of_ratvar(H) && (H.getBrainLoss() || H.hallucination || H.druggy)) //not an else so that newly converted servants are healed of the damage it inflicts
				H.adjustBrainLoss(-H.getBrainLoss()) //heals servants of braindamage, hallucination, and druggy
				H.hallucination = 0
				H.adjust_drugginess(-H.druggy)
	else
		visible_message("<span class='warning'>[src] hums loudly, then the sockets at its base fall dark!</span>")
		playsound(src, 'sound/effects/screech.ogg', 40, 1)
		toggle(0)

/obj/structure/clockwork/powered/mania_motor/attack_hand(mob/living/user)
	if(user.canUseTopic(src, BE_CLOSE))
		if(!total_accessable_power() >= mania_cost)
			user << "<span class='warning'>[src] needs more power to function!</span>"
			return 0
		toggle(0, user)



/obj/structure/clockwork/powered/interdiction_lens //Interdiction lens: A powerful artifact that constantly disrupts electronics but, if it fails to find something to disrupt, turns off.
	name = "<NAME>"
	desc = "An ominous, double-pronged brass totem. There's a strange gemstone clasped between the pincers."
	clockwork_desc = "A powerful totem that constantly disrupts nearby electronics and funnels power into nearby Sigils of Transmission."
	icon_state = "interdiction_lens"
	construction_value = 25
	active_icon = "interdiction_lens_active"
	inactive_icon = "interdiction_lens"
	break_message = "<span class='warning'>The lens flares a blinding violet before shattering!</span>"
	break_sound = 'sound/effects/Glassbr3.ogg'
	var/recharging = 0 //world.time when the lens was last used
	var/recharge_time = 1200 //if it drains no power and affects no objects, it turns off for two minutes
	var/disabled = FALSE //if it's actually usable
	var/interdiction_range = 14 //how large an area it drains and disables in
	var/disrupt_cost = 100 //how much power to use when disabling an object

/obj/structure/clockwork/powered/interdiction_lens/examine(mob/user)
	..()
	user << "<span class='[recharging > world.time ? "nezbere_small":"brass"]'>Its gemstone [recharging > world.time ? "has been breached by writhing tendrils of blackness that cover the totem" \
	: "vibrates in place and thrums with power"].</span>"
	if(is_servant_of_ratvar(user) || isobserver(user))
		user << "<span class='nezbere_small'>It requires [disrupt_cost]W of power for each nearby disruptable electronic.</span>"
		user << "<span class='nezbere_small'>If it fails to both drain any power and disrupt any electronics, it will disable itself for [round(recharge_time/600, 1)] minutes.</span>"

/obj/structure/clockwork/powered/interdiction_lens/toggle(fast_process, mob/living/user)
	..()
	if(active)
		SetLuminosity(4,2)
	else
		SetLuminosity(0)

/obj/structure/clockwork/powered/interdiction_lens/attack_hand(mob/living/user)
	if(user.canUseTopic(src, BE_CLOSE))
		if(disabled)
			user << "<span class='warning'>As you place your hand on the gemstone, cold tendrils of black matter crawl up your arm. You quickly pull back.</span>"
			return 0
		if(!total_accessable_power() >= disrupt_cost)
			user << "<span class='warning'>[src] needs more power to function!</span>"
			return 0
		toggle(0, user)

/obj/structure/clockwork/powered/interdiction_lens/process()
	if(recharging > world.time)
		return
	if(disabled)
		visible_message("<span class='warning'>The writhing tendrils return to the gemstone, which begins to glow with power!</span>")
		flick("[initial(icon_state)]_recharged", src)
		disabled = FALSE
		toggle(0)
	else
		var/successfulprocess = FALSE
		var/power_drained = 0
		var/list/atoms_to_test = list()
		for(var/atom/movable/M in urange(interdiction_range, src))
			atoms_to_test |= M
		for(var/M in atoms_to_test)
			if(istype(M, /obj/machinery/power/apc))
				var/obj/machinery/power/apc/A = M
				if(A.cell && A.cell.charge)
					successfulprocess = TRUE
					playsound(A, "sparks", 50, 1)
					flick("apc-spark", A)
					power_drained += min(A.cell.charge, 100)
					A.cell.charge = max(0, A.cell.charge - 100)
					if(!A.cell.charge && !A.shorted)
						A.shorted = 1
						A.visible_message("<span class='warning'>The [A.name]'s screen blurs with static.</span>")
					A.update()
					A.update_icon()
			else if(istype(M, /obj/machinery/power/smes))
				var/obj/machinery/power/smes/S = M
				if(S.charge)
					successfulprocess = TRUE
					power_drained += min(S.charge, 500)
					S.charge = max(0, S.charge - 50000) //SMES units contain too much power and could run an interdiction lens basically forever, or provide power forever
					if(!S.charge && !S.panel_open)
						S.panel_open = TRUE
						S.icon_state = "[initial(S.icon_state)]-o"
						var/datum/effect_system/spark_spread/spks = new(get_turf(S))
						spks.set_up(10, 0, get_turf(S))
						spks.start()
						S.visible_message("<span class='warning'>[S]'s panel flies open with a flurry of sparks.</span>")
					S.update_icon()
			else if(isrobot(M))
				var/mob/living/silicon/robot/R = M
				if(!is_servant_of_ratvar(R) && R.cell && R.cell.charge)
					successfulprocess = TRUE
					power_drained += min(R.cell.charge, 200)
					R.cell.charge = max(0, R.cell.charge - 200)
					R << "<span class='warning'>ERROR: Power loss detected!</span>"
					var/datum/effect_system/spark_spread/spks = new(get_turf(R))
					spks.set_up(3, 0, get_turf(R))
					spks.start()
		if(!return_power(power_drained) || power_drained < 50) //failed to return power drained or too little power to return
			successfulprocess = FALSE
		if(try_use_power(disrupt_cost) && total_accessable_power() >= disrupt_cost) //if we can disable at least one object
			playsound(src, 'sound/items/PSHOOM.ogg', 50, 1, interdiction_range-7, 1)
			for(var/M in atoms_to_test)
				if(istype(M, /obj/machinery/light)) //cosmetic light flickering
					var/obj/machinery/light/L = M
					if(L.on)
						playsound(L, 'sound/effects/light_flicker.ogg', 50, 1)
						L.flicker(3)
				else if(istype(M, /obj/machinery/camera))
					var/obj/machinery/camera/C = M
					if(C.isEmpProof() || !C.status)
						continue
					successfulprocess = TRUE
					if(C.emped)
						continue
					if(!try_use_power(disrupt_cost))
						break
					C.emp_act(1)
				else if(istype(M, /obj/item/device/radio))
					var/obj/item/device/radio/O = M
					successfulprocess = TRUE
{'fraction_non_alphanumeric': 0.13571715750326666, 'fraction_numerical': 0.015453814453713941, 'mean_word_length': 3.9156373517786562, 'pattern_counts': {'":': 6, '<': 249, '<?xml version=': 0, '>': 179, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7242096', 'n_tokens_mistral': 16757, 'n_tokens_neox': 14318, 'n_words': 3293}