diff --git a/code/__HELPERS/qdel.dm b/code/__HELPERS/qdel.dm index 2aea6de0dd7..8171dd66427 100644 --- a/code/__HELPERS/qdel.dm +++ b/code/__HELPERS/qdel.dm @@ -2,4 +2,4 @@ #define QDEL_NULL(item) if(item) { qdel(item); item = null } #define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } #define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } -#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qel(L[I]); L.Cut(); } +#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index f3ae2fdea48..e969751e1dd 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -33,13 +33,20 @@ if(control_disabled || stat) return - + var/turf/pixel_turf = get_turf_pixel(A) - if(pixel_turf && !cameranet.checkTurfVis(pixel_turf)) - log_admin("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(A)])") - message_admins("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([ADMIN_COORDJMP(A)]))") - send2irc_adminless_only("NOCHEAT", "[key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(A)]))") - return + var/turf_visible + if(pixel_turf) + turf_visible = cameranet.checkTurfVis(pixel_turf) + if(!turf_visible) + if(istype(loc, /obj/item/device/aicard) && (pixel_turf in view(client.view, loc))) + turf_visible = TRUE + else + if(pixel_turf.obscured) + log_admin("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)])") + message_admins("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))") + send2irc_adminless_only("NOCHEAT", "[key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))") + return var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm index 80d7fe7abf5..2184533add6 100644 --- a/code/datums/ai_law_sets.dm +++ b/code/datums/ai_law_sets.dm @@ -27,7 +27,6 @@ /datum/ai_laws/nanotrasen name = "NT Default" selectable = 1 - default = 1 /datum/ai_laws/nanotrasen/New() src.add_inherent_law("Safeguard: Protect your assigned space station to the best of your abilities. It is not something we can easily afford to replace.") @@ -61,7 +60,6 @@ /datum/ai_laws/robocop name = "Robocop" selectable = 1 - default = 1 /datum/ai_laws/robocop/New() add_inherent_law("Serve the public trust.") @@ -74,7 +72,6 @@ name = "P.A.L.A.D.I.N." law_header = "Divine Ordainments" selectable = 1 - default = 1 /datum/ai_laws/paladin/New() add_inherent_law("Never willingly commit an evil act.") diff --git a/code/datums/mind.dm b/code/datums/mind.dm index b584cdb92ab..aa80b0fc63e 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -659,16 +659,13 @@ if("remove") for(var/obj/item/weapon/implant/mindshield/I in H.contents) if(I && I.implanted) - I.removed(H) qdel(I) to_chat(H, "Your mindshield implant has been deactivated.") log_admin("[key_name(usr)] has deactivated [key_name(current)]'s mindshield implant") message_admins("[key_name_admin(usr)] has deactivated [key_name_admin(current)]'s mindshield implant") if("add") var/obj/item/weapon/implant/mindshield/L = new/obj/item/weapon/implant/mindshield(H) - L.imp_in = H - L.implanted = 1 - H.sec_hud_set_implants() + L.implant(H) log_admin("[key_name(usr)] has given [key_name(current)] a mindshield implant") message_admins("[key_name_admin(usr)] has given [key_name_admin(current)] a mindshield implant") diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index 9bc700ebabe..5c11c42930a 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -219,9 +219,7 @@ apply_to_card(I, H, get_centcom_access("Nanotrasen Navy Officer"), "Nanotrasen Navy Officer") var/obj/item/weapon/implant/L = new /obj/item/weapon/implant/mindshield(H) - L.imp_in = H - L.implanted = 1 - H.sec_hud_set_implants() + L.implant(H) /datum/outfit/admin/nt_special_ops_officer @@ -330,9 +328,7 @@ apply_to_card(I, H, get_centcom_access("Nanotrasen Navy Captain"), "Nanotrasen Navy Captain") var/obj/item/weapon/implant/L = new /obj/item/weapon/implant/mindshield(H) - L.imp_in = H - L.implanted = 1 - H.sec_hud_set_implants() + L.implant(H) /datum/outfit/admin/nt_diplomat name = "NT Diplomat" @@ -756,9 +752,7 @@ apply_to_card(I, H, get_centcom_access("Emergency Response Team Member"), "Emergency Response Team Member") var/obj/item/weapon/implant/L = new /obj/item/weapon/implant/mindshield(H) - L.imp_in = H - L.implanted = 1 - H.sec_hud_set_implants() + L.implant(H) /datum/outfit/admin/chrono name = "Chrono Legionnaire" diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index b8673b497d5..7dd8d0c5be8 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -26,7 +26,7 @@ // If you're wondering what goofery this is, this is for things that need the environment // around them set up - like `air_update_turf` and the like - if((ticker && ticker.current_state == GAME_STATE_PLAYING)) + if((ticker && ticker.current_state >= GAME_STATE_SETTING_UP)) attempt_init() /atom/movable/Destroy() @@ -231,7 +231,7 @@ if(isobj(A)) if(A.density && !A.throwpass) // **TODO: Better behaviour for windows which are dense, but shouldn't always stop movement src.throw_impact(A,speed) - + /atom/movable/proc/throw_at_fast(atom/target, range, speed, thrower, no_spin) set waitfor = 0 throw_at(target, range, speed, thrower, no_spin) diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index 892c89fdd3a..5fd98986332 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -37,27 +37,27 @@ // isn't, but I don't want to remove it, just in case. for(var/organ_name in H.bodyparts_by_name) var/obj/item/organ/external/O = H.bodyparts_by_name[organ_name] - if(!O) continue + if(!O) + continue for(var/obj/item/weapon/shard/shrapnel/s in O.implants) - if(istype(s)) - O.implants -= s - H.contents -= s - qdel(s) + O.implants -= s + H.contents -= s + qdel(s) O.brute_dam = 0 O.burn_dam = 0 O.damage_state = "00" O.germ_level = 0 - O.hidden = null + QDEL_NULL(O.hidden) O.number_wounds = 0 O.open = 0 O.perma_injury = 0 O.status = 0 - O.trace_chemicals = list() - O.wounds = list() + O.trace_chemicals.Cut() + QDEL_LIST(O.wounds) O.wound_update_accuracy = 1 for(var/obj/item/organ/internal/IO in H.internal_organs) IO.damage = 0 - IO.trace_chemicals = list() + IO.trace_chemicals.Cut() H.updatehealth() to_chat(user, "We have regenerated.") diff --git a/code/game/gamemodes/cult/cult_objectives.dm b/code/game/gamemodes/cult/cult_objectives.dm index 4b30bbd37b0..c9e951cf940 100644 --- a/code/game/gamemodes/cult/cult_objectives.dm +++ b/code/game/gamemodes/cult/cult_objectives.dm @@ -21,7 +21,7 @@ if("convert") explanation = "We must increase our influence before we can summon [ticker.mode.cultdat.entity_name], Convert [convert_target] crew members. Take it slowly to avoid raising suspicions." if("bloodspill") - spilltarget = 100 + rand(0,player_list.len * 3) + spilltarget = 70 + rand(0,player_list.len * 3) explanation = "We must prepare this place for [ticker.mode.cultdat.entity_title1]'s coming. Spill blood and gibs over [spilltarget] floor tiles." if("sacrifice") explanation = "We need to sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role], for his blood is the key that will lead our master to this realm. You will need 3 cultists around a Sacrifice rune to perform the ritual." diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 14fe620cc3c..2ae02d2f773 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -336,7 +336,7 @@ var/list/teleport_runes = list() var/turf/T = get_turf(src) for(var/mob/living/M in T.contents) - if(!iscultist(M) && !ismindshielded(M)) + if(!iscultist(M) && !ismindshielded(M) && ishuman(M)) convertees.Add(M) if(!convertees.len) fail_invoke() @@ -415,6 +415,7 @@ var/list/teleport_runes = list() /obj/effect/rune/sacrifice/proc/sac(var/list/invokers, mob/living/T) var/sacrifice_fulfilled + var/datum/game_mode/cult/cult_mode = ticker.mode if(T) if(istype(T, /mob/living/simple_animal/pet/corgi)) for(var/M in invokers) @@ -428,11 +429,12 @@ var/list/teleport_runes = list() sacrifice_fulfilled = 1 new /obj/effect/overlay/temp/cult/sac(loc) if(ticker && ticker.mode && ticker.mode.name == "cult") - var/datum/game_mode/cult/cult_mode = ticker.mode + cult_mode.harvested++ for(var/M in invokers) if(sacrifice_fulfilled) to_chat(M, "\"Yes! This is the one I desire! You have done well.\"") + cult_mode.additional_phase() else if(ishuman(T) || isrobot(T)) to_chat(M, "\"I accept this sacrifice.\"") diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 1868222718f..70ebd23912f 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -126,8 +126,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' //Now apply cortical stack. var/obj/item/weapon/implant/cortical/I = new(vox) - I.imp_in = vox - I.implanted = 1 + I.implant(vox) cortical_stacks += I vox.equip_vox_raider() diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 4d0b4d51dd3..ec9b8776f80 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -198,9 +198,7 @@ if(implants) for(var/implant_type in implants) var/obj/item/weapon/implant/I = new implant_type(H) - I.imp_in = H - I.implanted = 1 - H.sec_hud_set_implants() + I.implant(H) if(gear_leftovers.len) for(var/datum/gear/G in gear_leftovers) @@ -228,7 +226,7 @@ var/datum/job/J = job_master.GetJobType(jobtype) if(!J) J = job_master.GetJob(H.job) - + var/alt_title if(H.mind) alt_title = H.mind.role_alt_title diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index e1b6bfda98e..3cd236881c5 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -191,6 +191,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0) implants = list(/obj/item/weapon/implant/mindshield) backpack = /obj/item/weapon/storage/backpack/security + satchel = /obj/item/weapon/storage/backpack/satchel_sec + dufflebag = /obj/item/weapon/storage/backpack/duffel/security /datum/job/judge @@ -234,6 +236,9 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0) implants = list(/obj/item/weapon/implant/mindshield) + satchel = /obj/item/weapon/storage/backpack/satchel_sec + dufflebag = /obj/item/weapon/storage/backpack/duffel/security + //var/global/lawyer = 0//Checks for another lawyer //This changed clothes on 2nd lawyer, both IA get the same dreds. @@ -270,3 +275,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 0) pda = /obj/item/device/pda/lawyer implants = list(/obj/item/weapon/implant/mindshield) + + satchel = /obj/item/weapon/storage/backpack/satchel_sec + dufflebag = /obj/item/weapon/storage/backpack/duffel/security diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index e4cb0028408..b5612389def 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -213,6 +213,10 @@ radio_controller.remove_object(src, frequency) air_alarm_repository.update_cache(src) QDEL_NULL(wires) + if(alarm_area && alarm_area.master_air_alarm == src) + alarm_area.master_air_alarm = null + elect_master(exclude_self = 1) + alarm_area = null return ..() /obj/machinery/alarm/proc/first_run() @@ -236,8 +240,10 @@ return alarm_area.master_air_alarm && !(alarm_area.master_air_alarm.stat & (NOPOWER|BROKEN)) -/obj/machinery/alarm/proc/elect_master() +/obj/machinery/alarm/proc/elect_master(exclude_self = 0) //Why is this an alarm and not area proc? for(var/obj/machinery/alarm/AA in alarm_area) + if(exclude_self && AA == src) + continue if(!(AA.stat & (NOPOWER|BROKEN))) alarm_area.master_air_alarm = AA return 1 diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 69cfd4a6e89..063eb8baa1b 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -10,88 +10,117 @@ power_channel = EQUIP var/obj/item/weapon/stock_parts/cell/charging = null var/chargelevel = -1 - proc - updateicon() - icon_state = "ccharger[charging ? 1 : 0]" - if(charging && !(stat & (BROKEN|NOPOWER)) ) +/obj/machinery/cell_charger/Destroy() + QDEL_NULL(charging) + return ..() - var/newlevel = round(charging.percent() * 4 / 100) -// to_chat(world, "nl: [newlevel]") +/obj/machinery/cell_charger/proc/updateicon() + icon_state = "ccharger[charging ? 1 : 0]" - if(chargelevel != newlevel) + if(charging && !(stat & (BROKEN|NOPOWER))) + var/newlevel = round(charging.percent() * 4 / 100) - overlays.Cut() - overlays += "ccharger-o[newlevel]" + if(chargelevel != newlevel) + chargelevel = newlevel - chargelevel = newlevel - else - overlays.Cut() - examine(mob/user) - if(..(user, 5)) - to_chat(user, "There's [charging ? "a" : "no"] cell in the charger.") - if(charging) - to_chat(user, "Current charge: [charging.charge]") + overlays.Cut() + overlays += "ccharger-o[newlevel]" - attackby(obj/item/weapon/W, mob/user, params) + else + overlays.Cut() + +/obj/machinery/cell_charger/examine(mob/user) + ..() + to_chat(user, "There's [charging ? "a" : "no"] cell in the charger.") + if(charging) + to_chat(user, "Current charge: [round(charging.percent(), 1)]%") + +/obj/machinery/cell_charger/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/weapon/stock_parts/cell)) if(stat & BROKEN) + to_chat(user, "[src] is broken!") + return + if(!anchored) + to_chat(user, "[src] isn't attached to the ground!") return - - if(istype(W, /obj/item/weapon/stock_parts/cell) && anchored) - if(charging) - to_chat(user, "There is already a cell in the charger.") - return - else - var/area/a = loc.loc // Gets our locations location, like a dream within a dream - 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!") - return - - user.drop_item() - W.loc = src - charging = W - user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.") - chargelevel = -1 - updateicon() - else if(istype(W, /obj/item/weapon/wrench)) - if(charging) - to_chat(user, "Remove the cell first!") - return - - anchored = !anchored - to_chat(user, "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground") - playsound(get_turf(src), W.usesound, 75, 1) - - attack_hand(mob/user) if(charging) - usr.put_in_hands(charging) - charging.add_fingerprint(user) - charging.updateicon() + to_chat(user, "There is already a cell in the charger!") + return + else + var/area/a = loc.loc // Gets our locations location, like a dream within a dream + 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, "[src] blinks red as you try to insert the cell!") + return + if(!user.drop_item()) + return - src.charging = null - user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.") + W.forceMove(src) + charging = W + user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.") chargelevel = -1 updateicon() + else if(iswrench(W)) + if(charging) + to_chat(user, "Remove the cell first!") + return - attack_ai(mob/user) + anchored = !anchored + to_chat(user, "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground") + playsound(src.loc, W.usesound, 75, 1) + else + return ..() + + +/obj/machinery/cell_charger/proc/removecell() + charging.updateicon() + charging = null + chargelevel = -1 + updateicon() + +/obj/machinery/cell_charger/attack_hand(mob/user) + if(!charging) return - emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - return - if(charging) - charging.emp_act(severity) - ..(severity) + user.put_in_hands(charging) + charging.add_fingerprint(user) + + user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].") + + removecell() + +/obj/machinery/cell_charger/attack_tk(mob/user) + if(!charging) + return + + charging.forceMove(loc) + to_chat(user, "You telekinetically remove [charging] from [src].") + + removecell() + +/obj/machinery/cell_charger/attack_ai(mob/user) + return + +/obj/machinery/cell_charger/emp_act(severity) + if(stat & (BROKEN|NOPOWER)) + return + + if(charging) + charging.emp_act(severity) + + ..(severity) - process() -// to_chat(world, "ccpt [charging] [stat]") - if(!charging || (stat & (BROKEN|NOPOWER)) || !anchored) - return +/obj/machinery/cell_charger/process() + if(!charging || !anchored || (stat & (BROKEN|NOPOWER))) + return - use_power(200) //this used to use CELLRATE, but CELLRATE is fucking awful. feel free to fix this properly! - charging.give(175) //inefficiency. + if(charging.percent() >= 100) + return - updateicon() + use_power(200) //this used to use CELLRATE, but CELLRATE is fucking awful. feel free to fix this properly! + charging.give(175) //inefficiency. + + updateicon() \ No newline at end of file diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 0d47420edc9..ee307dd84d5 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -413,13 +413,10 @@ R.languages=subject.languages //Add an implant if needed var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject) - if(isnull(imp)) + if(!imp) imp = new /obj/item/weapon/implant/health(subject) - imp.implanted = subject - R.implant = "\ref[imp]" - //Update it if needed - else - R.implant = "\ref[imp]" + imp.implant(subject) + R.implant = "\ref[imp]" if(!isnull(subject.mind)) //Save that mind so traitors can continue traitoring after cloning. R.mind = "\ref[subject.mind]" diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 586b45f0a13..da85a864214 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -19,13 +19,6 @@ FIRE ALARM var/last_process = 0 var/wiresexposed = 0 var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone - var/area/master_area - -/obj/machinery/firealarm/New() - var/area/A = get_area_master(src) - if(!istype(A, /area)) - return - master_area = A /obj/machinery/firealarm/update_icon() @@ -294,14 +287,6 @@ Just a object used in constructing fire alarms idle_power_usage = 2 active_power_usage = 6 - var/area/master_area - -/obj/machinery/partyalarm/New() - var/area/A = get_area_master(src) - if(!( istype(A, /area) )) - return - master_area=A - /obj/machinery/partyalarm/attack_hand(mob/user) if((user.stat && !isobserver(user)) || stat & (NOPOWER|BROKEN)) return diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm index f0c3ee84e98..46ee95d119b 100644 --- a/code/game/objects/items/candle.dm +++ b/code/game/objects/items/candle.dm @@ -17,6 +17,10 @@ // No visible message light(show_message = 0) +/obj/item/candle/Destroy() + processing_objects.Remove(src) + return ..() + /obj/item/candle/update_icon() var/i if(wax>150) diff --git a/code/game/objects/items/devices/autopsy.dm b/code/game/objects/items/devices/autopsy.dm index 7ebf13e538b..2839715d7d7 100644 --- a/code/game/objects/items/devices/autopsy.dm +++ b/code/game/objects/items/devices/autopsy.dm @@ -7,16 +7,24 @@ w_class = WEIGHT_CLASS_TINY origin_tech = "materials=1;biotech=1" var/list/datum/autopsy_data_scanner/wdata = list() - var/list/datum/autopsy_data_scanner/chemtraces = list() + var/list/chemtraces = list() var/target_name = null var/timeofdeath = null +/obj/item/weapon/autopsy_scanner/Destroy() + QDEL_LIST_ASSOC_VAL(wdata) + return ..() + /datum/autopsy_data_scanner var/weapon = null // this is the DEFINITE weapon type that was used var/list/organs_scanned = list() // this maps a number of scanned organs to // the wounds to those organs with this data's weapon type var/organ_names = "" +/datum/autopsy_data_scanner/Destroy() + QDEL_LIST_ASSOC_VAL(organs_scanned) + return ..() + /datum/autopsy_data var/weapon = null var/pretend_weapon = null diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index b48f21a60cd..7145bd88bb7 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -66,8 +66,6 @@ var/global/list/default_medbay_channels = list( /obj/item/device/radio/New() ..() wires = new(src) - if(radio_controller) - initialize() internal_channels = default_internal_channels.Copy() global_radios |= src diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index d99ed06bb6c..ef1589f50b7 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -10,8 +10,7 @@ var/model_info dir = SOUTH - -/obj/item/robot_parts/New(var/newloc, var/model) +/obj/item/robot_parts/New(newloc, model) ..(newloc) if(model_info && model) model_info = model @@ -57,9 +56,13 @@ desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." icon_state = "chest" part = list("groin","chest") - var/wires = 0.0 + var/wired = FALSE var/obj/item/weapon/stock_parts/cell/cell = null +/obj/item/robot_parts/chest/Destroy() + QDEL_NULL(cell) + return ..() + /obj/item/robot_parts/head name = "head" desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals." @@ -68,6 +71,11 @@ var/obj/item/device/flash/flash1 = null var/obj/item/device/flash/flash2 = null +/obj/item/robot_parts/head/Destroy() + QDEL_NULL(flash1) + QDEL_NULL(flash2) + return ..() + /obj/item/robot_parts/robot_suit name = "endoskeleton" desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors." @@ -88,89 +96,108 @@ /obj/item/robot_parts/robot_suit/New() ..() - src.updateicon() + updateicon() + +/obj/item/robot_parts/robot_suit/Destroy() + QDEL_NULL(l_arm) + QDEL_NULL(r_arm) + QDEL_NULL(l_leg) + QDEL_NULL(r_leg) + QDEL_NULL(chest) + QDEL_NULL(head) + forced_ai = null + return ..() /obj/item/robot_parts/robot_suit/proc/updateicon() - src.overlays.Cut() - if(src.l_arm) - src.overlays += "l_arm+o" - if(src.r_arm) - src.overlays += "r_arm+o" - if(src.chest) - src.overlays += "chest+o" - if(src.l_leg) - src.overlays += "l_leg+o" - if(src.r_leg) - src.overlays += "r_leg+o" - if(src.head) - src.overlays += "head+o" + overlays.Cut() + if(l_arm) + overlays += "l_arm+o" + if(r_arm) + overlays += "r_arm+o" + if(chest) + overlays += "chest+o" + if(l_leg) + overlays += "l_leg+o" + if(r_leg) + overlays += "r_leg+o" + if(head) + overlays += "head+o" /obj/item/robot_parts/robot_suit/proc/check_completion() - if(src.l_arm && src.r_arm) - if(src.l_leg && src.r_leg) - if(src.chest && src.head) + if(l_arm && r_arm) + if(l_leg && r_leg) + if(chest && head) feedback_inc("cyborg_frames_built",1) return 1 return 0 -/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/robot_parts/robot_suit/attackby(obj/item/W, mob/user, params) ..() if(istype(W, /obj/item/stack/sheet/metal) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head) + var/obj/item/stack/sheet/metal/M = W var/obj/item/weapon/ed209_assembly/B = new /obj/item/weapon/ed209_assembly - B.loc = get_turf(src) + B.forceMove(get_turf(src)) to_chat(user, "You armed the robot frame") - W:use(1) + M.use(1) if(user.get_inactive_hand()==src) user.unEquip(src) user.put_in_inactive_hand(B) qdel(src) if(istype(W, /obj/item/robot_parts/l_leg)) - if(src.l_leg) return + if(l_leg) + return user.drop_item() - W.loc = src - src.l_leg = W - src.updateicon() + W.forceMove(src) + l_leg = W + updateicon() if(istype(W, /obj/item/robot_parts/r_leg)) - if(src.r_leg) return + if(r_leg) + return user.drop_item() - W.loc = src - src.r_leg = W - src.updateicon() + W.forceMove(src) + r_leg = W + updateicon() if(istype(W, /obj/item/robot_parts/l_arm)) - if(src.l_arm) return + if(l_arm) + return user.drop_item() - W.loc = src - src.l_arm = W - src.updateicon() + W.forceMove(src) + l_arm = W + updateicon() if(istype(W, /obj/item/robot_parts/r_arm)) - if(src.r_arm) return + if(r_arm) + return user.drop_item() - W.loc = src - src.r_arm = W - src.updateicon() + W.forceMove(src) + r_arm = W + updateicon() if(istype(W, /obj/item/robot_parts/chest)) - if(src.chest) return - if(W:wires && W:cell) + var/obj/item/robot_parts/chest/CH = W + if(chest) + return + if(CH.wired && CH.cell) user.drop_item() - W.loc = src - src.chest = W - src.updateicon() - else if(!W:wires) + W.forceMove(src) + chest = W + updateicon() + else if(!CH.wired) to_chat(user, "You need to attach wires to it first!") else to_chat(user, "You need to attach a cell to it first!") if(istype(W, /obj/item/robot_parts/head)) - if(src.head) return - if(W:flash2 && W:flash1) + var/obj/item/robot_parts/head/HD = W + if(head) + return + if(HD.flash2 && HD.flash1) user.drop_item() - W.loc = src - src.head = W - src.updateicon() + W.forceMove(src) + head = W + updateicon() else to_chat(user, "You need to attach a flash to it first!") @@ -183,11 +210,11 @@ if(istype(W, /obj/item/device/mmi)) var/obj/item/device/mmi/M = W if(check_completion()) - if(!istype(loc,/turf)) - to_chat(user, "You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise.") + if(!isturf(loc)) + to_chat(user, "You can't put [M] in, the frame has to be standing on the ground to be perfectly precise.") return if(!M.brainmob) - to_chat(user, "Sticking an empty [W] into the frame would sort of defeat the purpose.") + to_chat(user, "Sticking an empty [M] into the frame would sort of defeat the purpose.") return if(!M.brainmob.key) @@ -202,15 +229,15 @@ ghost_can_reenter = 1 break if(!ghost_can_reenter) - to_chat(user, "\The [W] is completely unresponsive; there's no point.") + to_chat(user, "[M] is completely unresponsive; there's no point.") return if(M.brainmob.stat == DEAD) - to_chat(user, "Sticking a dead [W] into the frame would sort of defeat the purpose.") + to_chat(user, "Sticking a dead [M] into the frame would sort of defeat the purpose.") return if(M.brainmob.mind in ticker.mode.head_revolutionaries) - to_chat(user, "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W].") + to_chat(user, "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [M].") return if(jobban_isbanned(M.brainmob, "Cyborg") || jobban_isbanned(M.brainmob,"nonhumandept")) @@ -218,7 +245,8 @@ return var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc), unfinished = 1) - if(!O) return + if(!O) + return user.drop_item() @@ -257,9 +285,9 @@ O.job = "Cyborg" O.cell = chest.cell - chest.cell.loc = O + chest.cell.forceMove(O) chest.cell = null - W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. + M.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. // Since we "magically" installed a cell, we also have to update the correct component. if(O.cell) var/datum/robot_component/cell_component = O.components["power cell"] @@ -271,7 +299,8 @@ feedback_inc("cyborg_birth",1) callHook("borgify", list(O)) - src.loc = O + forceMove(O) + O.robot_suit = src if(!locomotion) O.lockcharge = 1 @@ -308,8 +337,8 @@ return if(href_list["Name"]) - var/new_name = reject_bad_name(input(usr, "Enter new designation. Set to blank to reset to default.", "Cyborg Debug", src.created_name),1) - if(!in_range(src, usr) && src.loc != usr) + var/new_name = reject_bad_name(input(usr, "Enter new designation. Set to blank to reset to default.", "Cyborg Debug", created_name),1) + if(!in_range(src, usr) && loc != usr) return if(new_name) created_name = new_name @@ -337,22 +366,22 @@ /obj/item/robot_parts/chest/attackby(obj/item/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/stock_parts/cell)) - if(src.cell) + if(cell) to_chat(user, "You have already inserted a cell!") return else user.drop_item() - W.loc = src - src.cell = W + W.forceMove(src) + cell = W to_chat(user, "You insert the cell!") if(istype(W, /obj/item/stack/cable_coil)) - if(src.wires) + if(wired) to_chat(user, "You have already inserted wire!") return else var/obj/item/stack/cable_coil/coil = W coil.use(1) - src.wires = 1.0 + wired = TRUE to_chat(user, "You insert the wire!") return @@ -362,18 +391,18 @@ if(istype(user,/mob/living/silicon/robot)) to_chat(user, "How do you propose to do that?") return - else if(src.flash1 && src.flash2) + else if(flash1 && flash2) to_chat(user, "You have already inserted the eyes!") return - else if(src.flash1) + else if(flash1) user.drop_item() - W.loc = src - src.flash2 = W + W.forceMove(src) + flash2 = W to_chat(user, "You insert the flash into the eye socket!") else user.drop_item() - W.loc = src - src.flash1 = W + W.forceMove(src) + flash1 = W to_chat(user, "You insert the flash into the eye socket!") else if(istype(W, /obj/item/weapon/stock_parts/manipulator)) to_chat(user, "You install some manipulators and modify the head, creating a functional spider-bot!") @@ -381,15 +410,10 @@ user.drop_item() qdel(W) qdel(src) - return - return -/obj/item/robot_parts/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/weapon/card/emag)) - if(sabotaged) - to_chat(user, "[src] is already sabotaged!") - else - to_chat(user, "You slide [W] into the dataport on [src] and short out the safeties.") - sabotaged = 1 - return - ..() +/obj/item/robot_parts/emag_act(user) + if(sabotaged) + to_chat(user, "[src] is already sabotaged!") + else + to_chat(user, "You slide the emag into the dataport on [src] and short out the safeties.") + sabotaged = 1 diff --git a/code/game/objects/items/weapons/bee_briefcase.dm b/code/game/objects/items/weapons/bee_briefcase.dm index 7d2b718da82..3252fe4d856 100644 --- a/code/game/objects/items/weapons/bee_briefcase.dm +++ b/code/game/objects/items/weapons/bee_briefcase.dm @@ -18,6 +18,10 @@ var/sound_file = 'sound/misc/briefcase_bees.ogg' var/next_sound = 0 +/obj/item/weapon/bee_briefcase/Destroy() + blood_list.Cut() + return ..() + /obj/item/weapon/bee_briefcase/examine(mob/user) ..() if(loc == user) @@ -70,6 +74,6 @@ //Release up to 5 bees per use. Without using strange reagent, that means two uses. WITH strange reagent, you can get more if you don't release the last bee for(var/bee = min(5, bees_left), bee > 0, bee--) var/mob/living/simple_animal/hostile/poison/bees/syndi/B = new /mob/living/simple_animal/hostile/poison/bees/syndi(null) - B.master_and_friends = blood_list //Doesn't automatically add the person who opens the case, so the bees will attack the user unless they gave their blood + B.master_and_friends = blood_list.Copy() //Doesn't automatically add the person who opens the case, so the bees will attack the user unless they gave their blood B.forceMove(get_turf(user)) //RELEASE THE BEES! bees_left -= 5 diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 66b4b228b64..8109e8e8b86 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -48,7 +48,7 @@ for(var/X in actions) var/datum/action/A = X A.Grant(source) - if(istype(source, /mob/living/carbon/human)) + if(ishuman(source)) var/mob/living/carbon/human/H = source H.sec_hud_set_implants() @@ -66,7 +66,7 @@ var/datum/action/A = X A.Grant(source) - if(istype(source, /mob/living/carbon/human)) + if(ishuman(source)) var/mob/living/carbon/human/H = source H.sec_hud_set_implants() diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm index 0ba245af4e6..70073b38123 100644 --- a/code/game/objects/items/weapons/shards.dm +++ b/code/game/objects/items/weapons/shards.dm @@ -71,7 +71,7 @@ /obj/item/weapon/shard/Crossed(AM as mob|obj) if(isliving(AM)) var/mob/living/M = AM - if(M.incorporeal_move || M.flying)//you are incorporal or flying..no shard stepping! + if(M.incorporeal_move || M.flying || M.throwing)//you are incorporal or flying or being thrown ..no shard stepping! return to_chat(M, "You step on \the [src]!") playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 9ecf82a54fb..72638ff0943 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -256,6 +256,9 @@ var/global/list/captain_display_cases = list() new /obj/machinery/constructable_frame/machine_frame(T) qdel(src) return + if(W.flags & ABSTRACT) + to_chat(user, "You can't put this into the case.") + return if(user.a_intent == I_HARM) if(locked && !destroyed) src.health -= W.force diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 496c998b623..04f8b29da0c 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -485,8 +485,7 @@ client/proc/one_click_antag() //Now apply cortical stack. var/obj/item/weapon/implant/cortical/I = new(new_vox) - I.imp_in = new_vox - I.implanted = 1 + I.implant(new_vox) cortical_stacks += I new_vox.equip_vox_raider() diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index d90c8a50a84..83e8d617210 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -158,9 +158,7 @@ var/global/sent_strike_team = 0 var/obj/item/weapon/implant/mindshield/L = new/obj/item/weapon/implant/mindshield(src) - L.imp_in = src - L.implanted = 1 - sec_hud_set_implants() + L.implant(src) var/obj/item/weapon/card/id/W = new(src) W.name = "[real_name]'s ID Card" diff --git a/code/modules/client/preference/loadout/loadout_racial.dm b/code/modules/client/preference/loadout/loadout_racial.dm new file mode 100644 index 00000000000..e9d89a31d34 --- /dev/null +++ b/code/modules/client/preference/loadout/loadout_racial.dm @@ -0,0 +1,40 @@ +/datum/gear/racial + sort_category = "Racial" + subtype_path = /datum/gear/racial + cost = 2 + + +/datum/gear/racial/tajciv + display_name = "embroidered veil" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." + path = /obj/item/clothing/glasses/tajblind + +/datum/gear/racial/tajsec + display_name = "sleek veil" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built security HUD." + path = /obj/item/clothing/glasses/hud/security/tajblind + allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot", "Internal Affairs Agent", "Magistrate") + +/datum/gear/racial/tajmed + display_name = "lightweight veil" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built medical HUD." + path = /obj/item/clothing/glasses/hud/health/tajblind + allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Psychiatrist", "Paramedic", "Virologist", "Brig Physician") + +/datum/gear/racial/tajsci + display_name = "hi-tech veil" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." + path = /obj/item/clothing/glasses/tajblind/sci + allowed_roles = list("Scientist", "Research Director", "Robotocist") + +/datum/gear/racial/tajeng + display_name = "industrial veil" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." + path = /obj/item/clothing/glasses/tajblind/eng + allowed_roles = list("Chief Engineer", "Station Engineer", "Mechanic", "Life Support Specialist") + +/datum/gear/racial/tajcargo + display_name = "khaki veil" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. It is light and comfy!" + path = /obj/item/clothing/glasses/tajblind/cargo + allowed_roles = list("Quartermaster","Cargo Technician", "Miner") \ No newline at end of file diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 9fe951a7dc7..febc8d5b306 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -495,4 +495,46 @@ else to_chat(user, "The eye winks at you and vanishes into the abyss, you feel really unlucky.") qdel(src) - ..() \ No newline at end of file + ..() + +/obj/item/clothing/glasses/tajblind + name = "embroidered veil" + desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes." + icon_state = "tajblind" + item_state = "tajblind" + flags_cover = GLASSESCOVERSEYES + actions_types = list(/datum/action/item_action/toggle) + up = 0 + tint = 0 + +/obj/item/clothing/glasses/tajblind/eng + name = "industrial veil" + icon_state = "tajblind_engi" + item_state = "tajblind_engi" + +/obj/item/clothing/glasses/tajblind/sci + name = "hi-tech veil" + icon_state = "tajblind_sci" + item_state = "tajblind_sci" + +/obj/item/clothing/glasses/tajblind/cargo + name = "khaki veil" + icon_state = "tajblind_cargo" + item_state = "tajblind_cargo" + +/obj/item/clothing/glasses/tajblind/attack_self() + toggle_veil() + +/obj/item/clothing/glasses/proc/toggle_veil() + if(usr.canmove && !usr.incapacitated()) + if(up) + up = !up + tint = initial(tint) + to_chat(usr, "You activate [src], allowing you to see.") + else + up = !up + tint = 3 + to_chat(usr, "You deactivate [src], obscuring your vision.") + var/mob/living/carbon/user = usr + user.update_tint() + user.update_inv_glasses() \ No newline at end of file diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 18d9b26361f..38fd0d38ace 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -9,6 +9,7 @@ /obj/item/clothing/glasses/hud/equipped(mob/living/carbon/human/user, slot) + ..() if(HUDType && slot == slot_glasses) var/datum/atom_hud/H = huds[HUDType] H.add_hud_to(user) @@ -133,4 +134,28 @@ item_state = "glasses" darkness_view = 8 invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these - prescription_upgradable = 0 \ No newline at end of file + prescription_upgradable = 0 + +/obj/item/clothing/glasses/hud/security/tajblind + name = "sleek veil" + desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes. This one has an in-built security HUD." + icon_state = "tajblind_sec" + item_state = "tajblind_sec" + flags_cover = GLASSESCOVERSEYES + actions_types = list(/datum/action/item_action/toggle) + up = 0 + +/obj/item/clothing/glasses/hud/security/tajblind/attack_self() + toggle_veil() + +/obj/item/clothing/glasses/hud/health/tajblind + name = "lightweight veil" + desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes. This one has an installed medical HUD." + icon_state = "tajblind_med" + item_state = "tajblind_med" + flags_cover = GLASSESCOVERSEYES + actions_types = list(/datum/action/item_action/toggle) + up = 0 + +/obj/item/clothing/glasses/hud/health/tajblind/attack_self() + toggle_veil() \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 324a05614c3..20a14cc4fc5 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -294,6 +294,16 @@ icon_state = "plasmaman_HoS_helmet0" base_state = "plasmaman_HoS_helmet" +//NT REP +/obj/item/clothing/suit/space/eva/plasmaman/nt_rep + name = "plasmaman NT representative suit" + icon_state = "plasmaman_rep" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/nt_rep + name = "plasmaman NT representative helmet" + icon_state = "plasmaman_rep_helmet0" + base_state = "plasmaman_rep_helmet" + //SECURITY /obj/item/clothing/suit/space/eva/plasmaman/security diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index f1b2937565c..51a34d245ef 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -390,11 +390,10 @@ picked_color = input(H, "Which color would you like to paint [target]?", "Recolor") as null|anything in helmets var/obj/item/clothing/head/helmet/space/eva/plasmaman/P = target - if(picked_color) - P.icon_state = helmets[picked_color] + "[P.on]" - P.base_state = helmets[picked_color] - else + if(!picked_color) return + P.icon_state = helmets[picked_color] + "[P.on]" + P.base_state = helmets[picked_color] to_chat(H, "You modify the appearance of [target].") P.icon = 'icons/obj/custom_items.dmi' @@ -410,10 +409,9 @@ picked_color = input(H, "Which color would you like to paint [target]?", "Recolor") as null|anything in suits var/obj/item/clothing/suit/space/eva/plasmaman/P = target - if(picked_color) - P.icon_state = suits[picked_color] - else + if(!picked_color) return + P.icon_state = suits[picked_color] to_chat(H, "You modify the appearance of [target].") P.icon = 'icons/obj/custom_items.dmi' diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 1781479ec6c..5862de7d6ca 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -61,7 +61,7 @@ head.disfigure("burn") add_logs(user, G.affecting, "deep-fried", addition="'s face") qdel(G) //Removes the grip so the person MIGHT have a small chance to run the fuck away and to prevent rapid dunks. - return 1 + return 0 return 0 diff --git a/code/modules/food_and_drinks/kitchen_machinery/grill_new.dm b/code/modules/food_and_drinks/kitchen_machinery/grill_new.dm index d63971dcc30..1a1dd34196d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/grill_new.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/grill_new.dm @@ -57,5 +57,5 @@ C.adjustFireLoss(30) add_logs(user, G.affecting, "burned", src) qdel(G) //Removes the grip to prevent rapid sears and give you a chance to run - return 1 + return 0 return 0 \ No newline at end of file diff --git a/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm b/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm index bd850288bc4..5c1ed4ac6df 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/oven_new.dm @@ -63,5 +63,5 @@ C.Weaken(2) add_logs(user, G.affecting, "smashed", addition="'s head on [src]") qdel(G) //Removes the grip to prevent rapid bashes. With the weaken, you PROBABLY can't run unless they are slow to grab you again... - return 1 + return 0 return 0 diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 18f87a8a45a..7bfa00d35c3 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -51,11 +51,13 @@ /obj/structure/beebox/Destroy() processing_objects.Remove(src) + for(var/mob/living/simple_animal/hostile/poison/bees/B in bees) + B.beehome = null bees.Cut() bees = null - honeycombs.Cut() - honeycombs = null - queen_bee = null + QDEL_LIST(honeycombs) + QDEL_LIST(honey_frames) + QDEL_NULL(queen_bee) return ..() diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 7e7aa825411..7c5297e07c4 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -75,6 +75,7 @@ plant_hud_set_water() /obj/machinery/hydroponics/Destroy() + remove_from_all_data_huds() QDEL_NULL(myseed) return ..() diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 379a15a296a..7f2c3587349 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -44,7 +44,7 @@ icon_state = "sextractor" density = 1 anchored = 1 - var/piles = list() + var/list/piles = list() var/max_seeds = 1000 var/seed_multiplier = 1 @@ -56,6 +56,10 @@ component_parts += new /obj/item/weapon/stock_parts/manipulator(null) RefreshParts() +/obj/machinery/seed_extractor/Destroy() + QDEL_LIST(piles) + return ..() + /obj/machinery/seed_extractor/RefreshParts() for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts) max_seeds = 1000 * B.rating @@ -125,14 +129,14 @@ /obj/machinery/seed_extractor/attack_hand(mob/user) interact(user) - + /obj/machinery/seed_extractor/attack_ghost(mob/user) interact(user) /obj/machinery/seed_extractor/interact(mob/user) if(stat) return 0 - + add_fingerprint(user) user.set_machine(src) diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 9aa93f9f92b..ae79eda23d3 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -69,9 +69,7 @@ genes += new /datum/plant_gene/reagent(reag_id, reagents_add[reag_id]) /obj/item/seeds/Destroy() - for(var/thing in genes) - qdel(thing) - genes.Cut() + QDEL_LIST(genes) return ..() /obj/item/seeds/proc/Copy() diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index ae236b1ebd4..2041ca5f3e6 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -84,9 +84,12 @@ if("Captain", "Blueshield") suit=/obj/item/clothing/suit/space/eva/plasmaman/security/captain helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/captain - if("Head of Personnel", "Nanotrasen Representative") + if("Head of Personnel") suit=/obj/item/clothing/suit/space/eva/plasmaman/security/hop helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hop + if("Nanotrasen Representative") + suit = /obj/item/clothing/suit/space/eva/plasmaman/nt_rep + helm = /obj/item/clothing/head/helmet/space/eva/plasmaman/nt_rep if("Medical Doctor","Brig Physician") suit=/obj/item/clothing/suit/space/eva/plasmaman/medical helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index ce9fe15ae6e..e5a9d73e402 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -97,7 +97,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/head/griffin/(H), slot_head) var/obj/item/weapon/implant/freedom/L = new/obj/item/weapon/implant/freedom(H) - L.implant(H, H) + L.implant(H) /datum/superheroes/lightnian diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2b0ded32896..8ab82e7d9ca 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -41,6 +41,7 @@ var/list/robot_verbs_default = list( // Components are basically robot organs. var/list/components = list() + var/obj/item/robot_parts/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of.. var/obj/item/device/mmi/mmi = null var/obj/item/device/pda/silicon/robot/rbPDA = null @@ -255,6 +256,7 @@ var/list/robot_verbs_default = list( QDEL_NULL(module) QDEL_NULL(camera) QDEL_NULL(cell) + QDEL_NULL(robot_suit) return ..() /mob/living/silicon/robot/proc/pick_module() @@ -644,20 +646,13 @@ var/list/robot_verbs_default = list( else if(wiresexposed && wires.IsAllCut()) //Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob. if(!mmi) - to_chat(user, "\The [src] has no brain to remove.") + to_chat(user, "[src] has no brain to remove.") return - to_chat(user, "You jam the crowbar into the robot and begin levering [mmi].") + to_chat(user, "You jam the crowbar into the robot and begin levering the securing bolts.") if(do_after(user, 30 * W.toolspeed, target = src)) - to_chat(user, "You damage some parts of the chassis, but eventually manage to rip out [mmi]!") - var/obj/item/robot_parts/robot_suit/C = new/obj/item/robot_parts/robot_suit(loc) - C.l_leg = new/obj/item/robot_parts/l_leg(C) - C.r_leg = new/obj/item/robot_parts/r_leg(C) - C.l_arm = new/obj/item/robot_parts/l_arm(C) - C.r_arm = new/obj/item/robot_parts/r_arm(C) - C.updateicon() - new/obj/item/robot_parts/chest(loc) - qdel(src) + user.visible_message("[user] deconstructs [src]!", "You unfasten the securing bolts, and [src] falls to pieces!") + deconstruct() else // Okay we're not removing the cell or an MMI, but maybe something else? var/list/removable_components = list() @@ -1135,6 +1130,49 @@ var/list/robot_verbs_default = list( update_icons() +/mob/living/silicon/robot/proc/deconstruct() + var/turf/T = get_turf(src) + if(robot_suit) + robot_suit.forceMove(T) + robot_suit.l_leg.forceMove(T) + robot_suit.l_leg = null + robot_suit.r_leg.forceMove(T) + robot_suit.r_leg = null + new /obj/item/stack/cable_coil(T, robot_suit.chest.wired) + robot_suit.chest.forceMove(T) + robot_suit.chest.wired = FALSE + robot_suit.chest = null + robot_suit.l_arm.forceMove(T) + robot_suit.l_arm = null + robot_suit.r_arm.forceMove(T) + robot_suit.r_arm = null + robot_suit.head.forceMove(T) + robot_suit.head.flash1.forceMove(T) + robot_suit.head.flash1.burn_out() + robot_suit.head.flash1 = null + robot_suit.head.flash2.forceMove(T) + robot_suit.head.flash2.burn_out() + robot_suit.head.flash2 = null + robot_suit.head = null + robot_suit.updateicon() + else + new /obj/item/robot_parts/robot_suit(T) + new /obj/item/robot_parts/l_leg(T) + new /obj/item/robot_parts/r_leg(T) + new /obj/item/stack/cable_coil(T, 1) + new /obj/item/robot_parts/chest(T) + new /obj/item/robot_parts/l_arm(T) + new /obj/item/robot_parts/r_arm(T) + new /obj/item/robot_parts/head(T) + var/b + for(b=0, b!=2, b++) + var/obj/item/device/flash/F = new /obj/item/device/flash(T) + F.burn_out() + if(cell) //Sanity check. + cell.forceMove(T) + cell = null + qdel(src) + #define BORG_CAMERA_BUFFER 30 /mob/living/silicon/robot/Move(a, b, flag) var/oldLoc = src.loc diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 904762d6c27..ffd354961ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -58,15 +58,12 @@ /mob/living/simple_animal/hostile/poison/bees/Destroy() beegent = null + if(beehome) + if(beehome.bees) + beehome.bees.Remove(src) + beehome = null return ..() -/mob/living/simple_animal/hostile/poison/bees/death(gibbed) - beegent = null - ..() - -/mob/living/simple_animal/hostile/poison/bees/examine(mob/user) - ..() - /mob/living/simple_animal/hostile/poison/bees/proc/generate_bee_visuals() overlays.Cut() @@ -137,21 +134,6 @@ /mob/living/simple_animal/hostile/poison/bees/worker //Blank type define in case we need to give them special stuff later, plus organization (currently they are same as base type bee) - -/mob/living/simple_animal/hostile/poison/bees/worker/Destroy() - if(beehome) - if(beehome.bees) - beehome.bees.Remove(src) - beehome = null - return ..() - -/mob/living/simple_animal/hostile/poison/bees/worker/death(gibbed) - if(beehome) - if(beehome.bees) - beehome.bees.Remove(src) - beehome = null - ..() - /mob/living/simple_animal/hostile/poison/bees/worker/examine(mob/user) ..() @@ -313,6 +295,10 @@ beegent = new /datum/reagent/facid() //prepare to die var/list/master_and_friends = list() +/mob/living/simple_animal/hostile/poison/bees/syndi/Destroy() + master_and_friends.Cut() + return ..() + /mob/living/simple_animal/hostile/poison/bees/syndi/assign_reagent(datum/reagent/R) return diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 1df7348a839..911f66a5527 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -30,7 +30,7 @@ var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever) - + //typecache of things this mob will attack in DestroySurroundings() if it has environment_smash var/list/environment_target_typecache = list( /obj/machinery/door/window, @@ -44,15 +44,16 @@ var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such var/list/emote_taunt = list() var/taunt_chance = 0 - + /mob/living/simple_animal/hostile/New() ..() if(!targets_from) targets_from = src environment_target_typecache = typecacheof(environment_target_typecache) - + /mob/living/simple_animal/hostile/Destroy() targets_from = null + target = null return ..() /mob/living/simple_animal/hostile/Life() @@ -80,7 +81,7 @@ if(AIShouldSleep(possible_targets)) // we try to acquire a new one AIStatus = AI_IDLE // otherwise we go idle return 1 - + /mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user) if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client && user) FindTarget(list(user), 1) @@ -91,8 +92,8 @@ if(P.firer && get_dist(src, P.firer) <= aggro_vision_range) FindTarget(list(P.firer), 1) Goto(P.starting, move_to_delay, 3) - return ..() - + return ..() + //////////////HOSTILE MOB TARGETTING AND AGGRESSION//////////// @@ -126,7 +127,7 @@ var/Target = PickTarget(.) GiveTarget(Target) return Target //We now have a target - + /mob/living/simple_animal/hostile/proc/PossibleThreats() . = list() for(var/pos_targ in ListTargets()) @@ -176,24 +177,24 @@ if(faction_check && !attack_same) return 0 return 1 - + if(ishuman(the_target)) var/mob/living/carbon/human/H = the_target if(is_type_in_list(src, H.species.ignored_by)) return 0 - + if(istype(the_target, /obj/mecha)) var/obj/mecha/M = the_target if(M.occupant)//Just so we don't attack empty mechs if(CanAttack(M.occupant)) return 1 - + if(istype(the_target, /obj/spacepod)) var/obj/spacepod/S = the_target if(S.pilot) //Just so we don't attack empty pods if(CanAttack(S.pilot)) return 1 - + if(istype(the_target, /obj/machinery/porta_turret)) var/obj/machinery/porta_turret/P = the_target if(P.faction in faction) @@ -292,7 +293,7 @@ /mob/living/simple_animal/hostile/death(gibbed) LoseTarget() ..(gibbed) - + /mob/living/simple_animal/hostile/proc/summon_backup(distance) do_alert_animation(src) playsound(loc, 'sound/machines/chime.ogg', 50, 1, -1) diff --git a/code/modules/security_levels/security levels.dm b/code/modules/security_levels/security levels.dm index 0d25330177c..42bfb39b4eb 100644 --- a/code/modules/security_levels/security levels.dm +++ b/code/modules/security_levels/security levels.dm @@ -34,9 +34,9 @@ post_status("alert", "outline") - for(var/obj/machinery/firealarm/FA in world) + for(var/obj/machinery/firealarm/FA in machines) if(is_station_contact(FA.z)) - FA.overlays = list() + FA.overlays.Cut() FA.overlays += image('icons/obj/monitors.dmi', "overlay_green") if(SEC_LEVEL_BLUE) @@ -48,9 +48,9 @@ post_status("alert", "outline") - for(var/obj/machinery/firealarm/FA in world) + for(var/obj/machinery/firealarm/FA in machines) if(is_station_contact(FA.z)) - FA.overlays = list() + FA.overlays.Cut() FA.overlays += image('icons/obj/monitors.dmi', "overlay_blue") if(SEC_LEVEL_RED) @@ -60,16 +60,16 @@ security_announcement_down.Announce("The station's self-destruct mechanism has been deactivated, but there is still an immediate and serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.","Attention! Code Red!") security_level = SEC_LEVEL_RED - var/obj/machinery/door/airlock/highsecurity/red/R = locate(/obj/machinery/door/airlock/highsecurity/red) in world + var/obj/machinery/door/airlock/highsecurity/red/R = locate(/obj/machinery/door/airlock/highsecurity/red) in airlocks if(R && is_station_level(R.z)) R.locked = 0 R.update_icon() post_status("alert", "redalert") - for(var/obj/machinery/firealarm/FA in world) + for(var/obj/machinery/firealarm/FA in machines) if(is_station_contact(FA.z)) - FA.overlays = list() + FA.overlays.Cut() FA.overlays += image('icons/obj/monitors.dmi', "overlay_red") if(SEC_LEVEL_GAMMA) @@ -91,9 +91,9 @@ post_status("alert", "gammaalert") - for(var/obj/machinery/firealarm/FA in world) + for(var/obj/machinery/firealarm/FA in machines) if(is_station_contact(FA.z)) - FA.overlays = list() + FA.overlays.Cut() FA.overlays += image('icons/obj/monitors.dmi', "overlay_gamma") FA.update_icon() @@ -103,9 +103,9 @@ post_status("alert", "epsilonalert") - for(var/obj/machinery/firealarm/FA in world) + for(var/obj/machinery/firealarm/FA in machines) if(is_station_contact(FA.z)) - FA.overlays = list() + FA.overlays.Cut() FA.overlays += image('icons/obj/monitors.dmi', "overlay_epsilon") if(SEC_LEVEL_DELTA) @@ -114,9 +114,9 @@ post_status("alert", "deltaalert") - for(var/obj/machinery/firealarm/FA in world) + for(var/obj/machinery/firealarm/FA in machines) if(is_station_contact(FA.z)) - FA.overlays = list() + FA.overlays.Cut() FA.overlays += image('icons/obj/monitors.dmi', "overlay_delta") else diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index b952ddd0f79..498976c4635 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -291,7 +291,6 @@ user.visible_message("[user] places [I] into [case]!", "You place [I] into [case].") else qdel(I) - //target.sec_hud_set_implants() return 1 else user.visible_message(" [user] could not find anything inside [target]'s [affected.name], and pulls \the [tool] out.", \ diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index dd0c9655384..1af9e92b233 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -32,6 +32,14 @@ var/list/organ_cache = list() var/sterile = 0 //can the organ be infected by germs? var/tough = 0 //can organ be easily damaged? +/obj/item/organ/Destroy() + processing_objects.Remove(src) + if(owner) + remove(owner, 1) + QDEL_LIST_ASSOC_VAL(autopsy_data) + QDEL_NULL(dna) + return ..() + /obj/item/organ/proc/update_health() return diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 10f50cceaea..fa955c8ea98 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -71,11 +71,11 @@ /obj/item/organ/external/necrotize(update_sprite=TRUE) if(status & (ORGAN_ROBOT|ORGAN_DEAD)) return - to_chat(owner, "You can't feel your [name] anymore...") status |= ORGAN_DEAD if(dead_icon) icon_state = dead_icon if(owner) + to_chat(owner, "You can't feel your [name] anymore...") owner.update_body(update_sprite) owner.bad_external_organs |= src if(vital) @@ -85,6 +85,8 @@ if(parent && parent.children) parent.children -= src + parent = null + if(internal_organs) for(var/obj/item/organ/internal/O in internal_organs) internal_organs -= O @@ -102,6 +104,12 @@ deltimer(wound_cleanup_timer) wound_cleanup_timer = null + QDEL_LIST(wounds) + + QDEL_LIST(implants) + + QDEL_NULL(hidden) + return ..() /obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 6c775862373..7bea9c480af 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -15,11 +15,6 @@ if(istype(holder)) insert(holder) -/obj/item/organ/internal/Destroy() - if(owner) - remove(owner, 1) - return ..() - /obj/item/organ/internal/proc/insert(mob/living/carbon/M, special = 0, var/dont_remove_slot = 0) if(!iscarbon(M) || owner == M) return @@ -120,12 +115,6 @@ reagents.add_reagent("nutriment", 5) - -/obj/item/organ/internal/Destroy() - if(owner) - remove(owner, 1) - return ..() - /obj/item/organ/internal/attack(mob/living/carbon/M, mob/user) if(M == user && ishuman(user)) var/mob/living/carbon/human/H = user @@ -296,21 +285,18 @@ // . = ..() -/obj/item/organ/internal/lungs/process() +/obj/item/organ/internal/lungs/on_life() ..() - - if(!owner) - return if(germ_level > INFECTION_LEVEL_ONE) if(prob(5)) owner.emote("cough") //respitory tract infection if(is_bruised()) if(prob(2)) - spawn owner.custom_emote(1, "coughs up blood!") + owner.custom_emote(1, "coughs up blood!") owner.drip(10) if(prob(4)) - spawn owner.custom_emote(1, "gasps for air!") + owner.custom_emote(1, "gasps for air!") owner.AdjustLoseBreath(5) /obj/item/organ/internal/kidneys @@ -321,13 +307,8 @@ parent_organ = "groin" slot = "kidneys" -/obj/item/organ/internal/kidneys/process() - +/obj/item/organ/internal/kidneys/on_life() ..() - - if(!owner) - return - // Coffee is really bad for you with busted kidneys. // This should probably be expanded in some way, but fucked if I know // what else kidneys can process in our reagent list. @@ -439,12 +420,8 @@ slot = "liver" var/alcohol_intensity = 1 -/obj/item/organ/internal/liver/process() +/obj/item/organ/internal/liver/on_life() ..() - - if(!owner) - return - if(germ_level > INFECTION_LEVEL_ONE) if(prob(1)) to_chat(owner, " Your skin itches.") diff --git a/code/modules/surgery/organs/subtypes/misc.dm b/code/modules/surgery/organs/subtypes/misc.dm deleted file mode 100644 index be76fa907dc..00000000000 --- a/code/modules/surgery/organs/subtypes/misc.dm +++ /dev/null @@ -1,66 +0,0 @@ -//CORTICAL BORER ORGANS. -/obj/item/organ/internal/borer - name = "cortical borer" - icon = 'icons/obj/objects.dmi' - icon_state = "borer" - parent_organ = "head" - organ_tag = "brain" - slot = "borer" - vital = 1 - -/obj/item/organ/internal/borer/process() - - // Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss. - for(var/chem in list("saline", "sailcylic", "meth", "mannitol")) - if(owner.reagents.get_reagent_amount(chem) < 3) - owner.reagents.add_reagent(chem, 5) - - // They're also super gross and ooze ichor. - if(prob(5)) - var/mob/living/carbon/human/H = owner - if(!istype(H)) - return - - var/datum/reagent/blood/B = locate(/datum/reagent/blood) in H.vessel.reagent_list - blood_splatter(H,B,1) - var/obj/effect/decal/cleanable/blood/splatter/goo = locate() in get_turf(owner) - if(goo) - goo.name = "husk ichor" - goo.desc = "It's thick and stinks of decay." - goo.basecolor = "#412464" - goo.update_icon() - -/obj/item/organ/internal/borer/remove(var/mob/living/user) - - ..() - - var/mob/living/simple_animal/borer/B = owner.has_brain_worms() - if(B) - B.leave_host() - B.ckey = owner.ckey - - spawn(0) - qdel(src) - return null - -//VOX ORGANS. -/obj/item/organ/internal/stack - name = "cortical stack" - icon_state = "brain-prosthetic" - parent_organ = "head" - organ_tag = "stack" - slot = "vox_stack" - robotic = 2 - vital = 1 - var/backup_time = 0 - var/datum/mind/backup - -/obj/item/organ/internal/stack/process() - if(owner && owner.stat != 2 && !is_broken()) - backup_time = world.time - if(owner.mind) backup = owner.mind - -/obj/item/organ/internal/stack/vox - name = "vox cortical stack" - -/obj/item/organ/internal/stack/vox/stack diff --git a/code/modules/surgery/organs/subtypes/vox.dm b/code/modules/surgery/organs/subtypes/vox.dm index f0b94e2963e..bb56c41030d 100644 --- a/code/modules/surgery/organs/subtypes/vox.dm +++ b/code/modules/surgery/organs/subtypes/vox.dm @@ -1,3 +1,16 @@ /obj/item/organ/internal/liver/vox alcohol_intensity = 1.6 species = "Vox" + + +/obj/item/organ/internal/stack + name = "cortical stack" + icon_state = "brain-prosthetic" + parent_organ = "head" + organ_tag = "stack" + slot = "vox_stack" + robotic = 2 + vital = 1 + +/obj/item/organ/internal/stack/vox + name = "vox cortical stack" \ No newline at end of file diff --git a/html/changelog.html b/html/changelog.html index 2b604dcfcb2..56f7dd73502 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,41 @@ -->
+

07 May 2017

+

Twinmold updated:

+ + +

06 May 2017

+

Allfd updated:

+ +

Fethas updated:

+ +

LightFire69 updated:

+ +

uraniummeltdown updated:

+ + +

05 May 2017

+

Fethas updated:

+ +

01 May 2017

Fethas updated: