diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm
index 2fd9719eb45..3b4815b3533 100644
--- a/code/__defines/chemistry.dm
+++ b/code/__defines/chemistry.dm
@@ -49,7 +49,7 @@
// Chemistry lists.
var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") // Increase heart rate.
var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "bliss", "stoxin", "ambrosia_extract") // Decrease heart rate.
-var/list/heartstopper = list("potassium_chlorophoride", "zombie_powder") // This stops the heart.
+var/list/heartstopper = list("potassium_chlorophoride", "zombiepowder") // This stops the heart.
var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional
#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites
diff --git a/code/game/antagonist/station/highlander.dm b/code/game/antagonist/station/highlander.dm
index 9b54383278b..2e4885fd769 100644
--- a/code/game/antagonist/station/highlander.dm
+++ b/code/game/antagonist/station/highlander.dm
@@ -12,6 +12,8 @@ var/datum/antagonist/highlander/highlanders
initial_spawn_req = 3
initial_spawn_target = 5
+ id_type = /obj/item/weapon/card/id/centcom/ERT
+
/datum/antagonist/highlander/New()
..()
highlanders = src
@@ -32,26 +34,28 @@ var/datum/antagonist/highlander/highlanders
if(!..())
return
- for (var/obj/item/I in player)
- if (istype(I, /obj/item/weapon/implant))
- continue
- qdel(I)
-
+ // drop original items! It used to be a loop that just Qdeled everything including your organs!
+ // Dropping because of non-oxy breathers... That would suck wouldn't it?
+ player.drop_from_inventory(player.get_equipped_item(slot_wear_id))
+ player.drop_from_inventory(player.get_equipped_item(slot_wear_suit))
+ player.drop_from_inventory(player.get_equipped_item(slot_w_uniform))
+ player.drop_from_inventory(player.get_equipped_item(slot_l_ear))
+ player.drop_from_inventory(player.get_equipped_item(slot_head))
+ player.drop_from_inventory(player.get_equipped_item(slot_l_hand))
+ player.drop_from_inventory(player.get_equipped_item(slot_shoes))
+ player.drop_from_inventory(player.get_equipped_item(slot_l_store))
+ // highlanders!
player.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(player), slot_w_uniform)
- player.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(player), slot_l_ear)
player.equip_to_slot_or_del(new /obj/item/clothing/head/beret(player), slot_head)
player.equip_to_slot_or_del(new /obj/item/weapon/material/sword(player), slot_l_hand)
player.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots/combat(player), slot_shoes)
player.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(get_turf(player)), slot_l_store)
- var/obj/item/weapon/card/id/W = new(player)
- W.name = "[player.real_name]'s ID Card"
- W.icon_state = "centcom"
- W.access = get_all_station_access().Copy()
- W.access |= get_all_centcom_access()
- W.assignment = "Highlander"
- W.registered_name = player.real_name
- player.equip_to_slot_or_del(W, slot_wear_id)
+ var/obj/item/weapon/card/id/id = create_id("Highlander", player)
+ if(id)
+ id.access |= get_all_station_access()
+ id.icon_state = "centcom"
+ create_radio(DTH_FREQ, player)
/proc/only_one()
diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm
index 2927cb97860..c5e3af5b1a7 100644
--- a/code/game/objects/items/weapons/material/material_weapons.dm
+++ b/code/game/objects/items/weapons/material/material_weapons.dm
@@ -140,7 +140,7 @@
return
/obj/item/weapon/material/proc/sharpen(var/material, var/sharpen_time, var/kit, mob/living/M)
- if(!fragile)
+ if(!fragile && src.material.can_sharpen)
if(health < initial(health))
to_chat(M, "You should repair [src] first. Try using [kit] on it.")
return FALSE
diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm
index 1b58490012c..03b3b6f14cf 100644
--- a/code/game/turfs/flooring/flooring.dm
+++ b/code/game/turfs/flooring/flooring.dm
@@ -198,6 +198,17 @@ var/list/flooring_types
'sound/effects/footstep/mud3.ogg',
'sound/effects/footstep/mud4.ogg'))
+/decl/flooring/rock
+ name = "rocks"
+ desc = "Hard as a rock."
+ icon = 'icons/turf/outdoors.dmi'
+ icon_base = "rock"
+ footstep_sounds = list("human" = list(
+ 'sound/effects/footstep/LightStone1.ogg',
+ 'sound/effects/footstep/LightStone2.ogg',
+ 'sound/effects/footstep/LightStone3.ogg',
+ 'sound/effects/footstep/LightStone4.ogg'))
+
/decl/flooring/asteroid
name = "coarse sand"
desc = "You got a pebble in your shoe just looking at it."
diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm
index e55196aea6c..98d195001cd 100644
--- a/code/game/turfs/simulated/outdoors/outdoors.dm
+++ b/code/game/turfs/simulated/outdoors/outdoors.dm
@@ -123,6 +123,7 @@ var/list/turf_edge_cache = list()
desc = "Hard as a rock."
icon_state = "rock"
edge_blending_priority = 1
+ initial_flooring = /decl/flooring/rock
/turf/simulated/floor/outdoors/rocks/caves
outdoors = OUTDOORS_NO
@@ -185,4 +186,4 @@ var/list/turf_edge_cache = list()
icon = 'icons/turf/concrete.dmi'
icon_state = "concrete_dark"
desc = "Some sort of material composite road."
- edge_blending_priority = -1
\ No newline at end of file
+ edge_blending_priority = -1
diff --git a/code/modules/lore_codex/codex.dm b/code/modules/lore_codex/codex.dm
index 12fa8dbdfb1..71ec091dcb7 100644
--- a/code/modules/lore_codex/codex.dm
+++ b/code/modules/lore_codex/codex.dm
@@ -9,13 +9,21 @@
var/datum/codex_tree/tree = null
var/root_type = /datum/lore/codex/category/main_virgo_lore //Runtimes on codex_tree.dm, line 18 with a null here
+ var/static/list/codex_tree_keys = list() // static list linking codexes to the correct codex_tree.
+
/obj/item/weapon/book/codex/Initialize()
- tree = new(src, root_type)
+ tree = codex_tree_keys["[root_type]"]
+ if(!tree)
+ tree = new(src, root_type)
+ codex_tree_keys["[root_type]"] = tree
. = ..()
/obj/item/weapon/book/codex/attack_self(mob/user)
if(!tree)
- tree = new(src, root_type)
+ tree = codex_tree_keys["[root_type]"]
+ if(!tree)
+ tree = new(src, root_type)
+ codex_tree_keys["[root_type]"] = tree
icon_state = "[initial(icon_state)]-open"
tree.display(user)
diff --git a/code/modules/lore_codex/codex_tree.dm b/code/modules/lore_codex/codex_tree.dm
index 71aa80b0870..200a1ec4f09 100644
--- a/code/modules/lore_codex/codex_tree.dm
+++ b/code/modules/lore_codex/codex_tree.dm
@@ -4,9 +4,9 @@
var/atom/movable/holder = null
var/root_type = null
var/datum/lore/codex/home = null // Top-most page.
- var/datum/lore/codex/current_page = null // Current page or category to display to the user.
+ var/list/current_page = list() // Current page or category to display to the user. // converted to list to track multiple players.
var/list/indexed_pages = list() // Assoc list with search terms pointing to a ref of the page. It's created on New().
- var/list/history = list() // List of pages we previously visited.
+ var/list/history = list() // List of pages we previously visited. // now a 2D list
/datum/codex_tree/New(var/new_holder, var/new_root_type)
holder = new_holder
@@ -16,25 +16,31 @@
/datum/codex_tree/proc/generate_pages()
home = new root_type(src) // This will also generate the others.
- current_page = home
- indexed_pages = current_page.index_page()
+ //current_page = home
+ indexed_pages = home.index_page() // changed from current_page to home.
// Changes current_page to its parent, assuming one exists.
-/datum/codex_tree/proc/go_to_parent()
- if(current_page && current_page.parent)
- current_page = current_page.parent
+/datum/codex_tree/proc/go_to_parent(var/mob/user)
+ var/datum/lore/codex/D = current_page["[user]"]
+ if(istype(D) && D.parent)
+ current_page["[user]"] = D.parent
// Changes current_page to a specific page or category.
-/datum/codex_tree/proc/go_to_page(var/datum/lore/codex/new_page, var/dont_record_history = FALSE)
- if(new_page) // Make sure we're not going to a null page for whatever reason.
- current_page = new_page
+/datum/codex_tree/proc/go_to_page(var/datum/lore/codex/new_page, var/dont_record_history = FALSE, var/mob/user)
+ var/datum/lore/codex/D = current_page["[user]"]
+ if(new_page && istype(D)) // Make sure we're not going to a null page for whatever reason.
+ current_page["[user]"] = new_page
if(!dont_record_history)
- history.Add(new_page)
+ var/list/H = history["[user]"]
+ if(!H)
+ H = list()
+ H.Add(new_page)
+ history["[user]"] = H
-/datum/codex_tree/proc/quick_link(var/search_word)
+/datum/codex_tree/proc/quick_link(var/search_word, var/mob/user)
for(var/word in indexed_pages)
if(lowertext(search_word) == lowertext(word)) // Exact matches unfortunately limit our ability to perform SEOs.
- go_to_page(indexed_pages[word])
+ go_to_page(indexed_pages[word], FALSE, user)
return
/datum/codex_tree/proc/get_page_from_type(var/desired_type)
@@ -45,16 +51,26 @@
return null
// Returns to the last visited page, based on the history list.
-/datum/codex_tree/proc/go_back()
- if((history.len - 1) > 0)
- if(history[history.len] == current_page)
- history.len-- // This gets rid of the current page in the history.
- go_to_page(pop(history), dont_record_history = TRUE) // Where as this will get us the previous page that we want to go to.
+/datum/codex_tree/proc/go_back(var/mob/user)
+ var/list/H = history["[user]"]
+ var/datum/lore/codex/D = current_page["[user]"]
+ if(!LAZYLEN(H) || !istype(D))
+ return
+ if((H.len) > 1)
+ if(H[H.len] == D)
+ H.len-- // This gets rid of the current page in the history.
+ history["[user]"] = H
+ if(H.len == 1)
+ go_to_page(H[H.len], TRUE, user)
+ return
+ go_to_page(pop(history["[user]"]), TRUE, user) // Where as this will get us the previous page that we want to go to.
+ else
+ go_to_page(H[H.len], TRUE, user)
-/datum/codex_tree/proc/get_tree_position()
- if(current_page)
+/datum/codex_tree/proc/get_tree_position(var/mob/user)
+ var/datum/lore/codex/checked = current_page["[user]"]
+ if(istype(checked))
var/output = ""
- var/datum/lore/codex/checked = current_page
output = "[checked.name]"
while(checked.parent)
output = "[checked.parent.name] \> [output]"
@@ -75,38 +91,53 @@
/datum/codex_tree/proc/display(mob/user)
// icon_state = "[initial(icon_state)]-open"
- if(!current_page)
+ if(!home)
generate_pages()
+ if(!user)
+ return
+ var/datum/lore/codex/D = current_page["[user]"]
+ if(!istype(D)) // Initialize current_page and history
+ current_page["[user]"] = home
+ D = current_page["[user]"]
+ if(!istype(D))
+ log_debug("Codex_tree failed to failed to load for [user].")
+ return
+ var/list/H_init = list()
+ H_init.Add(home)
+ history["[user]"] = H_init
+ //if(!current_page)
+ //generate_pages()
user << browse_rsc('html/browser/codex.css', "codex.css")
var/dat
dat = "
"
- dat += "[holder.name] ([current_page.name])"
+ dat += "[holder.name] ([D.name])"
dat += ""
dat += ""
dat += ""
- dat += "[get_tree_position()] "
+ dat += "[get_tree_position(user)] "
dat += "[make_search_bar()] "
dat += "
"
- dat += "
[current_page.name]
"
+ dat += "
[D.name]
"
dat += " "
- if(current_page.data)
- dat += "[current_page.data] "
+ if(D.data)
+ dat += "[D.data] "
dat += " "
- if(istype(current_page, /datum/lore/codex/category))
+ if(istype(D, /datum/lore/codex/category))
dat += "
"
- var/datum/lore/codex/category/C = current_page
+ var/datum/lore/codex/category/C = D
for(var/datum/lore/codex/child in C.children)
dat += "[child.name]"
dat += "
"
dat += ""
- if(history.len - 1)
+ var/list/H = history["[user]"]
+ if(LAZYLEN(H))
dat += " \[Go Back\]"
- if(current_page.parent)
+ if(D.parent)
dat += " \[Go Up\]"
- if(current_page != home)
+ if(D != home)
dat += " \[Go To Home\]"
dat += "
"
user << browse(dat, "window=the_empress_protects;size=600x550")
@@ -120,21 +151,21 @@
if(href_list["target"]) // Direct link, using a ref
var/datum/lore/codex/new_page = locate(href_list["target"])
- go_to_page(new_page)
+ go_to_page(new_page, FALSE, usr)
else if(href_list["search_query"])
- quick_link(href_list["search_query"])
+ quick_link(href_list["search_query"], usr)
else if(href_list["go_to_parent"])
- go_to_parent()
+ go_to_parent(usr)
else if(href_list["go_back"])
- go_back()
+ go_back(usr)
else if(href_list["go_to_home"])
- go_to_page(home)
+ go_to_page(home, FALSE, usr)
else if(href_list["quick_link"]) // Indirect link, using a (hopefully) indexed word.
- quick_link(href_list["quick_link"])
+ quick_link(href_list["quick_link"], usr)
else if(href_list["close"])
// Close the book, if our holder is actually a book.
- if(istype(holder, /obj/item/weapon/book/codex))
- holder.icon_state = initial(holder.icon_state)
+ //if(istype(holder, /obj/item/weapon/book/codex))
+ //holder.icon_state = initial(holder.icon_state)
usr << browse(null, "window=the_empress_protects")
return
- display(usr)
\ No newline at end of file
+ display(usr)
diff --git a/code/modules/maps/tg/map_template.dm b/code/modules/maps/tg/map_template.dm
index 3e530206a4c..17f43d10292 100644
--- a/code/modules/maps/tg/map_template.dm
+++ b/code/modules/maps/tg/map_template.dm
@@ -9,8 +9,8 @@
var/annihilate = FALSE // If true, all (movable) atoms at the location where the map is loaded will be deleted before the map is loaded in.
var/fixed_orientation = FALSE // If true, the submap will not be rotated randomly when loaded.
- var/cost = null /* The map generator has a set 'budget' it spends to place down different submaps. It will pick available submaps randomly until
- it runs out. The cost of a submap should roughly corrispond with several factors such as size, loot, difficulty, desired scarcity, etc.
+ var/cost = null /* The map generator has a set 'budget' it spends to place down different submaps. It will pick available submaps randomly until
+ it runs out. The cost of a submap should roughly corrispond with several factors such as size, loot, difficulty, desired scarcity, etc.
Set to -1 to force the submap to always be made. */
var/allow_duplicates = FALSE // If false, only one map template will be spawned by the game. Doesn't affect admins spawning then manually.
var/discard_prob = 0 // If non-zero, there is a chance that the map seeding algorithm will skip this template when selecting potential templates to use.
@@ -74,7 +74,7 @@
A.power_change()
if(machinery_was_awake)
- SSmachines.wake() // Wake only if it was awake before we tried to suspended it.
+ SSmachines.wake() // Wake only if it was awake before we tried to suspended it.
SSshuttles.block_init_queue = prev_shuttle_queue_state
SSshuttles.process_init_queues() // We will flush the queue unless there were other blockers, in which case they will do it.
@@ -214,6 +214,12 @@
potential_submaps -= chosen_template
continue
+ // Is single use template already placed
+ if(!chosen_template.allow_duplicates && chosen_template.loaded)
+ priority_submaps -= chosen_template
+ potential_submaps -= chosen_template
+ continue
+
// Did we already place down a very similar submap?
if(chosen_template.template_group && (chosen_template.template_group in template_groups_used))
priority_submaps -= chosen_template
@@ -253,6 +259,13 @@
admin_notice("Submap \"[chosen_template.name]\" placed at ([T.x], [T.y], [T.z])\n", R_DEBUG)
+ if(specific_sanity < 0)
+ // I have no idea how this function has a race condition for the sanity check, but forcing the inner check loop to end like this fixes it...
+ // If a template doesn't allow duplicates, it tries to double place a template. this fixes that.
+ break
+ if(!chosen_template.allow_duplicates)
+ specific_sanity = -1 // force end the placement loop
+
// Do loading here.
chosen_template.load(T, centered = TRUE, orientation=orientation) // This is run before the main map's initialization routine, so that can initilize our submaps for us instead.
diff --git a/code/modules/materials/materials/_materials.dm b/code/modules/materials/materials/_materials.dm
index fba60dda059..1e1fec8a2d0 100644
--- a/code/modules/materials/materials/_materials.dm
+++ b/code/modules/materials/materials/_materials.dm
@@ -213,6 +213,7 @@ var/list/name_to_material
var/luminescence
var/radiation_resistance = 0 // Radiation resistance, which is added on top of a material's weight for blocking radiation. Needed to make lead special without superrobust weapons.
var/supply_conversion_value // Supply points per sheet that this material sells for.
+ var/can_sharpen = TRUE // Is this material compatible with a sharpening kit?
// Placeholder vars for the time being, todo properly integrate windows/light tiles/rods.
var/created_window
diff --git a/code/modules/materials/materials/plastic.dm b/code/modules/materials/materials/plastic.dm
index d10e5153f6b..b31ed2cb736 100644
--- a/code/modules/materials/materials/plastic.dm
+++ b/code/modules/materials/materials/plastic.dm
@@ -108,4 +108,5 @@
hardness = 1
weight = 1
protectiveness = 0 // 0%
- conductive = 0
\ No newline at end of file
+ conductive = 0
+ can_sharpen = FALSE
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index e7722cff392..51911e23a91 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -407,6 +407,11 @@
O.organ_tag = organ_tag
H.internal_organs_by_name[organ_tag] = O
+ // set butcherable meats from species
+ for(var/obj/item/organ/O in H.organs)
+ O.set_initial_meat()
+ for(var/obj/item/organ/O in H.internal_organs)
+ O.set_initial_meat()
/datum/species/proc/hug(var/mob/living/carbon/human/H, var/mob/living/target)
@@ -570,4 +575,3 @@
/datum/species/proc/post_spawn_special(mob/living/carbon/human/H)
return
-
diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm
index f297317a27f..a7a9386c394 100644
--- a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm
+++ b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm
@@ -331,7 +331,7 @@
var/burncolor = (patient.getFireLoss() < 60 ? "color:gray;" : "color:red;")
dat += "\t-Pulse, bpm: [patient.get_pulse(GETPULSE_TOOL)] "
- dat += "\t-Overall Health %: [round(patient.health)] "
+ dat += "\t-Overall Health %: [round(100 * (patient.health / patient.getMaxHealth()))] "
dat += "\t-Brute Damage %: [patient.getBruteLoss()] "
dat += "\t-Respiratory Damage %: [patient.getOxyLoss()] "
dat += "\t-Toxin Content %: [patient.getToxLoss()] "
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index ec117338fa6..621e875df64 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -114,8 +114,7 @@ var/list/organ_cache = list()
handle_organ_mod_special()
-/obj/item/organ/Initialize()
- . = ..()
+/obj/item/organ/proc/set_initial_meat()
if(owner)
if(!meat_type)
if(owner.isSynthetic())
@@ -394,7 +393,7 @@ var/list/organ_cache = list()
var/obj/item/organ/external/affected = owner.get_organ(parent_organ)
if(affected) affected.internal_organs -= src
- forceMove(owner.drop_location())
+ owner.remove_from_mob(src, owner.drop_location())
START_PROCESSING(SSobj, src)
rejecting = null
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 4a79eb64a83..94dea567779 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -234,9 +234,9 @@ var/global/photo_count = 0
holding = "They are holding \a [A.r_hand]"
if(!mob_detail)
- mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
+ mob_detail = "You can see [A] on the photo[(A:health / A.getMaxHealth()) < 0.75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. "
else
- mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
+ mob_detail += "You can also see [A] on the photo[(A:health / A.getMaxHealth()) < 0.75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]."
return mob_detail
diff --git a/code/modules/pda/core_apps.dm b/code/modules/pda/core_apps.dm
index f45f6d5e70f..960978b94d0 100644
--- a/code/modules/pda/core_apps.dm
+++ b/code/modules/pda/core_apps.dm
@@ -46,16 +46,26 @@
icon = "sticky-note-o"
template = "pda_notekeeper"
+ var/greeted = FALSE
var/note = null
+ var/notetitle = null
+ var/currentnote = 1
+ var/list/storedtitles = list("","","","","","","","","","","","")
+ var/list/storednotes = list("","","","","","","","","","","","")
var/notehtml = ""
/datum/data/pda/app/notekeeper/start()
. = ..()
- if(!note)
- note = "Congratulations, your station has chosen the [pda.model_name]!"
+ if(!note && greeted == FALSE)
+
+ // display greeting!
+ greeted = TRUE
+ note = "Your station has chosen the [pda.model_name]!"
+ notetitle = "Congratulations!"
/datum/data/pda/app/notekeeper/update_ui(mob/user as mob, list/data)
data["note"] = note // current pda notes
+ data["notename"] = "Note [alphabet_uppercase[currentnote]] : [notetitle]"
/datum/data/pda/app/notekeeper/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
@@ -70,6 +80,126 @@
else
pda.close(usr)
return TRUE
+ if("Titleset")
+ var/n = tgui_input_text(usr, "Please enter title", name, notetitle, multiline = FALSE)
+ if(pda.loc == usr)
+ notetitle = adminscrub(n)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Print")
+ if(pda.loc == usr)
+ printnote()
+ else
+ pda.close(usr)
+ return TRUE
+ // dumb way to do this, but i don't know how to easily parse this without a lot of silly code outside the switch!
+ if("Note1")
+ if(pda.loc == usr)
+ changetonote(1)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note2")
+ if(pda.loc == usr)
+ changetonote(2)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note3")
+ if(pda.loc == usr)
+ changetonote(3)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note4")
+ if(pda.loc == usr)
+ changetonote(4)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note5")
+ if(pda.loc == usr)
+ changetonote(5)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note6")
+ if(pda.loc == usr)
+ changetonote(6)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note7")
+ if(pda.loc == usr)
+ changetonote(7)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note8")
+ if(pda.loc == usr)
+ changetonote(8)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note9")
+ if(pda.loc == usr)
+ changetonote(9)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note10")
+ if(pda.loc == usr)
+ changetonote(10)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note11")
+ if(pda.loc == usr)
+ changetonote(11)
+ else
+ pda.close(usr)
+ return TRUE
+ if("Note12")
+ if(pda.loc == usr)
+ changetonote(12)
+ else
+ pda.close(usr)
+ return TRUE
+
+/datum/data/pda/app/notekeeper/proc/printnote()
+ // get active hand of person holding PDA, and print the page to the paper in it
+ if(istype( usr, /mob/living/carbon/human ))
+ var/mob/living/carbon/human/H = usr
+ var/obj/item/I = H.get_active_hand()
+ if(istype(I,/obj/item/weapon/paper))
+ var/obj/item/weapon/paper/P = I
+ if(isnull(P.info) || P.info == "" )
+ var/titlenote = "Note [alphabet_uppercase[currentnote]]"
+ if(!isnull(notetitle) && notetitle != "")
+ titlenote = notetitle
+ to_chat(usr, "Successfully printed [titlenote]!")
+ P.set_content( pencode2html(note), titlenote)
+ else
+ to_chat(usr, "You can only print to empty paper!")
+ else
+ to_chat(usr, "You must be holding paper for the pda to print to!")
+
+
+/datum/data/pda/app/notekeeper/proc/changetonote(var/noteindex)
+ // save note to current slot, then load another slot
+ storednotes[currentnote] = note
+ storedtitles[currentnote] = notetitle
+
+ currentnote = noteindex
+
+ note = storednotes[currentnote]
+ notetitle = storedtitles[currentnote]
+
+ // update text on keeper, silly swapping!
+ note = replacetext(note, " ", "\n")
+ notehtml = html_decode(note)
+ note = replacetext(note, "\n", " ")
/datum/data/pda/app/manifest
name = "Crew Manifest"
diff --git a/code/modules/pda/utilities.dm b/code/modules/pda/utilities.dm
index 36ef40a8006..65c2484378c 100644
--- a/code/modules/pda/utilities.dm
+++ b/code/modules/pda/utilities.dm
@@ -178,11 +178,18 @@
if(length(notes.note) > 0)
notes.note += "
"
// Store the scanned document to the notes
- notes.note += "Scanned Document. Edit to restore previous notes/delete scan. ---------- " + formatted_scan + " "
- // notehtml ISN'T set to allow user to get their old notes back. A better implementation would add a "scanned documents"
- // feature to the PDA, which would better convey the availability of the feature, but this will work for now.
+ notes.note = formatted_scan
+ notes.notetitle = sanitize_simple(P.name, list("\n" = "", "\t" = "", "ΓΏ" = ""))
+ // update the saved note too incase we kept the pda open, this is really silly due to how the notehtml is actually what's passed to the editor's text.
+ // If I don't update it here, it loses the data when you edit it!
+ notes.storednotes[notes.currentnote] = notes.note
+ notes.storedtitles[notes.currentnote] = notes.notetitle
+ notes.notehtml = html_decode(replacetext(notes.note," ", "\n"))
// Inform the user
- to_chat(user, "Paper scanned and OCRed to notekeeper.")//concept of scanning paper copyright brainoblivion 2009
+ var/scannedtitle = "Paper"
+ if(!isnull(notes.notetitle) && notes.notetitle != "")
+ scannedtitle = "'[notes.notetitle]'"
+ to_chat(user, "[scannedtitle] scanned to Notekeeper in note [alphabet_uppercase[notes.currentnote]].")//concept of scanning paper copyright brainoblivion 2009
else
to_chat(user, "Error scanning [A].")
diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm
index 7f30e02966b..ce696745223 100644
--- a/code/modules/power/singularity/particle_accelerator/particle.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle.dm
@@ -7,6 +7,7 @@
icon_state = "particle1"//Need a new icon for this
anchored = TRUE
density = TRUE
+ movement_type = UNSTOPPABLE // for bumps to trigger
var/movement_range = 10
var/energy = 10 //energy in eV
var/mega_energy = 0 //energy in MeV
diff --git a/code/modules/power/singularity/particle_accelerator/particle_emitter.dm b/code/modules/power/singularity/particle_accelerator/particle_emitter.dm
index 0a82e480d6b..292900b4197 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_emitter.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_emitter.dm
@@ -31,7 +31,7 @@
if((last_shot + fire_delay) <= world.time)
last_shot = world.time
var/obj/effect/accelerated_particle/A = null
- var/turf/T = get_step(src,dir)
+ var/turf/T = src.loc // if it doesn't spawn here, it won't bump stuff directly infront of the PA
switch(strength)
if(0)
A = new/obj/effect/accelerated_particle/weak(T, dir)
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index ac02254e2c1..75bb9a1d153 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -111,6 +111,8 @@
spawn(1) // slight delay to prevent infinite propagation due to map order //TODO: please no spawn() in process(). It's a very bad idea
var/items_moved = 0
for(var/atom/movable/A in affecting)
+ if(istype(A,/obj/effect/abstract)) // Flashlight's lights are not physical objects
+ continue
if(!A.anchored)
if(A.loc == src.loc) // prevents the object from being affected if it's not currently here.
step(A,movedir)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index dfbf624cf56..ef806bb3fbb 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -20,6 +20,8 @@
// CHEST INTERNAL ORGAN SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/internal/fix_organ
+ surgery_name = "Dress Organ"
+
allowed_tools = list(
/obj/item/stack/medical/advanced/bruise_pack= 100, \
/obj/item/stack/medical/bruise_pack = 20
@@ -114,6 +116,8 @@
//Robo internal organ fix. For when an organic has robotic limbs.
/datum/surgery_step/fix_organic_organ_robotic //For artificial organs
+ surgery_name = "Mend Organ"
+
allowed_tools = list(
/obj/item/stack/nanopaste = 100,
/obj/item/stack/cable_coil = 75,
@@ -187,6 +191,7 @@
///////////////////////////////////////////////////////////////
/datum/surgery_step/internal/detatch_organ/
+ surgery_name = "Detatch Organ"
allowed_tools = list(
/obj/item/weapon/surgical/scalpel = 100, \
@@ -329,6 +334,7 @@
///////////////////////////////////////////////////////////////
/datum/surgery_step/internal/replace_organ
+ surgery_name = "Replace Organ"
allowed_tools = list(
/obj/item/organ = 100
)
@@ -408,6 +414,7 @@
///////////////////////////////////////////////////////////////
/datum/surgery_step/internal/attach_organ
+ surgery_name = "Attach Organ"
allowed_tools = list(
/obj/item/weapon/surgical/FixOVein = 100, \
/obj/item/stack/cable_coil = 75
diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm
index d1ebb0e4c76..dceba741670 100644
--- a/code/modules/vore/eating/living_vr.dm
+++ b/code/modules/vore/eating/living_vr.dm
@@ -496,6 +496,11 @@
else if(tf_mob_holder)
log_and_message_admins("[key_name(src)] used the OOC escape button to revert back to their original form from being TFed into another mob.")
revert_mob_tf()
+
+ else if(istype(loc, /obj/item/weapon/holder/micro) && (istype(loc.loc, /obj/machinery/microwave)))
+ forceMove(get_turf(src))
+ log_and_message_admins("[key_name(src)] used the OOC escape button to get out of a microwave.")
+
//Don't appear to be in a vore situation
else
to_chat(src,"You aren't inside anyone, though, is the thing.")
diff --git a/tgui/packages/tgui/interfaces/pda/pda_notekeeper.jsx b/tgui/packages/tgui/interfaces/pda/pda_notekeeper.jsx
index c0af68c3706..1e9356e4c6b 100644
--- a/tgui/packages/tgui/interfaces/pda/pda_notekeeper.jsx
+++ b/tgui/packages/tgui/interfaces/pda/pda_notekeeper.jsx
@@ -1,21 +1,126 @@
/* eslint react/no-danger: "off" */
import { useBackend } from '../../backend';
-import { Box, Button, Section } from '../../components';
+import { Box, Button, Section, Table } from '../../components';
export const pda_notekeeper = (props) => {
const { act, data } = useBackend();
- const { note } = data;
+ const { note, notename } = data;
return (
+
+ {/* Lets just be nice and lazy with this, multinote support!. */}
+
+
+
+
{/* As usual with dangerouslySetInnerHTML,
this notekeeper was designed to use HTML injection.
Fix when markdown is easier. */}
- act('Edit')} content="Edit Notes" />
);
};