From 4b04b867ac7ff48ac5de56758331db83ae13ca16 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 10 Jun 2015 12:32:50 +0930 Subject: [PATCH 1/6] Fxes #9625 --- code/modules/hydroponics/spreading/spreading.dm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 From 8a2c0226dcf6daeae6434a7aefc9866205bfdf84 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 10 Jun 2015 12:45:03 +0930 Subject: [PATCH 2/6] Fixes #9597 --- code/modules/materials/materials.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index 710e8caf9d..0409a8b7f1 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -273,7 +273,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" @@ -316,7 +316,7 @@ var/list/name_to_material hardness = 40 weight = 30 stack_origin_tech = "materials=2" - composite_material = list() //todo + composite_material = list(DEFAULT_WALL_MATERIAL = 1875,"glass" = 3750) /material/plastic name = "plastic" From 018c3fc2aa4ebb00ea46360a5db0df7d8fd2d9be Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 10 Jun 2015 13:21:07 +0930 Subject: [PATCH 3/6] Fixes #9517 and #9542 --- code/modules/mob/freelook/mask/update_triggers.dm | 2 +- code/modules/mob/living/simple_animal/simple_animal.dm | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) 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/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) From cef958cac2f52aeaa90983d7c73bd2ec844130e4 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 10 Jun 2015 14:19:55 +0930 Subject: [PATCH 4/6] Fixes #9503 --- code/datums/mind.dm | 758 ++++++++---------- .../mob/living/carbon/brain/posibrain.dm | 1 + code/modules/mob/mob.dm | 3 +- 3 files changed, 347 insertions(+), 415 deletions(-) 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/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/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() From 48b063a96eb8bdbefe4dd1fc28aa228f4ffa03c2 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 10 Jun 2015 21:57:00 +0930 Subject: [PATCH 5/6] Fixes #9620 --- code/modules/hydroponics/_hydro_setup.dm | 3 +- code/modules/hydroponics/grown.dm | 49 ++++++++++++++++++++++- code/modules/hydroponics/seed.dm | 6 ++- code/modules/hydroponics/seed_datums.dm | 2 + icons/obj/hydroponics_misc.dmi | Bin 0 -> 337 bytes 5 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 icons/obj/hydroponics_misc.dmi 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..72f0e444ab 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 //This may need to be made more specific, but at this point I am not sure what the criteria should be. + 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..2331c328dc 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -60,6 +60,7 @@ set_trait(TRAIT_IDEAL_HEAT, 293) // Preferred temperature in Kelvin. set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25) // Plant eats this much per tick. set_trait(TRAIT_PLANT_COLOUR, "#46B543") // Colour of the plant icon. + set_trait(TRAIT_FLESH_COLOUR, "#46B543") spawn(5) sleep(-1) @@ -169,8 +170,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) diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index cfbf024eda..d93de27286 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" diff --git a/icons/obj/hydroponics_misc.dmi b/icons/obj/hydroponics_misc.dmi new file mode 100644 index 0000000000000000000000000000000000000000..a5c594d93ff9fadfa688db26bf17cf2dd5d0fe86 GIT binary patch literal 337 zcmV-X0j~auP)H9JO0004WQchCV=-0C=2J zR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5 zDXpk9vn0MaCo?%!iHkEOv#1y-YRJWzR+N~V3SpzEEy~PG!KGAL!PU<$1dB`J7j zo#o>I003=CL_t(IjqQ%x4S*mFMJuoXod6pKFxCMKbpM%*@ln#K0~pQ^3HP+U0G-Yw zLoy%U Date: Wed, 10 Jun 2015 22:11:33 +0930 Subject: [PATCH 6/6] Fixes #9777 --- baystation12.dme | 1 - .../game/objects/items/stacks/sheets/glass.dm | 174 ------------------ code/game/objects/structures/grille.dm | 11 +- code/modules/hydroponics/grown.dm | 2 +- code/modules/hydroponics/seed.dm | 3 +- code/modules/hydroponics/seed_datums.dm | 3 + code/modules/materials/material_sheets.dm | 39 +++- code/modules/materials/material_synth.dm | 6 + code/modules/materials/materials.dm | 153 +++++++++++++-- 9 files changed, 196 insertions(+), 196 deletions(-) delete mode 100644 code/game/objects/items/stacks/sheets/glass.dm 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/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/grown.dm b/code/modules/hydroponics/grown.dm index 72f0e444ab..031fc8b23d 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -223,7 +223,7 @@ new /obj/item/weapon/reagent_containers/food/snacks/soydope(get_turf(src)) qdel(src) return - else //This may need to be made more specific, but at this point I am not sure what the criteria should be. + 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) diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 2331c328dc..9afa043256 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -60,7 +60,6 @@ set_trait(TRAIT_IDEAL_HEAT, 293) // Preferred temperature in Kelvin. set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25) // Plant eats this much per tick. set_trait(TRAIT_PLANT_COLOUR, "#46B543") // Colour of the plant icon. - set_trait(TRAIT_FLESH_COLOUR, "#46B543") spawn(5) sleep(-1) @@ -637,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 d93de27286..b8b0530788 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -844,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" @@ -856,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" @@ -867,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/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 0409a8b7f1..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 @@ -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" @@ -317,6 +419,31 @@ var/list/name_to_material 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"