diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 1e3c10d57c..3cc6734482 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -538,7 +538,7 @@ so as to remain in compliance with the most up-to-date laws." if(NOTIFY_JUMP) var/turf/T = get_turf(target) if(T && isturf(T)) - G.loc = T + G.forceMove(T) if(NOTIFY_ORBIT) G.ManualFollow(target) diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index b0ab260d63..903f3c0790 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -92,7 +92,7 @@ /obj/item/tk_grab/dropped(mob/user) if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item if(focus.Adjacent(loc)) - focus.loc = loc + focus.forceMove(loc) . = ..() //stops TK grabs being equipped anywhere but into hands diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm index 14c92f3263..f66fc5a3b2 100644 --- a/code/datums/antagonists/devil.dm +++ b/code/datums/antagonists/devil.dm @@ -205,7 +205,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", /datum/antagonist/devil/proc/regress_blood_lizard() var/mob/living/carbon/true_devil/D = owner.current to_chat(D, "Your powers weaken, have more contracts be signed to regain power.") - D.oldform.loc = D.loc + D.oldform.forceMove(D.drop_location()) owner.transfer_to(D.oldform) give_appropriate_spells() qdel(D) @@ -236,7 +236,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", sleep(50) var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc) A.faction |= "hell" - owner.current.loc = A + owner.current.forceMove(A) A.oldform = owner.current owner.transfer_to(A) A.set_name() diff --git a/code/datums/diseases/parrotpossession.dm b/code/datums/diseases/parrotpossession.dm index 0df7e0f7d3..a5d87be980 100644 --- a/code/datums/diseases/parrotpossession.dm +++ b/code/datums/diseases/parrotpossession.dm @@ -22,6 +22,6 @@ /datum/disease/parrot_possession/cure() if(parrot && parrot.loc == affected_mob) - parrot.loc = affected_mob.loc + parrot.forceMove(affected_mob.drop_location()) affected_mob.visible_message("[parrot] is violently driven out of [affected_mob]!", "[parrot] bursts out of your chest!") ..() \ No newline at end of file diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index fbdb107c83..66663162ee 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -1,115 +1,115 @@ -/datum/disease/wizarditis - name = "Wizarditis" - max_stages = 4 - spread_text = "Airborne" - cure_text = "The Manly Dorf" - cures = list("manlydorf") - cure_chance = 100 - agent = "Rincewindus Vulgaris" - viable_mobtypes = list(/mob/living/carbon/human) - disease_flags = CAN_CARRY|CAN_RESIST|CURABLE - permeability_mod = 0.75 - desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition." - severity = HARMFUL - required_organs = list(/obj/item/bodypart/head) - -/* -BIRUZ BENNAR -SCYAR NILA - teleport -NEC CANTIO - dis techno -EI NATH - shocking grasp -AULIE OXIN FIERA - knock -TARCOL MINTI ZHERI - forcewall -STI KALY - blind -*/ - -/datum/disease/wizarditis/stage_act() - ..() - - switch(stage) - if(2) - if(prob(1)&&prob(50)) - affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!")) - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")].") - - - if(3) - if(prob(1)&&prob(50)) - affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!")) - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")].") - - if(4) - - if(prob(1)) - affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!")) - return - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")].") - spawn_wizard_clothes(50) - if(prob(1)&&prob(1)) - teleport() - return - - - -/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0) - if(ishuman(affected_mob)) - var/mob/living/carbon/human/H = affected_mob - if(prob(chance)) - if(!istype(H.head, /obj/item/clothing/head/wizard)) - if(!H.dropItemToGround(H.head)) - qdel(H.head) - H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head) - return - if(prob(chance)) - if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe)) - if(!H.dropItemToGround(H.wear_suit)) - qdel(H.wear_suit) - H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit) - return - if(prob(chance)) - if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic)) - if(!H.dropItemToGround(H.shoes)) - qdel(H.shoes) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), slot_shoes) - return - else - var/mob/living/carbon/H = affected_mob - if(prob(chance)) - var/obj/item/staff/S = new(H) - if(!H.put_in_hands(S)) - qdel(S) - - -/datum/disease/wizarditis/proc/teleport() - var/list/theareas = get_areas_in_range(80, affected_mob) - for(var/area/space/S in theareas) - theareas -= S - - if(!theareas||!theareas.len) - return - - var/area/thearea = pick(theareas) - - var/list/L = list() - for(var/turf/T in get_area_turfs(thearea.type)) - if(T.z != affected_mob.z) continue - if(T.name == "space") continue - if(!T.density) - var/clear = 1 - for(var/obj/O in T) - if(O.density) - clear = 0 - break - if(clear) - L+=T - - if(!L) - return - - affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!") - affected_mob.loc = pick(L) - - return +/datum/disease/wizarditis + name = "Wizarditis" + max_stages = 4 + spread_text = "Airborne" + cure_text = "The Manly Dorf" + cures = list("manlydorf") + cure_chance = 100 + agent = "Rincewindus Vulgaris" + viable_mobtypes = list(/mob/living/carbon/human) + disease_flags = CAN_CARRY|CAN_RESIST|CURABLE + permeability_mod = 0.75 + desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition." + severity = HARMFUL + required_organs = list(/obj/item/bodypart/head) + +/* +BIRUZ BENNAR +SCYAR NILA - teleport +NEC CANTIO - dis techno +EI NATH - shocking grasp +AULIE OXIN FIERA - knock +TARCOL MINTI ZHERI - forcewall +STI KALY - blind +*/ + +/datum/disease/wizarditis/stage_act() + ..() + + switch(stage) + if(2) + if(prob(1)&&prob(50)) + affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!")) + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")].") + + + if(3) + if(prob(1)&&prob(50)) + affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!")) + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")].") + + if(4) + + if(prob(1)) + affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!")) + return + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")].") + spawn_wizard_clothes(50) + if(prob(1)&&prob(1)) + teleport() + return + + + +/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0) + if(ishuman(affected_mob)) + var/mob/living/carbon/human/H = affected_mob + if(prob(chance)) + if(!istype(H.head, /obj/item/clothing/head/wizard)) + if(!H.dropItemToGround(H.head)) + qdel(H.head) + H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head) + return + if(prob(chance)) + if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe)) + if(!H.dropItemToGround(H.wear_suit)) + qdel(H.wear_suit) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit) + return + if(prob(chance)) + if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic)) + if(!H.dropItemToGround(H.shoes)) + qdel(H.shoes) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), slot_shoes) + return + else + var/mob/living/carbon/H = affected_mob + if(prob(chance)) + var/obj/item/staff/S = new(H) + if(!H.put_in_hands(S)) + qdel(S) + + +/datum/disease/wizarditis/proc/teleport() + var/list/theareas = get_areas_in_range(80, affected_mob) + for(var/area/space/S in theareas) + theareas -= S + + if(!theareas||!theareas.len) + return + + var/area/thearea = pick(theareas) + + var/list/L = list() + for(var/turf/T in get_area_turfs(thearea.type)) + if(T.z != affected_mob.z) continue + if(T.name == "space") continue + if(!T.density) + var/clear = 1 + for(var/obj/O in T) + if(O.density) + clear = 0 + break + if(clear) + L+=T + + if(!L) + return + + affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!") + affected_mob.forceMove(pick(L)) + + return diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 95267cf927..ae938f18ce 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -1,260 +1,260 @@ -#define MAXIMUM_EMP_WIRES 3 - -/proc/is_wire_tool(obj/item/I) - if(istype(I, /obj/item/device/multitool)) - return TRUE - if(istype(I, /obj/item/wirecutters)) - return TRUE - if(istype(I, /obj/item/device/assembly)) - var/obj/item/device/assembly/A = I - if(A.attachable) - return TRUE - return - -/atom - var/datum/wires/wires = null - -/datum/wires - var/atom/holder = null // The holder (atom that contains these wires). - var/holder_type = null // The holder's typepath (used to make wire colors common to all holders). - var/proper_name = "Unknown" // The display name for the wire set shown in station blueprints. Not used if randomize is true or it's an item NT wouldn't know about (Explosives/Nuke) - - var/list/wires = list() // List of wires. - var/list/cut_wires = list() // List of wires that have been cut. - var/list/colors = list() // Dictionary of colors to wire. - var/list/assemblies = list() // List of attached assemblies. - var/randomize = 0 // If every instance of these wires should be random. - // Prevents wires from showing up in station blueprints - -/datum/wires/New(atom/holder) - ..() - if(!istype(holder, holder_type)) - CRASH("Wire holder is not of the expected type!") - return - - src.holder = holder - if(randomize) - randomize() - else - if(!GLOB.wire_color_directory[holder_type]) - randomize() - GLOB.wire_color_directory[holder_type] = colors - GLOB.wire_name_directory[holder_type] = proper_name - else - colors = GLOB.wire_color_directory[holder_type] - -/datum/wires/Destroy() - holder = null - assemblies = list() - return ..() - -/datum/wires/proc/add_duds(duds) - while(duds) - var/dud = WIRE_DUD_PREFIX + "[--duds]" - if(dud in wires) - continue - wires += dud - -/datum/wires/proc/randomize() - var/static/list/possible_colors = list( - "blue", - "brown", - "crimson", - "cyan", - "gold", - "grey", - "green", - "magenta", - "orange", - "pink", - "purple", - "red", - "silver", - "violet", - "white", - "yellow" - ) - - var/list/my_possible_colors = possible_colors.Copy() - - for(var/wire in shuffle(wires)) - colors[pick_n_take(my_possible_colors)] = wire - -/datum/wires/proc/shuffle_wires() - colors.Cut() - randomize() - -/datum/wires/proc/repair() - cut_wires.Cut() - -/datum/wires/proc/get_wire(color) - return colors[color] - -/datum/wires/proc/get_attached(color) - if(assemblies[color]) - return assemblies[color] - return null - -/datum/wires/proc/is_attached(color) - if(assemblies[color]) - return TRUE - -/datum/wires/proc/is_cut(wire) - return (wire in cut_wires) - -/datum/wires/proc/is_color_cut(color) - return is_cut(get_wire(color)) - -/datum/wires/proc/is_all_cut() - if(cut_wires.len == wires.len) - return TRUE - -/datum/wires/proc/cut(wire) - if(is_cut(wire)) - cut_wires -= wire - on_cut(wire, mend = TRUE) - else - cut_wires += wire - on_cut(wire, mend = FALSE) - -/datum/wires/proc/cut_color(color) - cut(get_wire(color)) - -/datum/wires/proc/cut_random() - cut(wires[rand(1, wires.len)]) - -/datum/wires/proc/cut_all() - for(var/wire in wires) - cut(wire) - +#define MAXIMUM_EMP_WIRES 3 + +/proc/is_wire_tool(obj/item/I) + if(istype(I, /obj/item/device/multitool)) + return TRUE + if(istype(I, /obj/item/wirecutters)) + return TRUE + if(istype(I, /obj/item/device/assembly)) + var/obj/item/device/assembly/A = I + if(A.attachable) + return TRUE + return + +/atom + var/datum/wires/wires = null + +/datum/wires + var/atom/holder = null // The holder (atom that contains these wires). + var/holder_type = null // The holder's typepath (used to make wire colors common to all holders). + var/proper_name = "Unknown" // The display name for the wire set shown in station blueprints. Not used if randomize is true or it's an item NT wouldn't know about (Explosives/Nuke) + + var/list/wires = list() // List of wires. + var/list/cut_wires = list() // List of wires that have been cut. + var/list/colors = list() // Dictionary of colors to wire. + var/list/assemblies = list() // List of attached assemblies. + var/randomize = 0 // If every instance of these wires should be random. + // Prevents wires from showing up in station blueprints + +/datum/wires/New(atom/holder) + ..() + if(!istype(holder, holder_type)) + CRASH("Wire holder is not of the expected type!") + return + + src.holder = holder + if(randomize) + randomize() + else + if(!GLOB.wire_color_directory[holder_type]) + randomize() + GLOB.wire_color_directory[holder_type] = colors + GLOB.wire_name_directory[holder_type] = proper_name + else + colors = GLOB.wire_color_directory[holder_type] + +/datum/wires/Destroy() + holder = null + assemblies = list() + return ..() + +/datum/wires/proc/add_duds(duds) + while(duds) + var/dud = WIRE_DUD_PREFIX + "[--duds]" + if(dud in wires) + continue + wires += dud + +/datum/wires/proc/randomize() + var/static/list/possible_colors = list( + "blue", + "brown", + "crimson", + "cyan", + "gold", + "grey", + "green", + "magenta", + "orange", + "pink", + "purple", + "red", + "silver", + "violet", + "white", + "yellow" + ) + + var/list/my_possible_colors = possible_colors.Copy() + + for(var/wire in shuffle(wires)) + colors[pick_n_take(my_possible_colors)] = wire + +/datum/wires/proc/shuffle_wires() + colors.Cut() + randomize() + +/datum/wires/proc/repair() + cut_wires.Cut() + +/datum/wires/proc/get_wire(color) + return colors[color] + +/datum/wires/proc/get_attached(color) + if(assemblies[color]) + return assemblies[color] + return null + +/datum/wires/proc/is_attached(color) + if(assemblies[color]) + return TRUE + +/datum/wires/proc/is_cut(wire) + return (wire in cut_wires) + +/datum/wires/proc/is_color_cut(color) + return is_cut(get_wire(color)) + +/datum/wires/proc/is_all_cut() + if(cut_wires.len == wires.len) + return TRUE + +/datum/wires/proc/cut(wire) + if(is_cut(wire)) + cut_wires -= wire + on_cut(wire, mend = TRUE) + else + cut_wires += wire + on_cut(wire, mend = FALSE) + +/datum/wires/proc/cut_color(color) + cut(get_wire(color)) + +/datum/wires/proc/cut_random() + cut(wires[rand(1, wires.len)]) + +/datum/wires/proc/cut_all() + for(var/wire in wires) + cut(wire) + /datum/wires/proc/pulse(wire, user) - if(is_cut(wire)) - return + if(is_cut(wire)) + return on_pulse(wire, user) - + /datum/wires/proc/pulse_color(color, mob/living/user) pulse(get_wire(color), user) - -/datum/wires/proc/pulse_assembly(obj/item/device/assembly/S) - for(var/color in assemblies) - if(S == assemblies[color]) - pulse_color(color) - return TRUE - -/datum/wires/proc/attach_assembly(color, obj/item/device/assembly/S) - if(S && istype(S) && S.attachable && !is_attached(color)) - assemblies[color] = S - S.loc = holder - S.connected = src - return S - -/datum/wires/proc/detach_assembly(color) - var/obj/item/device/assembly/S = get_attached(color) - if(S && istype(S)) - assemblies -= color - S.connected = null - S.loc = holder.loc - return S - -/datum/wires/proc/emp_pulse() - var/list/possible_wires = shuffle(wires) - var/remaining_pulses = MAXIMUM_EMP_WIRES - - for(var/wire in possible_wires) - if(prob(33)) - pulse(wire) - remaining_pulses-- - if(remaining_pulses >= 0) - break - -// Overridable Procs -/datum/wires/proc/interactable(mob/user) - return TRUE - -/datum/wires/proc/get_status() - return list() - -/datum/wires/proc/on_cut(wire, mend = FALSE) - return - + +/datum/wires/proc/pulse_assembly(obj/item/device/assembly/S) + for(var/color in assemblies) + if(S == assemblies[color]) + pulse_color(color) + return TRUE + +/datum/wires/proc/attach_assembly(color, obj/item/device/assembly/S) + if(S && istype(S) && S.attachable && !is_attached(color)) + assemblies[color] = S + S.forceMove(holder) + S.connected = src + return S + +/datum/wires/proc/detach_assembly(color) + var/obj/item/device/assembly/S = get_attached(color) + if(S && istype(S)) + assemblies -= color + S.connected = null + S.forceMove(holder.drop_location()) + return S + +/datum/wires/proc/emp_pulse() + var/list/possible_wires = shuffle(wires) + var/remaining_pulses = MAXIMUM_EMP_WIRES + + for(var/wire in possible_wires) + if(prob(33)) + pulse(wire) + remaining_pulses-- + if(remaining_pulses >= 0) + break + +// Overridable Procs +/datum/wires/proc/interactable(mob/user) + return TRUE + +/datum/wires/proc/get_status() + return list() + +/datum/wires/proc/on_cut(wire, mend = FALSE) + return + /datum/wires/proc/on_pulse(wire, user) - return -// End Overridable Procs - -/datum/wires/proc/interact(mob/user) - if(!interactable(user)) - return - ui_interact(user) - for(var/A in assemblies) - var/obj/item/I = assemblies[A] - if(istype(I) && I.on_found(user)) - return - -/datum/wires/ui_host() - return holder - -/datum/wires/ui_status(mob/user) - if(interactable(user)) - return ..() - return UI_CLOSE - + return +// End Overridable Procs + +/datum/wires/proc/interact(mob/user) + if(!interactable(user)) + return + ui_interact(user) + for(var/A in assemblies) + var/obj/item/I = assemblies[A] + if(istype(I) && I.on_found(user)) + return + +/datum/wires/ui_host() + return holder + +/datum/wires/ui_status(mob/user) + if(interactable(user)) + return ..() + return UI_CLOSE + /datum/wires/ui_interact(mob/user, ui_key = "wires", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if (!ui) - ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state) - ui.open() - -/datum/wires/ui_data(mob/user) - var/list/data = list() - var/list/payload = list() - for(var/color in colors) - payload.Add(list(list( - "color" = color, - "wire" = (IsAdminGhost(user) || (user.is_holding_item_of_type(/obj/item/device/multitool/abductor)) ? get_wire(color) : null), - "cut" = is_color_cut(color), - "attached" = is_attached(color) - ))) - data["wires"] = payload - data["status"] = get_status() - return data - -/datum/wires/ui_act(action, params) - if(..() || !interactable(usr)) - return - var/target_wire = params["wire"] - var/mob/living/L = usr - var/obj/item/I = L.get_active_held_item() - switch(action) - if("cut") - if(istype(I, /obj/item/wirecutters) || IsAdminGhost(usr)) - playsound(holder, I.usesound, 20, 1) - cut_color(target_wire) - . = TRUE - else - to_chat(L, "You need wirecutters!") - if("pulse") - if(istype(I, /obj/item/device/multitool) || IsAdminGhost(usr)) - playsound(holder, 'sound/weapons/empty.ogg', 20, 1) + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if (!ui) + ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state) + ui.open() + +/datum/wires/ui_data(mob/user) + var/list/data = list() + var/list/payload = list() + for(var/color in colors) + payload.Add(list(list( + "color" = color, + "wire" = (IsAdminGhost(user) || (user.is_holding_item_of_type(/obj/item/device/multitool/abductor)) ? get_wire(color) : null), + "cut" = is_color_cut(color), + "attached" = is_attached(color) + ))) + data["wires"] = payload + data["status"] = get_status() + return data + +/datum/wires/ui_act(action, params) + if(..() || !interactable(usr)) + return + var/target_wire = params["wire"] + var/mob/living/L = usr + var/obj/item/I = L.get_active_held_item() + switch(action) + if("cut") + if(istype(I, /obj/item/wirecutters) || IsAdminGhost(usr)) + playsound(holder, I.usesound, 20, 1) + cut_color(target_wire) + . = TRUE + else + to_chat(L, "You need wirecutters!") + if("pulse") + if(istype(I, /obj/item/device/multitool) || IsAdminGhost(usr)) + playsound(holder, 'sound/weapons/empty.ogg', 20, 1) pulse_color(target_wire, L) - . = TRUE - else - to_chat(L, "You need a multitool!") - if("attach") - if(is_attached(target_wire)) - var/obj/item/O = detach_assembly(target_wire) - if(O) - L.put_in_hands(O) - . = TRUE - else - if(istype(I, /obj/item/device/assembly)) - var/obj/item/device/assembly/A = I - if(A.attachable) - if(!L.drop_item()) - return - attach_assembly(target_wire, A) - . = TRUE - else - to_chat(L, "You need an attachable assembly!") - -#undef MAXIMUM_EMP_WIRES + . = TRUE + else + to_chat(L, "You need a multitool!") + if("attach") + if(is_attached(target_wire)) + var/obj/item/O = detach_assembly(target_wire) + if(O) + L.put_in_hands(O) + . = TRUE + else + if(istype(I, /obj/item/device/assembly)) + var/obj/item/device/assembly/A = I + if(A.attachable) + if(!L.drop_item()) + return + attach_assembly(target_wire, A) + . = TRUE + else + to_chat(L, "You need an attachable assembly!") + +#undef MAXIMUM_EMP_WIRES diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 36a23b2bd1..ddb87e20f6 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(blobs_legit) //used for win-score calculations, contains only var/mob/camera/blob/B = blob.current.become_overmind(TRUE, round(blob_base_starting_points/blob_overminds.len)) B.mind.name = B.name var/turf/T = pick(GLOB.blobstart) - B.loc = T + B.forceMove(T) B.base_point_rate = blob_point_rate SSshuttle.registerHostileEnvironment(src) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 026183d951..865a58fd81 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -59,7 +59,7 @@ set name = "Jump to Core" set desc = "Move your camera to your core." if(blob_core) - src.loc = blob_core.loc + forceMove(blob_core.drop_location()) /mob/camera/blob/verb/jump_to_node() set category = "Blob" diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 8443f3d6f1..183ec88b23 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -190,7 +190,7 @@ B.density = TRUE if(T.Enter(B,src)) //NOW we can attempt to move into the tile B.density = initial(B.density) - B.loc = T + B.forceMove(T) B.update_icon() if(B.overmind && expand_reaction) B.overmind.blob_reagent_datum.expand_reaction(src, B, T, controller) diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm index 94d83e2520..e7f23bc07b 100644 --- a/code/game/gamemodes/changeling/powers/headcrab.dm +++ b/code/game/gamemodes/changeling/powers/headcrab.dm @@ -30,7 +30,7 @@ sleep(5) // So it's not killed in explosion var/mob/living/simple_animal/hostile/headcrab/crab = new(turf) for(var/obj/item/organ/I in organs) - I.loc = crab + I.forceMove(crab) crab.origin = M if(crab.origin) crab.origin.active = 1 diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm index 88bb84fc4a..2b012e5f81 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm @@ -60,9 +60,8 @@ /obj/machinery/abductor/gland_dispenser/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/organ/heart/gland)) - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - W.loc = src for(var/i=1,i<=gland_colors.len,i++) if(gland_types[i] == W.type) amounts[i]++ diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 8979fb8c78..d919d5d277 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -502,7 +502,7 @@ var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc) M.amount = 5 for(var/obj/item/I in target.component_parts) - I.loc = M.loc + I.forceMove(M.drop_location()) var/obj/effect/temp_visual/swarmer/disintegration/N = new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target)) N.pixel_x = target.pixel_x N.pixel_y = target.pixel_y @@ -511,7 +511,7 @@ if(istype(target, /obj/machinery/computer)) var/obj/machinery/computer/C = target if(C.circuit) - C.circuit.loc = M.loc + C.circuit.forceMove(M.drop_location()) qdel(target) diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index f763f742f7..5e1a97675b 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -77,7 +77,7 @@ /mob/living/simple_animal/hostile/morph/proc/eat(atom/movable/A) if(A && A.loc != src) visible_message("[src] swallows [A] whole!") - A.loc = src + A.forceMove(src) return 1 return 0 @@ -153,7 +153,7 @@ /mob/living/simple_animal/hostile/morph/proc/barf_contents() for(var/atom/movable/AM in src) - AM.loc = loc + AM.forceMove(loc) if(prob(90)) step(AM, pick(GLOB.alldirs)) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index acf55e4036..2179177fc1 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -110,7 +110,7 @@ P.info = "The nuclear authorization code is: [nuke_code]" P.name = "nuclear bomb code" var/mob/living/carbon/human/H = synd_mind.current - P.loc = H.loc + P.forceMove(H.drop_location()) H.put_in_hands_or_del(P) H.update_icons() else diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index f6c53a07f4..15cd346b2d 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -140,7 +140,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) var/mob/living/carbon/human/P = usr if(!istype(P)) return if(P.wear_suit) - P.wear_suit.loc = P.loc + P.wear_suit.forceMove(P.drop_location()) P.wear_suit.layer = initial(P.wear_suit.layer) P.wear_suit.plane = initial(P.wear_suit.plane) P.wear_suit = null @@ -149,7 +149,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) P.wear_suit.plane = ABOVE_HUD_PLANE P.update_inv_wear_suit() if(P.head) - P.head.loc = P.loc + P.head.forceMove(P.drop_location()) P.head.layer = initial(P.head.layer) P.head.plane = initial(P.head.plane) P.head = null @@ -158,7 +158,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) P.head.plane = ABOVE_HUD_PLANE P.update_inv_head() if(P.wear_mask) - P.wear_mask.loc = P.loc + P.wear_mask.forceMove(P.drop_location()) P.wear_mask.layer = initial(P.wear_mask.layer) P.wear_mask.plane = initial(P.wear_mask.plane) P.wear_mask = null @@ -167,7 +167,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) P.wear_mask.plane = ABOVE_HUD_PLANE P.update_inv_wear_mask() if(P.back) - P.back.loc = P.loc + P.back.forceMove(P.drop_location()) P.back.layer = initial(P.back.layer) P.back.plane = initial(P.back.plane) P.back = null diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index f4847e30a7..42d676c29b 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -234,11 +234,10 @@ if(!link) if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL) - user.drop_item() - I.loc = src - link = I - to_chat(user, "You attach [I] to the doll.") - update_targets() + if (user.transferItemToLoc(I,src)) + link = I + to_chat(user, "You attach [I] to the doll.") + update_targets() /obj/item/voodoo/check_eye(mob/user) if(loc != user) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index aae0261320..df57ded774 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -164,7 +164,7 @@ if(contents.len) to_chat(user, "Capture failed!: The soulstone is full! Free an existing soul to make room.") else - T.loc = src //put shade in stone + T.forceMove(src) //put shade in stone T.status_flags |= GODMODE T.canmove = 0 T.health = T.maxHealth diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index eea7afcb4b..69528b686c 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -30,7 +30,7 @@ to_chat(wizard.current, "A starting location for you could not be found, please report this bug!") return 0 for(var/datum/mind/wiz in wizards) - wiz.current.loc = pick(GLOB.wizardstart) + wiz.current.forceMove(pick(GLOB.wizardstart)) return 1 diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index 80400fee05..48eafce3c5 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -44,10 +44,10 @@ var/turf/T = loc Beacon = new /obj/item/device/radio/beacon Beacon.invisibility = INVISIBILITY_MAXIMUM - Beacon.loc = T + Beacon.forceMove(T) if(Beacon) if(Beacon.loc != loc) - Beacon.loc = loc + Beacon.forceMove(loc) updateicon() diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index b070de1b1c..054bf07f70 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -429,7 +429,7 @@ Class Procs: W.handle_item_insertion(A, 1) component_parts -= A component_parts += B - B.loc = null + B.moveToNullspace() to_chat(user, "[A.name] replaced with [B.name].") shouldplaysound = 1 //Only play the sound when parts are actually replaced! break diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index de07fc9c2d..9d446aa77c 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -43,7 +43,7 @@ say("Station funds depleted. Halting siphon.") siphoning = FALSE else - new /obj/item/stack/spacecash/c200(get_turf(src)) // will autostack + new /obj/item/stack/spacecash/c200(drop_location()) // will autostack playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1) SSshuttle.points -= 200 if(next_warning < world.time && prob(15)) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 7c1904d2fe..8a118b8d08 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -127,10 +127,10 @@ if(panel_open) if(device || board) if(device) - device.loc = get_turf(src) + device.forceMove(drop_location()) device = null if(board) - board.loc = get_turf(src) + board.forceMove(drop_location()) req_access = list() req_one_access = list() board = null diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index d7832622c5..7d3c40a0d9 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -246,7 +246,7 @@ if(disassembled) if(!assembly) assembly = new() - assembly.loc = src.loc + assembly.forceMove(drop_location()) assembly.state = 1 assembly.setDir(dir) assembly = null diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 340277b441..1e6fe4c532 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -1,145 +1,145 @@ -/obj/item/wallframe/camera - name = "camera assembly" - desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." - icon = 'icons/obj/monitors.dmi' - icon_state = "cameracase" - materials = list(MAT_METAL=400, MAT_GLASS=250) - result_path = /obj/structure/camera_assembly - - -/obj/structure/camera_assembly - name = "camera assembly" - desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." - icon = 'icons/obj/monitors.dmi' - icon_state = "camera1" - max_integrity = 150 - // Motion, EMP-Proof, X-Ray - var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer)) - var/list/upgrades - var/state = 1 - - /* - 1 = Wrenched in place - 2 = Welded in place - 3 = Wires attached to it (you can now attach/dettach upgrades) - 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades) - */ - -/obj/structure/camera_assembly/Initialize(mapload, ndir, building) - . = ..() - if(building) - setDir(ndir) - upgrades = list() - -/obj/structure/camera_assembly/Destroy() - QDEL_LIST(upgrades) - return ..() - -/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params) - switch(state) - if(1) - // State 1 - if(istype(W, /obj/item/weldingtool)) - if(weld(W, user)) - to_chat(user, "You weld the assembly securely into place.") +/obj/item/wallframe/camera + name = "camera assembly" + desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." + icon = 'icons/obj/monitors.dmi' + icon_state = "cameracase" + materials = list(MAT_METAL=400, MAT_GLASS=250) + result_path = /obj/structure/camera_assembly + + +/obj/structure/camera_assembly + name = "camera assembly" + desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." + icon = 'icons/obj/monitors.dmi' + icon_state = "camera1" + max_integrity = 150 + // Motion, EMP-Proof, X-Ray + var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer)) + var/list/upgrades + var/state = 1 + + /* + 1 = Wrenched in place + 2 = Welded in place + 3 = Wires attached to it (you can now attach/dettach upgrades) + 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades) + */ + +/obj/structure/camera_assembly/Initialize(mapload, ndir, building) + . = ..() + if(building) + setDir(ndir) + upgrades = list() + +/obj/structure/camera_assembly/Destroy() + QDEL_LIST(upgrades) + return ..() + +/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params) + switch(state) + if(1) + // State 1 + if(istype(W, /obj/item/weldingtool)) + if(weld(W, user)) + to_chat(user, "You weld the assembly securely into place.") anchored = TRUE - state = 2 - return - - else if(istype(W, /obj/item/wrench)) - playsound(src.loc, W.usesound, 50, 1) - to_chat(user, "You unattach the assembly from its place.") - new /obj/item/wallframe/camera(get_turf(src)) - qdel(src) - return - - if(2) - // State 2 - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W - if(C.use(2)) - to_chat(user, "You add wires to the assembly.") - state = 3 - else - to_chat(user, "You need two lengths of cable to wire a camera!") - return - return - - else if(istype(W, /obj/item/weldingtool)) - - if(weld(W, user)) - to_chat(user, "You unweld the assembly from its place.") - state = 1 + state = 2 + return + + else if(istype(W, /obj/item/wrench)) + playsound(src.loc, W.usesound, 50, 1) + to_chat(user, "You unattach the assembly from its place.") + new /obj/item/wallframe/camera(get_turf(src)) + qdel(src) + return + + if(2) + // State 2 + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = W + if(C.use(2)) + to_chat(user, "You add wires to the assembly.") + state = 3 + else + to_chat(user, "You need two lengths of cable to wire a camera!") + return + return + + else if(istype(W, /obj/item/weldingtool)) + + if(weld(W, user)) + to_chat(user, "You unweld the assembly from its place.") + state = 1 anchored = TRUE - return - - - if(3) - // State 3 - if(istype(W, /obj/item/screwdriver)) - playsound(src.loc, W.usesound, 50, 1) - + return + + + if(3) + // State 3 + if(istype(W, /obj/item/screwdriver)) + playsound(src.loc, W.usesound, 50, 1) + var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13") - if(!input) - to_chat(user, "No input found, please hang up and try your call again!") - return - - var/list/tempnetwork = splittext(input, ",") - if(tempnetwork.len < 1) - to_chat(user, "No network found, please hang up and try your call again!") - return - - state = 4 - var/obj/machinery/camera/C = new(src.loc) - src.loc = C - C.assembly = src - C.setDir(src.dir) - - C.network = tempnetwork - var/area/A = get_area(src) - C.c_tag = "[A.name] ([rand(1, 999)])" - - - else if(istype(W, /obj/item/wirecutters)) - new/obj/item/stack/cable_coil(get_turf(src), 2) - playsound(src.loc, W.usesound, 50, 1) - to_chat(user, "You cut the wires from the circuits.") - state = 2 - return - - // Upgrades! - if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. - if(!user.drop_item(W)) - return - to_chat(user, "You attach \the [W] into the assembly inner circuits.") - upgrades += W - W.forceMove(src) - return - - // Taking out upgrades - else if(istype(W, /obj/item/crowbar) && upgrades.len) - var/obj/U = locate(/obj) in upgrades - if(U) - to_chat(user, "You unattach an upgrade from the assembly.") - playsound(src.loc, W.usesound, 50, 1) - U.loc = get_turf(src) - upgrades -= U - return - - return ..() - -/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user) - if(!WT.remove_fuel(0, user)) - return 0 - to_chat(user, "You start to weld \the [src]...") - playsound(src.loc, WT.usesound, 50, 1) - if(do_after(user, 20*WT.toolspeed, target = src)) - if(WT.isOn()) - playsound(loc, 'sound/items/welder2.ogg', 50, 1) - return 1 - return 0 - -/obj/structure/camera_assembly/deconstruct(disassembled = TRUE) + if(!input) + to_chat(user, "No input found, please hang up and try your call again!") + return + + var/list/tempnetwork = splittext(input, ",") + if(tempnetwork.len < 1) + to_chat(user, "No network found, please hang up and try your call again!") + return + + state = 4 + var/obj/machinery/camera/C = new(src.loc) + forceMove(C) + C.assembly = src + C.setDir(src.dir) + + C.network = tempnetwork + var/area/A = get_area(src) + C.c_tag = "[A.name] ([rand(1, 999)])" + + + else if(istype(W, /obj/item/wirecutters)) + new/obj/item/stack/cable_coil(get_turf(src), 2) + playsound(src.loc, W.usesound, 50, 1) + to_chat(user, "You cut the wires from the circuits.") + state = 2 + return + + // Upgrades! + if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. + if(!user.drop_item(W)) + return + to_chat(user, "You attach \the [W] into the assembly inner circuits.") + upgrades += W + W.forceMove(src) + return + + // Taking out upgrades + else if(istype(W, /obj/item/crowbar) && upgrades.len) + var/obj/U = locate(/obj) in upgrades + if(U) + to_chat(user, "You unattach an upgrade from the assembly.") + playsound(src.loc, W.usesound, 50, 1) + U.forceMove(drop_location()) + upgrades -= U + return + + return ..() + +/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user) + if(!WT.remove_fuel(0, user)) + return 0 + to_chat(user, "You start to weld \the [src]...") + playsound(src.loc, WT.usesound, 50, 1) + if(do_after(user, 20*WT.toolspeed, target = src)) + if(WT.isOn()) + playsound(loc, 'sound/items/welder2.ogg', 50, 1) + return 1 + return 0 + +/obj/structure/camera_assembly/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) - new /obj/item/stack/sheet/metal(loc) - qdel(src) + new /obj/item/stack/sheet/metal(loc) + qdel(src) diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 3f95d2a780..63c63ce120 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -45,14 +45,13 @@ if(!isarea(a)) return if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power! - to_chat(user, "The [name] blinks red as you try to insert the cell!") + to_chat(user, "The [src] blinks red as you try to insert the cell!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(W,src)) return - W.loc = src charging = W - user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.") + user.visible_message("[user] inserts a cell into [src].", "You insert a cell into [src].") chargelevel = -1 updateicon() else if(istype(W, /obj/item/wrench)) @@ -61,7 +60,7 @@ return anchored = !anchored - to_chat(user, "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground") + to_chat(user, "You [anchored ? "attach" : "detach"] [src] [anchored ? "to" : "from"] the ground") playsound(src.loc, W.usesound, 75, 1) else return ..() @@ -80,7 +79,7 @@ user.put_in_hands(charging) charging.add_fingerprint(user) - user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.") + user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].") removecell() diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index d9371d5678..b590763ffe 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -1,146 +1,146 @@ -/obj/machinery/computer/aifixer - name = "\improper AI system integrity restorer" - desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order." - req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS) - var/mob/living/silicon/ai/occupier = null - var/active = 0 - circuit = /obj/item/circuitboard/computer/aifixer - icon_keyboard = "tech_key" - icon_screen = "ai-fixer" - light_color = LIGHT_COLOR_PINK - -/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params) - if(occupier && istype(I, /obj/item/screwdriver)) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "The screws on [name]'s screen won't budge.") - else - to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep.") - else - return ..() - -/obj/machinery/computer/aifixer/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/computer/aifixer/interact(mob/user) - - var/dat = "" - - if (src.occupier) - var/laws - dat += "