diff --git a/baystation12.dme b/baystation12.dme
index 3dc5369865..ce1f5b27c0 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -601,7 +601,6 @@
#include "code\game\objects\items\stacks\nanopaste.dm"
#include "code\game\objects\items\stacks\rods.dm"
#include "code\game\objects\items\stacks\stack.dm"
-#include "code\game\objects\items\stacks\sheets\glass.dm"
#include "code\game\objects\items\stacks\sheets\leather.dm"
#include "code\game\objects\items\stacks\sheets\light.dm"
#include "code\game\objects\items\stacks\tiles\light.dm"
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index cfbd155145..fac5c75fc3 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -29,7 +29,7 @@
*/
-datum/mind
+/datum/mind
var/key
var/name //replaces mob/var/original_name
var/mob/living/current
@@ -58,459 +58,389 @@ datum/mind
// the world.time since the mob has been brigged, or -1 if not at all
var/brigged_since = -1
- New(var/key)
- src.key = key
-
//put this here for easier tracking ingame
var/datum/money_account/initial_account
- proc/transfer_to(mob/living/new_character)
- if(!istype(new_character))
- world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn"
- if(current) //remove ourself from our old body's mind variable
- if(changeling)
- current.remove_changeling_powers()
- current.verbs -= /datum/changeling/proc/EvolutionMenu
- current.mind = null
+/datum/mind/New(var/key)
+ src.key = key
- nanomanager.user_transferred(current, new_character) // transfer active NanoUI instances to new user
- if(new_character.mind) //remove any mind currently in our new body's mind variable
- new_character.mind.current = null
-
- current = new_character //link ourself to our new body
- new_character.mind = src //and link our new body to ourself
+/datum/mind/proc/transfer_to(mob/living/new_character)
+ if(!istype(new_character))
+ world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn"
+ if(current) //remove ourself from our old body's mind variable
if(changeling)
- new_character.make_changeling()
+ current.remove_changeling_powers()
+ current.verbs -= /datum/changeling/proc/EvolutionMenu
+ current.mind = null
- if(active)
- new_character.key = key //now transfer the key to link the client to our new body
+ nanomanager.user_transferred(current, new_character) // transfer active NanoUI instances to new user
+ if(new_character.mind) //remove any mind currently in our new body's mind variable
+ new_character.mind.current = null
- proc/store_memory(new_text)
- memory += "[new_text]
"
+ current = new_character //link ourself to our new body
+ new_character.mind = src //and link our new body to ourself
- proc/show_memory(mob/recipient)
- var/output = "[current.real_name]'s Memory
"
- output += memory
+ if(changeling)
+ new_character.make_changeling()
- if(objectives.len>0)
- output += "
Objectives:"
+ if(active)
+ new_character.key = key //now transfer the key to link the client to our new body
- var/obj_count = 1
- for(var/datum/objective/objective in objectives)
- output += "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+/datum/mind/proc/store_memory(new_text)
+ memory += "[new_text]
"
- recipient << browse(output,"window=memory")
+/datum/mind/proc/show_memory(mob/recipient)
+ var/output = "[current.real_name]'s Memory
"
+ output += memory
- proc/edit_memory()
- if(!ticker || !ticker.mode)
- alert("Not before round-start!", "Alert")
- return
+ if(objectives.len>0)
+ output += "
Objectives:"
- var/out = "[name][(current&&(current.real_name!=name))?" (as [current.real_name])":""]
"
- out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
"
- out += "Assigned role: [assigned_role]. Edit
"
- out += "
"
- out += "Factions and special roles:
"
- for(var/antag_type in all_antag_types)
- var/datum/antagonist/antag = all_antag_types[antag_type]
- out += "[antag.get_panel_entry(src)]"
- out += "
"
- out += "Objectives"
+ var/obj_count = 1
+ for(var/datum/objective/objective in objectives)
+ output += "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
- if(objectives && objectives.len)
- var/num = 1
- for(var/datum/objective/O in objectives)
- out += "Objective #[num]: [O.explanation_text] "
- if(O.completed)
- out += "(complete)"
- else
- out += "(incomplete)"
- out += " \[toggle\]"
- out += " \[remove\]
"
- num++
- out += "
\[announce objectives\]"
+ recipient << browse(output,"window=memory")
- else
- out += "None."
- out += "
\[add\]"
- usr << browse(out, "window=edit_memory[src]")
+/datum/mind/proc/edit_memory()
+ if(!ticker || !ticker.mode)
+ alert("Not before round-start!", "Alert")
+ return
- Topic(href, href_list)
- if(!check_rights(R_ADMIN)) return
+ var/out = "[name][(current&&(current.real_name!=name))?" (as [current.real_name])":""]
"
+ out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
"
+ out += "Assigned role: [assigned_role]. Edit
"
+ out += "
"
+ out += "Factions and special roles:
"
+ for(var/antag_type in all_antag_types)
+ var/datum/antagonist/antag = all_antag_types[antag_type]
+ out += "[antag.get_panel_entry(src)]"
+ out += "
"
+ out += "Objectives"
- if(href_list["add_antagonist"])
- var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]]
- if(antag) antag.add_antagonist(src)
-
- else if(href_list["remove_antagonist"])
- var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]]
- if(antag) antag.remove_antagonist(src)
-
- else if(href_list["equip_antagonist"])
- var/datum/antagonist/antag = all_antag_types[href_list["equip_antagonist"]]
- if(antag) antag.equip(src.current)
-
- else if(href_list["unequip_antagonist"])
- var/datum/antagonist/antag = all_antag_types[href_list["unequip_antagonist"]]
- if(antag) antag.unequip(src.current)
-
- else if(href_list["move_antag_to_spawn"])
- var/datum/antagonist/antag = all_antag_types[href_list["move_antag_to_spawn"]]
- if(antag) antag.place_mob(src.current)
-
- else if (href_list["role_edit"])
- var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in joblist
- if (!new_role) return
- assigned_role = new_role
-
- else if (href_list["memory_edit"])
- var/new_memo = sanitize(input("Write new memory", "Memory", memory) as null|message)
- if (isnull(new_memo)) return
- memory = new_memo
-
- else if (href_list["obj_edit"] || href_list["obj_add"])
- var/datum/objective/objective
- var/objective_pos
- var/def_value
-
- if (href_list["obj_edit"])
- objective = locate(href_list["obj_edit"])
- if (!objective) return
- objective_pos = objectives.Find(objective)
-
- //Text strings are easy to manipulate. Revised for simplicity.
- var/temp_obj_type = "[objective.type]"//Convert path into a text string.
- def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword.
- if(!def_value)//If it's a custom objective, it will be an empty string.
- def_value = "custom"
-
- var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "mercenary", "capture", "absorb", "custom")
- if (!new_obj_type) return
-
- var/datum/objective/new_objective = null
-
- switch (new_obj_type)
- if ("assassinate","protect","debrain", "harm", "brig")
- //To determine what to name the objective in explanation text.
- var/objective_type_capital = uppertext(copytext(new_obj_type, 1,2))//Capitalize first letter.
- var/objective_type_text = copytext(new_obj_type, 2)//Leave the rest of the text.
- var/objective_type = "[objective_type_capital][objective_type_text]"//Add them together into a text string.
-
- var/list/possible_targets = list("Free objective")
- for(var/datum/mind/possible_target in ticker.minds)
- if ((possible_target != src) && istype(possible_target.current, /mob/living/carbon/human))
- possible_targets += possible_target.current
-
- var/mob/def_target = null
- var/objective_list[] = list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain)
- if (objective&&(objective.type in objective_list) && objective:target)
- def_target = objective:target.current
-
- var/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
- if (!new_target) return
-
- var/objective_path = text2path("/datum/objective/[new_obj_type]")
- if (new_target == "Free objective")
- new_objective = new objective_path
- new_objective.owner = src
- new_objective:target = null
- new_objective.explanation_text = "Free objective"
- else
- new_objective = new objective_path
- new_objective.owner = src
- new_objective:target = new_target:mind
- //Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
- new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role=="MODE" ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]."
-
- if ("prevent")
- new_objective = new /datum/objective/block
- new_objective.owner = src
-
- if ("hijack")
- new_objective = new /datum/objective/hijack
- new_objective.owner = src
-
- if ("escape")
- new_objective = new /datum/objective/escape
- new_objective.owner = src
-
- if ("survive")
- new_objective = new /datum/objective/survive
- new_objective.owner = src
-
- if ("mercenary")
- new_objective = new /datum/objective/nuclear
- new_objective.owner = src
-
- if ("steal")
- if (!istype(objective, /datum/objective/steal))
- new_objective = new /datum/objective/steal
- new_objective.owner = src
- else
- new_objective = objective
- var/datum/objective/steal/steal = new_objective
- if (!steal.select_target())
- return
-
- if("download","capture","absorb")
- var/def_num
- if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
- def_num = objective.target_amount
-
- var/target_number = input("Input target number:", "Objective", def_num) as num|null
- if (isnull(target_number))//Ordinarily, you wouldn't need isnull. In this case, the value may already exist.
- return
-
- switch(new_obj_type)
- if("download")
- new_objective = new /datum/objective/download
- new_objective.explanation_text = "Download [target_number] research levels."
- if("capture")
- new_objective = new /datum/objective/capture
- new_objective.explanation_text = "Accumulate [target_number] capture points."
- if("absorb")
- new_objective = new /datum/objective/absorb
- new_objective.explanation_text = "Absorb [target_number] compatible genomes."
- new_objective.owner = src
- new_objective.target_amount = target_number
-
- if ("custom")
- var/expl = sanitize(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null)
- if (!expl) return
- new_objective = new /datum/objective
- new_objective.owner = src
- new_objective.explanation_text = expl
-
- if (!new_objective) return
-
- if (objective)
- objectives -= objective
- objectives.Insert(objective_pos, new_objective)
+ if(objectives && objectives.len)
+ var/num = 1
+ for(var/datum/objective/O in objectives)
+ out += "Objective #[num]: [O.explanation_text] "
+ if(O.completed)
+ out += "(complete)"
else
- objectives += new_objective
+ out += "(incomplete)"
+ out += " \[toggle\]"
+ out += " \[remove\]
"
+ num++
+ out += "
\[announce objectives\]"
- else if (href_list["obj_delete"])
- var/datum/objective/objective = locate(href_list["obj_delete"])
- if(!istype(objective)) return
- objectives -= objective
+ else
+ out += "None."
+ out += "
\[add\]"
+ usr << browse(out, "window=edit_memory[src]")
- else if(href_list["obj_completed"])
- var/datum/objective/objective = locate(href_list["obj_completed"])
- if(!istype(objective)) return
- objective.completed = !objective.completed
+/datum/mind/Topic(href, href_list)
+ if(!check_rights(R_ADMIN)) return
- else if(href_list["implant"])
- var/mob/living/carbon/human/H = current
+ if(href_list["add_antagonist"])
+ var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]]
+ if(antag) antag.add_antagonist(src)
- BITSET(H.hud_updateflag, IMPLOYAL_HUD) // updates that players HUD images so secHUD's pick up they are implanted or not.
+ else if(href_list["remove_antagonist"])
+ var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]]
+ if(antag) antag.remove_antagonist(src)
- switch(href_list["implant"])
- if("remove")
- for(var/obj/item/weapon/implant/loyalty/I in H.contents)
- for(var/obj/item/organ/external/organs in H.organs)
- if(I in organs.implants)
- qdel(I)
- break
- H << "Your loyalty implant has been deactivated."
- log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].")
- if("add")
- H << "You somehow have become the recepient of a loyalty transplant, and it just activated!"
- H.implant_loyalty(H, override = TRUE)
- log_admin("[key_name_admin(usr)] has loyalty implanted [current].")
+ else if(href_list["equip_antagonist"])
+ var/datum/antagonist/antag = all_antag_types[href_list["equip_antagonist"]]
+ if(antag) antag.equip(src.current)
+
+ else if(href_list["unequip_antagonist"])
+ var/datum/antagonist/antag = all_antag_types[href_list["unequip_antagonist"]]
+ if(antag) antag.unequip(src.current)
+
+ else if(href_list["move_antag_to_spawn"])
+ var/datum/antagonist/antag = all_antag_types[href_list["move_antag_to_spawn"]]
+ if(antag) antag.place_mob(src.current)
+
+ else if (href_list["role_edit"])
+ var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in joblist
+ if (!new_role) return
+ assigned_role = new_role
+
+ else if (href_list["memory_edit"])
+ var/new_memo = sanitize(input("Write new memory", "Memory", memory) as null|message)
+ if (isnull(new_memo)) return
+ memory = new_memo
+
+ else if (href_list["obj_edit"] || href_list["obj_add"])
+ var/datum/objective/objective
+ var/objective_pos
+ var/def_value
+
+ if (href_list["obj_edit"])
+ objective = locate(href_list["obj_edit"])
+ if (!objective) return
+ objective_pos = objectives.Find(objective)
+
+ //Text strings are easy to manipulate. Revised for simplicity.
+ var/temp_obj_type = "[objective.type]"//Convert path into a text string.
+ def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword.
+ if(!def_value)//If it's a custom objective, it will be an empty string.
+ def_value = "custom"
+
+ var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "mercenary", "capture", "absorb", "custom")
+ if (!new_obj_type) return
+
+ var/datum/objective/new_objective = null
+
+ switch (new_obj_type)
+ if ("assassinate","protect","debrain", "harm", "brig")
+ //To determine what to name the objective in explanation text.
+ var/objective_type_capital = uppertext(copytext(new_obj_type, 1,2))//Capitalize first letter.
+ var/objective_type_text = copytext(new_obj_type, 2)//Leave the rest of the text.
+ var/objective_type = "[objective_type_capital][objective_type_text]"//Add them together into a text string.
+
+ var/list/possible_targets = list("Free objective")
+ for(var/datum/mind/possible_target in ticker.minds)
+ if ((possible_target != src) && istype(possible_target.current, /mob/living/carbon/human))
+ possible_targets += possible_target.current
+
+ var/mob/def_target = null
+ var/objective_list[] = list(/datum/objective/assassinate, /datum/objective/protect, /datum/objective/debrain)
+ if (objective&&(objective.type in objective_list) && objective:target)
+ def_target = objective:target.current
+
+ var/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets
+ if (!new_target) return
+
+ var/objective_path = text2path("/datum/objective/[new_obj_type]")
+ if (new_target == "Free objective")
+ new_objective = new objective_path
+ new_objective.owner = src
+ new_objective:target = null
+ new_objective.explanation_text = "Free objective"
else
- /*
- else if (href_list["monkey"])
- var/mob/living/L = current
- if (L.monkeyizing)
- return
- switch(href_list["monkey"])
- if("healthy")
- if (usr.client.holder.rights & R_ADMIN)
- var/mob/living/carbon/human/H = current
- var/mob/living/carbon/monkey/M = current
- if (istype(H))
- log_admin("[key_name(usr)] attempting to monkeyize [key_name(current)]")
- message_admins("\blue [key_name_admin(usr)] attempting to monkeyize [key_name_admin(current)]")
- src = null
- M = H.monkeyize()
- src = M.mind
- //world << "DEBUG: \"healthy\": M=[M], M.mind=[M.mind], src=[src]!"
- else if (istype(M) && length(M.viruses))
- for(var/datum/disease/D in M.viruses)
- D.cure(0)
- sleep(0) //because deleting of virus is done through spawn(0)
- if("infected")
- if (usr.client.holder.rights & R_ADMIN)
- var/mob/living/carbon/human/H = current
- var/mob/living/carbon/monkey/M = current
- if (istype(H))
- log_admin("[key_name(usr)] attempting to monkeyize and infect [key_name(current)]")
- message_admins("\blue [key_name_admin(usr)] attempting to monkeyize and infect [key_name_admin(current)]", 1)
- src = null
- M = H.monkeyize()
- src = M.mind
- current.contract_disease(new /datum/disease/jungle_fever,1,0)
- else if (istype(M))
- current.contract_disease(new /datum/disease/jungle_fever,1,0)
- if("human")
- var/mob/living/carbon/monkey/M = current
- if (istype(M))
- for(var/datum/disease/D in M.viruses)
- if (istype(D,/datum/disease/jungle_fever))
- D.cure(0)
- sleep(0) //because deleting of virus is doing throught spawn(0)
- log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
- message_admins("\blue [key_name_admin(usr)] attempting to humanize [key_name_admin(current)]")
- var/obj/item/weapon/dnainjector/m2h/m2h = new
- var/obj/item/weapon/implant/mobfinder = new(M) //hack because humanizing deletes mind --rastaf0
- src = null
- m2h.inject(M)
- src = mobfinder.loc:mind
- qdel(mobfinder)
- current.radiation -= 50
- */
- else if (href_list["silicon"])
- BITSET(current.hud_updateflag, SPECIALROLE_HUD)
- switch(href_list["silicon"])
+ new_objective = new objective_path
+ new_objective.owner = src
+ new_objective:target = new_target:mind
+ //Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
+ new_objective.explanation_text = "[objective_type] [new_target:real_name], the [new_target:mind:assigned_role=="MODE" ? (new_target:mind:special_role) : (new_target:mind:assigned_role)]."
- if("unemag")
- var/mob/living/silicon/robot/R = current
- if (istype(R))
+ if ("prevent")
+ new_objective = new /datum/objective/block
+ new_objective.owner = src
+
+ if ("hijack")
+ new_objective = new /datum/objective/hijack
+ new_objective.owner = src
+
+ if ("escape")
+ new_objective = new /datum/objective/escape
+ new_objective.owner = src
+
+ if ("survive")
+ new_objective = new /datum/objective/survive
+ new_objective.owner = src
+
+ if ("mercenary")
+ new_objective = new /datum/objective/nuclear
+ new_objective.owner = src
+
+ if ("steal")
+ if (!istype(objective, /datum/objective/steal))
+ new_objective = new /datum/objective/steal
+ new_objective.owner = src
+ else
+ new_objective = objective
+ var/datum/objective/steal/steal = new_objective
+ if (!steal.select_target())
+ return
+
+ if("download","capture","absorb")
+ var/def_num
+ if(objective&&objective.type==text2path("/datum/objective/[new_obj_type]"))
+ def_num = objective.target_amount
+
+ var/target_number = input("Input target number:", "Objective", def_num) as num|null
+ if (isnull(target_number))//Ordinarily, you wouldn't need isnull. In this case, the value may already exist.
+ return
+
+ switch(new_obj_type)
+ if("download")
+ new_objective = new /datum/objective/download
+ new_objective.explanation_text = "Download [target_number] research levels."
+ if("capture")
+ new_objective = new /datum/objective/capture
+ new_objective.explanation_text = "Accumulate [target_number] capture points."
+ if("absorb")
+ new_objective = new /datum/objective/absorb
+ new_objective.explanation_text = "Absorb [target_number] compatible genomes."
+ new_objective.owner = src
+ new_objective.target_amount = target_number
+
+ if ("custom")
+ var/expl = sanitize(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null)
+ if (!expl) return
+ new_objective = new /datum/objective
+ new_objective.owner = src
+ new_objective.explanation_text = expl
+
+ if (!new_objective) return
+
+ if (objective)
+ objectives -= objective
+ objectives.Insert(objective_pos, new_objective)
+ else
+ objectives += new_objective
+
+ else if (href_list["obj_delete"])
+ var/datum/objective/objective = locate(href_list["obj_delete"])
+ if(!istype(objective)) return
+ objectives -= objective
+
+ else if(href_list["obj_completed"])
+ var/datum/objective/objective = locate(href_list["obj_completed"])
+ if(!istype(objective)) return
+ objective.completed = !objective.completed
+
+ else if(href_list["implant"])
+ var/mob/living/carbon/human/H = current
+
+ BITSET(H.hud_updateflag, IMPLOYAL_HUD) // updates that players HUD images so secHUD's pick up they are implanted or not.
+
+ switch(href_list["implant"])
+ if("remove")
+ for(var/obj/item/weapon/implant/loyalty/I in H.contents)
+ for(var/obj/item/organ/external/organs in H.organs)
+ if(I in organs.implants)
+ qdel(I)
+ break
+ H << "Your loyalty implant has been deactivated."
+ log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].")
+ if("add")
+ H << "You somehow have become the recepient of a loyalty transplant, and it just activated!"
+ H.implant_loyalty(H, override = TRUE)
+ log_admin("[key_name_admin(usr)] has loyalty implanted [current].")
+ else
+ else if (href_list["silicon"])
+ BITSET(current.hud_updateflag, SPECIALROLE_HUD)
+ switch(href_list["silicon"])
+
+ if("unemag")
+ var/mob/living/silicon/robot/R = current
+ if (istype(R))
+ R.emagged = 0
+ if (R.activated(R.module.emag))
+ R.module_active = null
+ if(R.module_state_1 == R.module.emag)
+ R.module_state_1 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_2 == R.module.emag)
+ R.module_state_2 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_3 == R.module.emag)
+ R.module_state_3 = null
+ R.contents -= R.module.emag
+ log_admin("[key_name_admin(usr)] has unemag'ed [R].")
+
+ if("unemagcyborgs")
+ if (istype(current, /mob/living/silicon/ai))
+ var/mob/living/silicon/ai/ai = current
+ for (var/mob/living/silicon/robot/R in ai.connected_robots)
R.emagged = 0
- if (R.activated(R.module.emag))
- R.module_active = null
- if(R.module_state_1 == R.module.emag)
- R.module_state_1 = null
- R.contents -= R.module.emag
- else if(R.module_state_2 == R.module.emag)
- R.module_state_2 = null
- R.contents -= R.module.emag
- else if(R.module_state_3 == R.module.emag)
- R.module_state_3 = null
- R.contents -= R.module.emag
- log_admin("[key_name_admin(usr)] has unemag'ed [R].")
+ if (R.module)
+ if (R.activated(R.module.emag))
+ R.module_active = null
+ if(R.module_state_1 == R.module.emag)
+ R.module_state_1 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_2 == R.module.emag)
+ R.module_state_2 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_3 == R.module.emag)
+ R.module_state_3 = null
+ R.contents -= R.module.emag
+ log_admin("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.")
- if("unemagcyborgs")
- if (istype(current, /mob/living/silicon/ai))
- var/mob/living/silicon/ai/ai = current
- for (var/mob/living/silicon/robot/R in ai.connected_robots)
- R.emagged = 0
- if (R.module)
- if (R.activated(R.module.emag))
- R.module_active = null
- if(R.module_state_1 == R.module.emag)
- R.module_state_1 = null
- R.contents -= R.module.emag
- else if(R.module_state_2 == R.module.emag)
- R.module_state_2 = null
- R.contents -= R.module.emag
- else if(R.module_state_3 == R.module.emag)
- R.module_state_3 = null
- R.contents -= R.module.emag
- log_admin("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.")
-
- else if (href_list["common"])
- switch(href_list["common"])
- if("undress")
- for(var/obj/item/W in current)
- current.drop_from_inventory(W)
- if("takeuplink")
- take_uplink()
- memory = null//Remove any memory they may have had.
- if("crystals")
- if (usr.client.holder.rights & R_FUN)
- var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
- var/crystals
+ else if (href_list["common"])
+ switch(href_list["common"])
+ if("undress")
+ for(var/obj/item/W in current)
+ current.drop_from_inventory(W)
+ if("takeuplink")
+ take_uplink()
+ memory = null//Remove any memory they may have had.
+ if("crystals")
+ if (usr.client.holder.rights & R_FUN)
+ var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink()
+ var/crystals
+ if (suplink)
+ crystals = suplink.uses
+ crystals = input("Amount of telecrystals for [key]","Operative uplink", crystals) as null|num
+ if (!isnull(crystals))
if (suplink)
- crystals = suplink.uses
- crystals = input("Amount of telecrystals for [key]","Operative uplink", crystals) as null|num
- if (!isnull(crystals))
- if (suplink)
- suplink.uses = crystals
+ suplink.uses = crystals
- else if (href_list["obj_announce"])
- var/obj_count = 1
- current << "\blue Your current objectives:"
- for(var/datum/objective/objective in objectives)
- current << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
- edit_memory()
-/*
- proc/clear_memory(var/silent = 1)
- var/datum/game_mode/current_mode = ticker.mode
+ else if (href_list["obj_announce"])
+ var/obj_count = 1
+ current << "\blue Your current objectives:"
+ for(var/datum/objective/objective in objectives)
+ current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+ edit_memory()
- // remove traitor uplinks
- var/list/L = current.get_contents()
- for (var/t in L)
- if (istype(t, /obj/item/device/pda))
- if (t:uplink) qdel(t:uplink)
- t:uplink = null
- else if (istype(t, /obj/item/device/radio))
- if (t:traitorradio) qdel(t:traitorradio)
- t:traitorradio = null
- t:traitor_frequency = 0.0
- else if (istype(t, /obj/item/weapon/SWF_uplink) || istype(t, /obj/item/weapon/syndicate_uplink))
- if (t:origradio)
- var/obj/item/device/radio/R = t:origradio
- R.loc = current.loc
- R.traitorradio = null
- R.traitor_frequency = 0.0
- qdel(t)
+/datum/mind/proc/find_syndicate_uplink()
+ var/list/L = current.get_contents()
+ for (var/obj/item/I in L)
+ if (I.hidden_uplink)
+ return I.hidden_uplink
+ return null
- // remove wizards spells
- //If there are more special powers that need removal, they can be procced into here./N
- current.spellremove(current)
-
- // clear memory
- memory = ""
- special_role = null
-
-*/
-
- proc/find_syndicate_uplink()
- var/list/L = current.get_contents()
- for (var/obj/item/I in L)
- if (I.hidden_uplink)
- return I.hidden_uplink
- return null
-
- proc/take_uplink()
- var/obj/item/device/uplink/hidden/H = find_syndicate_uplink()
- if(H)
- qdel(H)
+/datum/mind/proc/take_uplink()
+ var/obj/item/device/uplink/hidden/H = find_syndicate_uplink()
+ if(H)
+ qdel(H)
- // check whether this mind's mob has been brigged for the given duration
- // have to call this periodically for the duration to work properly
- proc/is_brigged(duration)
- var/turf/T = current.loc
- if(!istype(T))
- brigged_since = -1
- return 0
-
- var/is_currently_brigged = 0
-
- if(istype(T.loc,/area/security/brig))
- is_currently_brigged = 1
- for(var/obj/item/weapon/card/id/card in current)
+// check whether this mind's mob has been brigged for the given duration
+// have to call this periodically for the duration to work properly
+/datum/mind/proc/is_brigged(duration)
+ var/turf/T = current.loc
+ if(!istype(T))
+ brigged_since = -1
+ return 0
+ var/is_currently_brigged = 0
+ if(istype(T.loc,/area/security/brig))
+ is_currently_brigged = 1
+ for(var/obj/item/weapon/card/id/card in current)
+ is_currently_brigged = 0
+ break // if they still have ID they're not brigged
+ for(var/obj/item/device/pda/P in current)
+ if(P.id)
is_currently_brigged = 0
break // if they still have ID they're not brigged
- for(var/obj/item/device/pda/P in current)
- if(P.id)
- is_currently_brigged = 0
- break // if they still have ID they're not brigged
- if(!is_currently_brigged)
- brigged_since = -1
- return 0
+ if(!is_currently_brigged)
+ brigged_since = -1
+ return 0
- if(brigged_since == -1)
- brigged_since = world.time
+ if(brigged_since == -1)
+ brigged_since = world.time
- return (duration <= world.time - brigged_since)
+ return (duration <= world.time - brigged_since)
+/datum/mind/proc/reset()
+ assigned_role = null
+ special_role = null
+ role_alt_title = null
+ assigned_job = null
+ //faction = null //Uncommenting this causes a compile error due to 'undefined type', fucked if I know.
+ changeling = null
+ initial_account = null
+ objectives = list()
+ special_verbs = list()
+ has_been_rev = 0
+ rev_cooldown = 0
+ brigged_since = -1
//Antagonist role check
/mob/living/proc/check_special_role(role)
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
deleted file mode 100644
index fd20de103c..0000000000
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Glass stack types
- * Contains:
- * Glass sheets
- * Reinforced glass sheets
- * Phoron Glass Sheets
- * Reinforced Phoron Glass Sheets (AKA Holy fuck strong windows)
- * Glass shards - TODO: Move this into code/game/object/item/weapons
- */
-
-/*
- * Glass sheets
- */
-/obj/item/stack/material/glass
- name = "glass"
- singular_name = "glass sheet"
- icon_state = "sheet-glass"
- var/created_window = /obj/structure/window/basic
- var/is_reinforced = 0
- var/list/construction_options = list("One Direction", "Full Window")
- default_type = "glass"
-
-/obj/item/stack/material/glass/attack_self(mob/user as mob)
- construct_window(user)
-
-/obj/item/stack/material/glass/attackby(obj/item/W, mob/user)
- ..()
- if(!is_reinforced)
- if(istype(W,/obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/CC = W
- if (get_amount() < 1 || CC.get_amount() < 5)
- user << "You attach wire to the [name]."
- new /obj/item/stack/light_w(user.loc)
- else if(istype(W, /obj/item/stack/rods))
- var/obj/item/stack/rods/V = W
- if (V.get_amount() < 1 || get_amount() < 1)
- user << "You need one rod and one sheet of glass to make reinforced glass."
- return
-
- var/obj/item/stack/material/glass/reinforced/RG = new (user.loc)
- RG.add_fingerprint(user)
- RG.add_to_stacks(user)
- var/obj/item/stack/material/glass/G = src
- src = null
- var/replace = (user.get_inactive_hand()==G)
- V.use(1)
- G.use(1)
- if (!G && replace)
- user.put_in_hands(RG)
-
-/obj/item/stack/material/glass/proc/construct_window(mob/user as mob)
- if(!user || !src) return 0
- if(!istype(user.loc,/turf)) return 0
- if(!user.IsAdvancedToolUser())
- return 0
- var/title = "Sheet-[name]"
- title += " ([src.get_amount()] sheet\s left)"
- switch(input(title, "What would you like to construct?") as null|anything in construction_options)
- if("One Direction")
- if(!src) return 1
- if(src.loc != user) return 1
-
- var/list/directions = new/list(cardinal)
- var/i = 0
- for (var/obj/structure/window/win in user.loc)
- i++
- if(i >= 4)
- user << "\red There are too many windows in this location."
- return 1
- directions-=win.dir
- if(!(win.dir in cardinal))
- user << "\red Can't let you do that."
- return 1
-
- //Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc.
- var/dir_to_set = 2
- for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) ))
- var/found = 0
- for(var/obj/structure/window/WT in user.loc)
- if(WT.dir == direction)
- found = 1
- if(!found)
- dir_to_set = direction
- break
- new created_window( user.loc, dir_to_set, 1 )
- src.use(1)
- if("Full Window")
- if(!src) return 1
- if(src.loc != user) return 1
- if(src.get_amount() < 4)
- user << "\red You need more glass to do that."
- return 1
- if(locate(/obj/structure/window) in user.loc)
- user << "\red There is a window in the way."
- return 1
- new created_window( user.loc, SOUTHWEST, 1 )
- src.use(4)
- if("Windoor")
- if(!is_reinforced) return 1
-
-
- if(!src || src.loc != user) return 1
-
- if(isturf(user.loc) && locate(/obj/structure/windoor_assembly/, user.loc))
- user << "\red There is already a windoor assembly in that location."
- return 1
-
- if(isturf(user.loc) && locate(/obj/machinery/door/window/, user.loc))
- user << "\red There is already a windoor in that location."
- return 1
-
- if(src.get_amount() < 5)
- user << "\red You need more glass to do that."
- return 1
-
- new /obj/structure/windoor_assembly(user.loc, user.dir, 1)
- src.use(5)
-
- return 0
-
-
-/*
- * Reinforced glass sheets
- */
-/obj/item/stack/material/glass/reinforced
- name = "reinforced glass"
- singular_name = "reinforced glass sheet"
- icon_state = "sheet-rglass"
- default_type = "reinforced glass"
- created_window = /obj/structure/window/reinforced
- is_reinforced = 1
- construction_options = list("One Direction", "Full Window", "Windoor")
-
-/*
- * Phoron Glass sheets
- */
-/obj/item/stack/material/glass/phoronglass
- name = "phoron glass"
- singular_name = "phoron glass sheet"
- icon_state = "sheet-phoronglass"
- created_window = /obj/structure/window/phoronbasic
- default_type = "phoron glass"
-
-/obj/item/stack/material/glass/phoronglass/attackby(obj/item/W, mob/user)
- ..()
- if( istype(W, /obj/item/stack/rods) )
- var/obj/item/stack/rods/V = W
- var/obj/item/stack/material/glass/phoronrglass/RG = new (user.loc)
- RG.add_fingerprint(user)
- RG.add_to_stacks(user)
- V.use(1)
- var/obj/item/stack/material/glass/G = src
- src = null
- var/replace = (user.get_inactive_hand()==G)
- G.use(1)
- if (!G && !RG && replace)
- user.put_in_hands(RG)
- else
- return ..()
-
-/*
- * Reinforced phoron glass sheets
- */
-/obj/item/stack/material/glass/phoronrglass
- name = "reinforced phoron glass"
- singular_name = "reinforced phoron glass sheet"
- icon_state = "sheet-phoronrglass"
- default_type = "reinforced phoron glass"
- created_window = /obj/structure/window/phoronreinforced
- is_reinforced = 1
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index fa7a448bd6..7829705a63 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -114,9 +114,12 @@
"You have [anchored ? "fastened the grille to" : "unfastened the grill from"] the floor.")
return
-//window placing begin
- else if(istype(W,/obj/item/stack/material/glass))
- var/obj/item/stack/material/glass/ST = W
+//window placing begin //TODO CONVERT PROPERLY TO MATERIAL DATUM
+ else if(istype(W,/obj/item/stack/material))
+ var/obj/item/stack/material/ST = W
+ if(!ST.material.created_window)
+ return 0
+
var/dir_to_set = 1
if(loc == user.loc)
dir_to_set = user.dir
@@ -146,7 +149,7 @@
user << "There is already a window facing this way there."
return
- var/wtype = ST.created_window
+ var/wtype = ST.material.created_window
if (ST.use(1))
var/obj/structure/window/WD = new wtype(loc, dir_to_set, 1)
user << "You place the [WD] on [src]."
diff --git a/code/modules/hydroponics/_hydro_setup.dm b/code/modules/hydroponics/_hydro_setup.dm
index a3fd4604a6..4641aa3ace 100644
--- a/code/modules/hydroponics/_hydro_setup.dm
+++ b/code/modules/hydroponics/_hydro_setup.dm
@@ -55,4 +55,5 @@
#define TRAIT_PRODUCT_COLOUR 35
#define TRAIT_BIOLUM 36
#define TRAIT_BIOLUM_COLOUR 37
-#define TRAIT_IMMUTABLE 38
\ No newline at end of file
+#define TRAIT_IMMUTABLE 38
+#define TRAIT_FLESH_COLOUR 39
\ No newline at end of file
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 8b7678f19f..031fc8b23d 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -194,9 +194,11 @@
else if(seed.chems)
if(istype(W,/obj/item/weapon/material/hatchet) && !isnull(seed.chems["woodpulp"]))
user.show_message("You make planks out of \the [src]!", 1)
+ var/flesh_colour = seed.get_trait(TRAIT_FLESH_COLOUR)
+ if(!flesh_colour) flesh_colour = seed.get_trait(TRAIT_PRODUCT_COLOUR)
for(var/i=0,i<2,i++)
var/obj/item/stack/material/wood/NG = new (user.loc)
- NG.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
+ if(flesh_colour) NG.color = flesh_colour
for (var/obj/item/stack/material/wood/G in user.loc)
if(G==NG)
continue
@@ -221,6 +223,15 @@
new /obj/item/weapon/reagent_containers/food/snacks/soydope(get_turf(src))
qdel(src)
return
+ else if(seed.get_trait(TRAIT_FLESH_COLOUR))
+ user << "You slice up \the [src]."
+ var/slices = rand(3,5)
+ var/reagents_to_transfer = round(reagents.total_volume/slices)
+ for(var/i=i;i<=slices;i++)
+ var/obj/item/weapon/reagent_containers/food/snacks/fruit_slice/F = new(get_turf(src),seed)
+ if(reagents_to_transfer) reagents.trans_to_obj(F,reagents_to_transfer)
+ qdel(src)
+ return
..()
/obj/item/weapon/reagent_containers/food/snacks/grown/attack(var/mob/living/carbon/M, var/mob/user, var/def_zone)
@@ -301,9 +312,11 @@
if(seed.kitchen_tag == "grass")
user.show_message("You make a grass tile out of \the [src]!", 1)
+ var/flesh_colour = seed.get_trait(TRAIT_FLESH_COLOUR)
+ if(!flesh_colour) flesh_colour = seed.get_trait(TRAIT_PRODUCT_COLOUR)
for(var/i=0,i<2,i++)
var/obj/item/stack/tile/grass/G = new (user.loc)
- G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
+ if(flesh_colour) G.color = flesh_colour
for (var/obj/item/stack/tile/grass/NG in user.loc)
if(G==NG)
continue
@@ -358,3 +371,35 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris
plantname = "ambrosia"
+
+/obj/item/weapon/reagent_containers/food/snacks/fruit_slice
+ name = "fruit slice"
+ desc = "A slice of some tasty fruit."
+ icon = 'icons/obj/hydroponics_misc.dmi'
+ icon_state = ""
+
+var/list/fruit_icon_cache = list()
+
+/obj/item/weapon/reagent_containers/food/snacks/fruit_slice/New(var/newloc, var/datum/seed/S)
+ ..(newloc)
+ // Need to go through and make a general image caching controller. Todo.
+ if(!istype(S))
+ qdel(src)
+ return
+
+ name = "[S.seed_name] slice"
+ desc = "A slice of \a [S.seed_name]. Tasty, probably."
+
+ var/rind_colour = S.get_trait(TRAIT_PRODUCT_COLOUR)
+ var/flesh_colour = S.get_trait(TRAIT_FLESH_COLOUR)
+ if(!flesh_colour) flesh_colour = rind_colour
+ if(!fruit_icon_cache["rind-[rind_colour]"])
+ var/image/I = image(icon,"fruit_rind")
+ I.color = rind_colour
+ fruit_icon_cache["rind-[rind_colour]"] = I
+ overlays |= fruit_icon_cache["rind-[rind_colour]"]
+ if(!fruit_icon_cache["slice-[rind_colour]"])
+ var/image/I = image(icon,"fruit_slice")
+ I.color = flesh_colour
+ fruit_icon_cache["slice-[rind_colour]"] = I
+ overlays |= fruit_icon_cache["slice-[rind_colour]"]
\ No newline at end of file
diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm
index 9fd666fbb6..9afa043256 100644
--- a/code/modules/hydroponics/seed.dm
+++ b/code/modules/hydroponics/seed.dm
@@ -169,8 +169,9 @@
if(get_trait(TRAIT_BIOLUM_COLOUR))
clr = get_trait(TRAIT_BIOLUM_COLOUR)
splat.set_light(get_trait(TRAIT_BIOLUM), l_color = clr)
- if(get_trait(TRAIT_PRODUCT_COLOUR))
- splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
+ var/flesh_colour = get_trait(TRAIT_FLESH_COLOUR)
+ if(!flesh_colour) flesh_colour = get_trait(TRAIT_PRODUCT_COLOUR)
+ if(flesh_colour) splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
if(chems)
for(var/mob/living/M in T.contents)
@@ -635,7 +636,7 @@
if(GENE_STRUCTURE)
traits_to_copy = list(TRAIT_PLANT_ICON,TRAIT_PRODUCT_ICON,TRAIT_HARVEST_REPEAT)
if(GENE_FRUIT)
- traits_to_copy = list(TRAIT_STINGS,TRAIT_EXPLOSIVE,TRAIT_JUICY)
+ traits_to_copy = list(TRAIT_STINGS,TRAIT_EXPLOSIVE,TRAIT_FLESH_COLOUR,TRAIT_JUICY)
if(GENE_SPECIAL)
traits_to_copy = list(TRAIT_TELEPORTING)
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index cfbf024eda..b8b0530788 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -244,6 +244,7 @@
set_trait(TRAIT_PRODUCT_ICON,"apple")
set_trait(TRAIT_PRODUCT_COLOUR,"#FF540A")
set_trait(TRAIT_PLANT_ICON,"tree2")
+ set_trait(TRAIT_FLESH_COLOUR,"#E8E39B")
/datum/seed/apple/poison
name = "poisonapple"
@@ -804,6 +805,7 @@
set_trait(TRAIT_PRODUCT_COLOUR,"#326B30")
set_trait(TRAIT_PLANT_COLOUR,"#257522")
set_trait(TRAIT_PLANT_ICON,"vine2")
+ set_trait(TRAIT_FLESH_COLOUR,"#F22C2C")
/datum/seed/pumpkin
name = "pumpkin"
@@ -842,6 +844,7 @@
set_trait(TRAIT_PRODUCT_ICON,"treefruit")
set_trait(TRAIT_PRODUCT_COLOUR,"#3AF026")
set_trait(TRAIT_PLANT_ICON,"tree")
+ set_trait(TRAIT_FLESH_COLOUR,"#3AF026")
/datum/seed/citrus/lemon
name = "lemon"
@@ -854,6 +857,7 @@
..()
set_trait(TRAIT_PRODUCES_POWER,1)
set_trait(TRAIT_PRODUCT_COLOUR,"#F0E226")
+ set_trait(TRAIT_FLESH_COLOUR,"#F0E226")
/datum/seed/citrus/orange
name = "orange"
@@ -865,6 +869,7 @@
/datum/seed/citrus/orange/New()
..()
set_trait(TRAIT_PRODUCT_COLOUR,"#FFC20A")
+ set_trait(TRAIT_FLESH_COLOUR,"#FFC20A")
/datum/seed/grass
name = "grass"
diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm
index e62a96c2ce..87894c6d73 100644
--- a/code/modules/hydroponics/spreading/spreading.dm
+++ b/code/modules/hydroponics/spreading/spreading.dm
@@ -196,16 +196,19 @@
layer = 3
density = 0
-/obj/effect/plant/proc/calc_dir(turf/location = loc)
+/obj/effect/plant/proc/calc_dir()
set background = 1
+ var/turf/T = get_turf(src)
+ if(!istype(T)) return
+
var/direction = 16
for(var/wallDir in cardinal)
- var/turf/newTurf = get_step(location,wallDir)
+ var/turf/newTurf = get_step(T,wallDir)
if(newTurf.density)
direction |= wallDir
- for(var/obj/effect/plant/shroom in location)
+ for(var/obj/effect/plant/shroom in T.contents)
if(shroom == src)
continue
if(shroom.floor) //special
diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm
index ec6f51540f..62b3c433dc 100644
--- a/code/modules/materials/material_sheets.dm
+++ b/code/modules/materials/material_sheets.dm
@@ -47,6 +47,19 @@
return 0
..(S,tamount,1)
+/obj/item/stack/material/attack_self(var/mob/user)
+ if(!material.build_windows(user, src))
+ ..()
+
+/obj/item/stack/material/attackby(var/obj/item/W, var/mob/user)
+ if(istype(W,/obj/item/stack/cable_coil))
+ material.build_wired_product(user, W, src)
+ return
+ else if(istype(W, /obj/item/stack/rods))
+ material.build_rod_product(user, W, src)
+ return
+ return ..()
+
/obj/item/stack/material/iron
name = "iron"
icon_state = "sheet-silver"
@@ -75,7 +88,7 @@
default_type = "phoron"
/obj/item/stack/material/plastic
- name = "Plastic"
+ name = "plastic"
icon_state = "sheet-plastic"
default_type = "plastic"
@@ -151,3 +164,27 @@
singular_name = "leather piece"
icon_state = "sheet-leather"
default_type = "leather"
+
+/obj/item/stack/material/glass
+ name = "glass"
+ singular_name = "glass sheet"
+ icon_state = "sheet-glass"
+ default_type = "glass"
+
+/obj/item/stack/material/glass/reinforced
+ name = "reinforced glass"
+ singular_name = "reinforced glass sheet"
+ icon_state = "sheet-rglass"
+ default_type = "reinforced glass"
+
+/obj/item/stack/material/glass/phoronglass
+ name = "phoron glass"
+ singular_name = "phoron glass sheet"
+ icon_state = "sheet-phoronglass"
+ default_type = "phoron glass"
+
+/obj/item/stack/material/glass/phoronrglass
+ name = "reinforced phoron glass"
+ singular_name = "reinforced phoron glass sheet"
+ icon_state = "sheet-phoronrglass"
+ default_type = "reinforced phoron glass"
diff --git a/code/modules/materials/material_synth.dm b/code/modules/materials/material_synth.dm
index a0977e69c5..23b0e7e546 100644
--- a/code/modules/materials/material_synth.dm
+++ b/code/modules/materials/material_synth.dm
@@ -13,20 +13,26 @@
matter = null
/obj/item/stack/material/cyborg/plastic
+ icon_state = "sheet-plastic"
default_type = "plastic"
/obj/item/stack/material/cyborg/steel
+ icon_state = "sheet-metal"
default_type = "steel"
/obj/item/stack/material/cyborg/plasteel
+ icon_state = "sheet-plasteel"
default_type = "plasteel"
/obj/item/stack/material/cyborg/wood
+ icon_state = "sheet-wood"
default_type = "wood"
/obj/item/stack/material/cyborg/glass
+ icon_state = "sheet-glass"
default_type = "glass"
/obj/item/stack/material/cyborg/glass/reinforced
+ icon_state = "sheet-rglass"
default_type = "reinforced glass"
charge_costs = list(500, 1000)
\ No newline at end of file
diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm
index 710e8caf9d..0e2fecff36 100644
--- a/code/modules/materials/materials.dm
+++ b/code/modules/materials/materials.dm
@@ -77,6 +77,12 @@ var/list/name_to_material
var/conductive = 1 // Objects with this var add CONDUCTS to flags on spawn.
var/list/composite_material // If set, object matter var will be a list containing these values.
+ // Placeholder vars for the time being, todo properly integrate windows/light tiles/rods.
+ var/created_window
+ var/rod_product
+ var/wire_product
+ var/list/window_options = list()
+
// Damage values.
var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons.
var/weight = 20 // Determines blunt damage/throwforce for weapons.
@@ -90,6 +96,37 @@ var/list/name_to_material
// Wallrot crumble message.
var/rotting_touch_message = "crumbles under your touch"
+// Placeholders for light tiles and rglass.
+/material/proc/build_rod_product(var/mob/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack)
+ if(!rod_product)
+ user << "You cannot make anything out of \the [target_stack]"
+ return
+ if(used_stack.get_amount() < 1 || target_stack.get_amount() < 1)
+ user << "You need one rod and one sheet of [display_name] to make anything useful."
+ return
+ used_stack.use(1)
+ target_stack.use(1)
+ var/obj/item/stack/S = new rod_product(get_turf(user))
+ S.add_fingerprint(user)
+ S.add_to_stacks(user)
+ if(!(user.l_hand && user.r_hand))
+ user.put_in_hands(S)
+
+/material/proc/build_wired_product(var/mob/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack)
+ if(!wire_product)
+ user << "You cannot make anything out of \the [target_stack]"
+ return
+ if(used_stack.get_amount() < 5 || target_stack.get_amount() < 1)
+ user << "You need five wires and one sheet of [display_name] to make anything useful."
+ return
+
+ used_stack.use(5)
+ target_stack.use(1)
+ user << "You attach wire to the [name]."
+ var/obj/item/product = new wire_product(get_turf(user))
+ if(!(user.l_hand && user.r_hand))
+ user.put_in_hands(product)
+
// Make sure we have a display name and shard icon even if they aren't explicitly set.
/material/New()
..()
@@ -100,6 +137,10 @@ var/list/name_to_material
if(!shard_icon)
shard_icon = shard_type
+// This is a placeholder for proper integration of windows/windoors into the system.
+/material/proc/build_windows(var/mob/living/user, var/obj/item/stack/used_stack)
+ return 0
+
// Weapons handle applying a divisor for this value locally.
/material/proc/get_blunt_damage()
return weight //todo
@@ -273,7 +314,7 @@ var/list/name_to_material
hardness = 80
weight = 23
stack_origin_tech = "materials=2"
- composite_material = list() //todo
+ composite_material = list(DEFAULT_WALL_MATERIAL = 3750, "platinum" = 3750) //todo
/material/glass
name = "glass"
@@ -288,21 +329,82 @@ var/list/name_to_material
weight = 15
door_icon_base = "stone"
destruction_desc = "shatters"
+ window_options = list("One Direction", "Full Window")
+ created_window = /obj/structure/window/basic
+ wire_product = /obj/item/stack/light_w
+ rod_product = /obj/item/stack/material/glass/reinforced
-/material/glass/phoron
- name = "phoron glass"
- stack_type = /obj/item/stack/material/glass/phoronglass
- flags = MATERIAL_BRITTLE
- ignition_point = 300
- integrity = 200 // idk why but phoron windows are strong, so.
- icon_colour = "#FC2BC5"
- stack_origin_tech = "materials=3;phorontech=2"
+/material/glass/build_windows(var/mob/living/user, var/obj/item/stack/used_stack)
-/material/glass/phoron/reinforced
- name = "reinforced phoron glass"
- stack_type = /obj/item/stack/material/glass/phoronrglass
- stack_origin_tech = "materials=4;phorontech=2"
- composite_material = list() //todo
+ if(!user || !used_stack || !created_window || !window_options.len)
+ return 0
+
+ if(!user.IsAdvancedToolUser())
+ user << "This task is too complex for your clumsy hands."
+ return 1
+
+ var/turf/T = user.loc
+ if(!istype(T))
+ user << "You must be standing on open flooring to build a window."
+ return 1
+
+ var/title = "Sheet-[used_stack.name] ([used_stack.get_amount()] sheet\s left)"
+ var/choice = input(title, "What would you like to construct?") as null|anything in window_options
+
+ if(!choice || !used_stack || !user || used_stack.loc != user || user.stat || user.loc != T)
+ return 1
+
+ // Get data for building windows here.
+ var/list/possible_directions = cardinal.Copy()
+ var/window_count = 0
+ for (var/obj/structure/window/check_window in user.loc)
+ window_count++
+ possible_directions -= check_window.dir
+
+ // Get the closest available dir to the user's current facing.
+ var/build_dir = SOUTHWEST //Default to southwest for fulltile windows.
+ var/failed_to_build
+
+ if(window_count >= 4)
+ failed_to_build = 1
+ else
+ if(choice in list("One Direction","Windoor"))
+ if(possible_directions.len)
+ for(var/direction in list(user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) ))
+ if(direction in possible_directions)
+ build_dir = direction
+ break
+ else
+ failed_to_build = 1
+ if(!failed_to_build && choice == "Windoor")
+ if(!is_reinforced())
+ user << "This material is not reinforced enough to use for a door."
+ return
+ if((locate(/obj/structure/windoor_assembly) in T.contents) || (locate(/obj/machinery/door/window) in T.contents))
+ failed_to_build = 1
+ if(failed_to_build)
+ user << "There is no room in this location."
+ return 1
+
+ var/build_path = /obj/structure/windoor_assembly
+ var/sheets_needed = 4
+ if(choice == "Windoor")
+ sheets_needed = 5
+ build_dir = user.dir
+ else
+ build_path = created_window
+
+ if(used_stack.get_amount() < sheets_needed)
+ user << "You need at least [sheets_needed] sheets to build this."
+ return 1
+
+ // Build the structure and update sheet count etc.
+ used_stack.use(sheets_needed)
+ new build_path(T, build_dir, 1)
+ return 1
+
+/material/glass/proc/is_reinforced()
+ return (hardness > 35) //todo
/material/glass/reinforced
name = "reinforced glass"
@@ -316,7 +418,32 @@ var/list/name_to_material
hardness = 40
weight = 30
stack_origin_tech = "materials=2"
+ composite_material = list(DEFAULT_WALL_MATERIAL = 1875,"glass" = 3750)
+ window_options = list("One Direction", "Full Window", "Windoor")
+ created_window = /obj/structure/window/reinforced
+ wire_product = null
+ rod_product = null
+
+/material/glass/phoron
+ name = "phoron glass"
+ stack_type = /obj/item/stack/material/glass/phoronglass
+ flags = MATERIAL_BRITTLE
+ ignition_point = 300
+ integrity = 200 // idk why but phoron windows are strong, so.
+ icon_colour = "#FC2BC5"
+ stack_origin_tech = "materials=3;phorontech=2"
+ created_window = /obj/structure/window/phoronbasic
+ wire_product = null
+ rod_product = /obj/item/stack/material/glass/phoronrglass
+
+/material/glass/phoron/reinforced
+ name = "reinforced phoron glass"
+ stack_type = /obj/item/stack/material/glass/phoronrglass
+ stack_origin_tech = "materials=4;phorontech=2"
composite_material = list() //todo
+ created_window = /obj/structure/window/phoronreinforced
+ hardness = 40
+ rod_product = null
/material/plastic
name = "plastic"
diff --git a/code/modules/mob/freelook/mask/update_triggers.dm b/code/modules/mob/freelook/mask/update_triggers.dm
index a8e68058fd..8100a309a2 100644
--- a/code/modules/mob/freelook/mask/update_triggers.dm
+++ b/code/modules/mob/freelook/mask/update_triggers.dm
@@ -35,7 +35,7 @@
cultnet.updateVisibility(src, 0)
/mob/living/death(gibbed, deathmessage="seizes up and falls limp...")
- if(..())
+ if(..(gibbed, deathmessage))
// If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
cultnet.updateVisibility(src)
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
index b9ff795aaa..5d66d68695 100644
--- a/code/modules/mob/living/carbon/brain/posibrain.dm
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -60,6 +60,7 @@
src.searching = 0
src.brainmob.mind = candidate.mind
src.brainmob.ckey = candidate.ckey
+ src.brainmob.mind.reset()
src.name = "positronic brain ([src.brainmob.name])"
src.brainmob << "You are a positronic brain, brought into existence on [station_name()]."
src.brainmob << "As a synthetic intelligence, you answer to all crewmembers, as well as the AI."
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index e2ec5059a2..4b33818033 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -295,7 +295,7 @@
if(!O.force)
visible_message("[user] gently taps [src] with \the [O].")
return
-
+
if(O.force > resistance)
var/damage = O.force
if (O.damtype == HALLOSS)
@@ -306,8 +306,8 @@
adjustBruteLoss(damage)
else
usr << "[src] has been attacked with the [O] by [user].")
+
+ visible_message("\The [src] has been attacked with the [O] by [user].")
user.do_attack_animation(src)
/mob/living/simple_animal/movement_delay()
@@ -327,10 +327,10 @@
if(statpanel("Status") && show_stat_health)
stat(null, "Health: [round((health / maxHealth) * 100)]%")
-/mob/living/simple_animal/death(gibbed, deathmessage="")
+/mob/living/simple_animal/death(gibbed, deathmessage = "dies!")
icon_state = icon_dead
density = 0
- return ..()
+ return ..(gibbed,deathmessage)
/mob/living/simple_animal/ex_act(severity)
if(!blinded)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 0ff35abdca..50dfbbfe93 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -362,7 +362,8 @@
return
M.key = key
-// M.Login() //wat
+ if(M.mind)
+ M.mind.reset()
return
/client/verb/changes()
diff --git a/icons/obj/hydroponics_misc.dmi b/icons/obj/hydroponics_misc.dmi
new file mode 100644
index 0000000000..a5c594d93f
Binary files /dev/null and b/icons/obj/hydroponics_misc.dmi differ