diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 98686aee07d..b5564f3f6b0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -21,7 +21,7 @@ reporting bugs in the code. Refer to ISSUE_TEMPLATE for the exact format that yo should be in. #### Guidelines: - - Issue reports should be as detailed as possible, and if applicable, should include + * Issue reports should be as detailed as possible, and if applicable, should include instructions on how to reproduce the bug. ## Pull requests @@ -31,119 +31,491 @@ strongly recommended you get approval/traction for it from our forums before sta actual development. #### Guidelines: - - Pull requests should be atomic; Make one commit for each distinct change, so if a part + * Pull requests should be atomic; Make one commit for each distinct change, so if a part of a pull request needs to be removed/changed, you may simply modify that single commit. Due to limitations of the engine, this may not always be possible; but do try your best. - - Document and explain your pull requests thoroughly. Detail what each commit changes, + * Document and explain your pull requests thoroughly. Detail what each commit changes, and why it changes it. We do not want to have to read all of you commit names to figure out what your pull request is about. - - Any pull request that is not solely composed of fixes or non gameplay-affecting + * Any pull request that is not solely composed of fixes or non gameplay-affecting refactors must have a changelog. Inline changelogs are supported through the format described [here](https://github.com/ParadiseSS13/Paradise/pull/3291#issuecomment-172950466) and should be used rather than manually edited .yml file changelogs. - - Pull requests should not have any merge commits except in the case of fixing merge + * Pull requests should not have any merge commits except in the case of fixing merge conflicts for an existing pull request. New pull requests should not have any merge commits. Use `git rebase` or `git reset` to update your branches, not `git pull`. -#### BYOND Specific Guidelines: - - Any `type` or `proc` paths **must** use absolute pathing unless the file you are - working in primarily utilizes relative pathing. - - Paths must begin with `/`. It should be `/obj/machinery/fancy_robot`, - not `obj/machinery/fancy_robot`. - - New bases of datum must begin with `/datum/`. `/datum/arbitrary_datum`, - not `/arbitrary_datum`. - - Don't use strings in combination with `text2path()` unless the paths are being - dynamically created. Variables can contain normal paths just fine. - - Don't duplicate code. If you have identical code in two places, it should probably - be a new proc that they both can use. - - No magic numbers/strings. If you have a number or text that is important and used in - your code, make a `#DEFINE` statement with a name that clearly indicates it's use. - - `if(condition)` must be used over `if (condition)` or any other variation. - - The same applies for `while` and `for` loops, they must have no space between the - keyword and condition brackets. `while(condition)`, `for(condition)` - - If you want to output a message to a player's chat - (this includes text sent to `world`), use `to_chat(mob/client/world, "message")`. - Do not use `mob/client/world << "message"`. - - Do not use one-line control statements (if, else, for, while, etc). The space saved - is not worth the decreased readability. - - Control statements comparing a variable to a constant should be formatted `variable`, - `operator`, `constant`. This means `if(count <= 10)` is preferred over - `if(10 >= count)`. - - **Never** use a colon `:` operator to bypass type safety checks, unless you are doing - something where the tiny performance increase is incredibly noticeable (eg, a loop for - a huge list). You should properly typecast everything and use the period `.` - operator. - - Use early returns, and avoid far-indented if blocks. This means that you should not - do this: +#### Using Changelog + * Tags used in changelog include add/rscadd, del/rscdel, fix/fixes, typo/spellcheck. + * Without specifying a name it will default to using your GitHub name. + Some examples +``` +:cl: +add: The ability to change the color of wires +del: Deleted depreciated wire merging now handled in parent +fix: Moving wires now follows the user input instead of moving the stack +/:cl: +``` +``` +:cl: N3X15 +typo: Fixes some misspelled words under Using Changelog +/:cl: +``` + + +## Specifications + +As mentioned before, you are expected to follow these specifications in order to make everyone's lives easier. It'll save both your time and ours, by making +sure you don't have to make any changes and we don't have to ask you to. Thank you for reading this section! + +### Object Oriented Code +As BYOND's Dream Maker (henceforth "DM") is an object-oriented language, code must be object-oriented when possible in order to be more flexible when adding +content to it. If you don't know what "object-oriented" means, we highly recommend you do some light research to grasp the basics. + +### All BYOND paths must contain the full path +(i.e. absolute pathing) + +DM will allow you nest almost any type keyword into a block, such as: + +```DM +datum + datum1 + var + varname1 = 1 + varname2 + static + varname3 + varname4 + proc + proc1() + code + proc2() + code + + datum2 + varname1 = 0 + proc + proc3() + code + proc2() + ..() + code +``` + +The use of this is not allowed in this project *unless the majority of the file is already relatively pathed* as it makes finding definitions via full text +searching next to impossible. The only exception is the variables of an object may be nested to the object, but must not nest further. + +The previous code made compliant: + +```DM +/datum/datum1 + var/varname1 + var/varname2 + var/static/varname3 + var/static/varname4 + +/datum/datum1/proc/proc1() + code +/datum/datum1/proc/proc2() + code +/datum/datum1/datum2 + varname1 = 0 +/datum/datum1/datum2/proc/proc3() + code +/datum/datum1/datum2/proc2() + ..() + code +``` + +### No overriding type safety checks +The use of the : operator to override type safety checks is not allowed. You must cast the variable to the proper type. + +### Type paths must begin with a / +eg: `/datum/thing`, not `datum/thing` + +### Datum type paths must began with "datum" +In DM, this is optional, but omitting it makes finding definitions harder. To be specific, you can declare the path `/arbitrary`, but it +will still be, in actuality, `/datum/arbitrary`. Write your code to reflect this. + +### Do not use text/string based type paths +It is rarely allowed to put type paths in a text format, as there are no compile errors if the type path no longer exists. Here is an example: + +```DM +//Good +var/path_type = /obj/item/baseball_bat + +//Bad +var/path_type = "/obj/item/baseball_bat" +``` + +### Do not use `\The`. +The `\The` macro doesn't actually do anything when used in the format `\The [atom reference]`. Directly referencing an atom in an embedded string +will automatically prefix `The` or `the` to it as appropriate. As an extension, when referencing an atom, don't use `[atom.name]`, use `[atom]`. +The only exception to this rule is when dealing with items "belonging" to a mob, in which case you should use `[mob]'s [atom.name]` to avoid `The` +ever forming. + +```DM +//Good +var/atom/A +"[A]" + +//Bad +"\The [A]" +``` + +### Use the pronoun library instead of `\his` macros. +We have a system in code/\_\_HELPERS/pronouns.dm for addressing all forms of pronouns. This is useful in a number of ways; + * BYOND's \his macro can be unpredictable on what object it references. + Take this example: `"[user] waves \his [user.weapon] around, hitting \his opponents!"`. + This will end up referencing the user's gender in the first occurence, but what about the second? + It'll actually print the gender set on the weapon he's carrying, which is unintended - and there's no way around this. + * It always prints the real `gender` variable of the atom it's referencing. This can lead to exposing a mob's gender even when their face is covered, + which would normally prevent it's gender from being printed. + +The way to avoid these problems is to use the pronoun system. Instead of `"[user] waves \his arms."`, you can do `"[user] waves [user.p_their()] arms."` + +``` +//Good +"[H] waves [H.p_their()] hands!" +"[user] waves [H.p_their()] [user.weapon] around, hitting [H.p_their()] opponents!"` + +//Bad +"[H] waves \his hands!" +"[user] waves \his [user.weapon] around, hitting \his opponents!" +``` + +### Use `[A.UID()]` over `\ref[A]` +BYOND has a system to pass "soft references" to datums, using the format `"\ref[datum]"` inside a string. This allows you to find the object just based +off of a text string, which is especially useful when dealing with the bridge between BYOND code and HTML/JS in UIs. It's resolved back into an object +reference by using `locate("\ref[datum]")` when the code comes back to BYOND. The issue with this is that locate() can return a unexpected datum +if the original datum has been deleted - BYOND recycles the references. + +UID's are actually unique; they work off of a global counter and are not recycled. Each datum has one assigned to it when it's created, which can be +accessed by `[datum.UID()]`. You can use this as a snap-in replacement for `\ref` by changing any `locate(ref)` calls in your code to `locateUID(ref)`. +Usage of this system is mandatory for any /Topic( calls, and will produce errors in Dream Daemon if it's not used. ``, not `Agent Vest
" dat += "Radio Silencer
" dat += "Science Tool
" + dat += "Mental Interface Device
" else dat += "NO EXPERIMENT MACHINE DETECTED
" - if(pad!=null) + if(pad) dat += "Emergency Teleporter System." dat += "Consider using primary observation console first." dat += "Activate Teleporter
" - if(gizmo!=null && gizmo.marked!=null) + if(gizmo && gizmo.marked) dat += "Retrieve Mark
" else dat += "Retrieve Mark
" else dat += "NO TELEPAD DETECTED
" - if(vest!=null) + if(vest) dat += "

Agent Vest Mode


" var/mode = vest.mode if(mode == VEST_STEALTH) @@ -100,13 +101,14 @@ else if(href_list["flip_vest"]) FlipVest() else if(href_list["toggle_vest"]) - toggle_vest() + if(vest) + vest.toggle_nodrop() else if(href_list["select_disguise"]) SelectDisguise() else if(href_list["dispense"]) switch(href_list["dispense"]) if("baton") - Dispense(/obj/item/abductor_baton,cost=2) + Dispense(/obj/item/abductor_baton, cost = 2) if("helmet") Dispense(/obj/item/clothing/head/helmet/abductor) if("silencer") @@ -115,19 +117,21 @@ Dispense(/obj/item/abductor/gizmo) if("vest") Dispense(/obj/item/clothing/suit/armor/abductor/vest) + if("mind_device") + Dispense(/obj/item/abductor/mind_device, cost = 2) updateUsrDialog() /obj/machinery/abductor/console/proc/TeleporterRetrieve() - if(gizmo!=null && pad!=null && gizmo.marked) + if(pad && gizmo && gizmo.marked) pad.Retrieve(gizmo.marked) /obj/machinery/abductor/console/proc/TeleporterSend() - if(pad!=null) + if(pad) pad.Send() /obj/machinery/abductor/console/proc/FlipVest() - if(vest!=null) + if(vest) vest.flip_mode() /obj/machinery/abductor/console/proc/SelectDisguise(remote = 0) @@ -175,21 +179,36 @@ return disguises[entry.name] = entry +/obj/machinery/abductor/console/proc/AddGizmo(obj/item/abductor/gizmo/G) + if(G == gizmo && G.console == src) + return FALSE + + if(G.console) + G.console.gizmo = null + + gizmo = G + G.console = src + return TRUE + +/obj/machinery/abductor/console/proc/AddVest(obj/item/clothing/suit/armor/abductor/vest/V) + if(vest == V) + return FALSE + + for(var/obj/machinery/abductor/console/C in machines) + if(C.vest == V) + C.vest = null + break + + vest = V + return TRUE + /obj/machinery/abductor/console/attackby(obj/O, mob/user, params) - if(istype(O, /obj/item/abductor/gizmo)) - var/obj/item/abductor/gizmo/G = O + if(istype(O, /obj/item/abductor/gizmo) && AddGizmo(O)) to_chat(user, "You link the tool to the console.") - gizmo = G - G.console = src - else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest)) - var/obj/item/clothing/suit/armor/abductor/vest/V = O + else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest) && AddVest(O)) to_chat(user, "You link the vest to the console.") - if(istype(vest)) - if(vest.flags & NODROP) - toggle_vest() - vest = V else - ..() + return ..() /obj/machinery/abductor/console/proc/Dispense(item,cost=1) if(experiment && experiment.credits >= cost) @@ -201,10 +220,4 @@ else new item(src.loc) else - atom_say("Insufficent data!") - -/obj/machinery/abductor/console/proc/toggle_vest() - vest.flags ^= NODROP - var/mob/M = vest.loc - if(istype(M)) - to_chat(M, "[src] is now [vest.flags & NODROP ? "locked" : "unlocked"].") \ No newline at end of file + atom_say("Insufficent data!") \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm index 9e07c9c04a9..1a377667650 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm @@ -3,8 +3,8 @@ desc = "A tank filled with replacement organs" icon = 'icons/obj/abductor.dmi' icon_state = "dispenser" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE var/list/gland_types var/list/gland_colors var/list/amounts @@ -49,7 +49,7 @@ var/g_color = gland_colors[i] var/amount = amounts[i] dat += "[amount]" - if(item_count == 3) // Three boxes per line + if(item_count == 4) // Three boxes per line dat +="

" item_count = 0 var/datum/browser/popup = new(user, "glands", "Gland Dispenser", 200, 200) @@ -68,7 +68,7 @@ if(gland_types[i] == W.type) amounts[i]++ else - ..() + return ..() /obj/machinery/abductor/gland_dispenser/Topic(href, href_list) if(..()) diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index 8682b50fc05..53969aaf7d1 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -3,8 +3,8 @@ desc = "A large man-sized tube sporting a complex array of surgical apparatus." icon = 'icons/obj/abductor.dmi' icon_state = "experiment-open" - anchored = 1 - density = 1 + anchored = TRUE + density = TRUE var/points = 0 var/credits = 0 var/list/history = list() @@ -47,9 +47,9 @@ /obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H) var/icon/I = icon(H.stand_icon) - var/icon/splat = icon(H.species.damage_overlays, "30") - splat.Blend(icon(H.species.damage_mask, "torso"), ICON_MULTIPLY) - splat.Blend(H.species.blood_color, ICON_MULTIPLY) + var/icon/splat = icon(H.dna.species.damage_overlays, "30") + splat.Blend(icon(H.dna.species.damage_mask, "torso"), ICON_MULTIPLY) + splat.Blend(H.dna.species.blood_color, ICON_MULTIPLY) I.Blend(splat, ICON_OVERLAY) return I @@ -137,6 +137,7 @@ to_chat(H, "You feel intensely watched.") sleep(5) to_chat(H, "Your mind snaps!") + to_chat(H, "You can't remember how you got here...") var/objtype = pick(subtypesof(/datum/objective/abductee/)) var/datum/objective/abductee/O = new objtype() ticker.mode.abductees += H.mind diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index 11ec158db84..9593ee6b792 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -308,7 +308,7 @@ var/list/choices = list() for(var/mob/living/carbon/human/H in view(1,src)) var/obj/item/organ/external/head/head = H.get_organ("head") - if(head.status & ORGAN_ROBOT) + if(head.is_robotic()) continue if(H.stat != DEAD && Adjacent(H) && !H.has_brain_worms()) choices += H diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 03b7d2e1b56..6b976ad7f05 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -123,7 +123,7 @@ to_chat(src, "Prime Directives:") to_chat(src, "1. Consume resources and replicate until there are no more resources left.") to_chat(src, "2. Ensure that the station is fit for invasion at a later date, do not perform actions that would render it dangerous or inhospitable.") - to_chat(src, "3. Biological and Sentient resources will be harvested at a later date, do not harm them.") + to_chat(src, "3. Biological and sentient resources will be harvested at a later date, do not harm them.") /mob/living/simple_animal/hostile/swarmer/New() ..() @@ -306,6 +306,12 @@ /obj/spacepod/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) to_chat(S, "Destroying this vehicle would destroy us. Aborting.") +/obj/machinery/clonepod/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + if(occupant) + to_chat(S, "Destroying this machine while it is occupied would result in biological and sentient resources to be harmed. Aborting.") + return + ..() + /mob/living/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) S.DisperseTarget(src) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index feffadcf9ab..17afd375952 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -141,15 +141,15 @@ proc/issyndicate(mob/living/M as mob) return ..() -/datum/game_mode/proc/create_syndicate(var/datum/mind/synd_mind) // So we don't have inferior species as ops - randomize a human +/datum/game_mode/proc/create_syndicate(datum/mind/synd_mind) // So we don't have inferior species as ops - randomize a human var/mob/living/carbon/human/M = synd_mind.current - var/obj/item/organ/external/head/head_organ = M.get_organ("head") - M.set_species("Human",1) + M.set_species(/datum/species/human, TRUE) M.dna.ready_dna(M) // Quadriplegic Nuke Ops won't be participating in the paralympics M.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ops. M.overeatduration = 0 + var/obj/item/organ/external/head/head_organ = M.get_organ("head") var/hair_c = pick("#8B4513","#000000","#FF4500","#FFD700") // Brown, black, red, blonde var/eye_c = pick("#000000","#8B4513","1E90FF") // Black, brown, blue var/skin_tone = pick(-50, -30, -10, 0, 0, 0, 10) // Caucasian/black @@ -159,8 +159,8 @@ proc/issyndicate(mob/living/M as mob) head_organ.sec_hair_colour = hair_c M.change_eye_color(eye_c) M.s_tone = skin_tone - head_organ.h_style = random_hair_style(M.gender, head_organ.species.name) - head_organ.f_style = random_facial_hair_style(M.gender, head_organ.species.name) + head_organ.h_style = random_hair_style(M.gender, head_organ.dna.species.name) + head_organ.f_style = random_facial_hair_style(M.gender, head_organ.dna.species.name) M.body_accessory = null M.regenerate_icons() M.update_body() @@ -253,7 +253,7 @@ proc/issyndicate(mob/living/M as mob) U.hidden_uplink.uses = 20 synd_mob.equip_to_slot_or_del(U, slot_in_backpack) - if(synd_mob.species) + if(synd_mob.dna.species) /* Incase anyone ever gets the burning desire to have nukeops with randomized apperances. -- Dave @@ -262,7 +262,7 @@ proc/issyndicate(mob/living/M as mob) A.randomize_appearance_for(synd_mob) */ - var/race = synd_mob.species.name + var/race = synd_mob.dna.species.name switch(race) if("Vox" || "Vox Armalis") diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm index 8fbeb2d9690..7e75f579bf5 100644 --- a/code/game/gamemodes/nuclear/nuclear_challenge.dm +++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm @@ -3,7 +3,7 @@ #define CHALLENGE_SCALE_PLAYER 1 // How many player per scaling bonus #define CHALLENGE_SCALE_BONUS 2 // How many TC per scaling bonus #define CHALLENGE_MIN_PLAYERS 50 -#define CHALLENGE_SHUTTLE_DELAY 15000 //25 minutes, so the ops have at least 5 minutes before the shuttle is callable. +#define CHALLENGE_SHUTTLE_DELAY 18000 //30 minutes, so the ops have at least 10 minutes before the shuttle is callable. Gives the nuke ops at least 15 minutes before shuttle arrive. /obj/item/nuclear_challenge name = "Declaration of War (Challenge Mode)" diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 07395aa0578..b7364970351 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -281,7 +281,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu for(var/datum/mind/possible_target in ticker.minds) if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && possible_target.current.client) var/mob/living/carbon/human/H = possible_target.current - if(!(NO_DNA in H.species.species_traits)) + if(!(NO_DNA in H.dna.species.species_traits)) possible_targets += possible_target if(possible_targets.len > 0) target = pick(possible_targets) @@ -445,7 +445,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu n_p++ else if(ticker.current_state == GAME_STATE_PLAYING) for(var/mob/living/carbon/human/P in player_list) - if(NO_DNA in P.species.species_traits) + if(NO_DNA in P.dna.species.species_traits) continue if(P.client && !(P.mind in ticker.mode.changelings) && P.mind!=owner) n_p++ diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 1d0bb3adf03..6a1c242efb4 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -209,7 +209,7 @@ Made by Xhuis if(shadow.special_role == SPECIAL_ROLE_SHADOWLING && config.shadowling_max_age) if(ishuman(shadow.current)) var/mob/living/carbon/human/H = shadow.current - if(H.get_species() != "Shadow") + if(!isshadowling(H)) for(var/obj/effect/proc_holder/spell/targeted/shadowling_hatch/hatch_ability in shadow.spell_list) hatch_ability.cycles_unused++ if(!H.stunned && prob(20) && hatch_ability.cycles_unused > config.shadowling_max_age) @@ -306,93 +306,6 @@ Made by Xhuis MISCELLANEOUS */ - -/datum/species/shadow/ling - //Normal shadowpeople but with enhanced effects - name = "Shadowling" - - icobase = 'icons/mob/human_races/r_shadowling.dmi' - deform = 'icons/mob/human_races/r_shadowling.dmi' - - blood_color = "#555555" - flesh_color = "#222222" - - species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NOGUNS) //Can't use guns due to muzzle flash - burn_mod = 1.5 //1.5x burn damage, 2x is excessive - oxy_mod = 0 - heatmod = 1.5 - - silent_steps = 1 - grant_vision_toggle = 0 - - has_organ = list( - "brain" = /obj/item/organ/internal/brain, - "eyes" = /obj/item/organ/internal/eyes) - -/datum/species/shadow/ling/handle_life(var/mob/living/carbon/human/H) - if(!H.weakeyes) - H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs - var/light_amount = 0 - H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry - if(isturf(H.loc)) - var/turf/T = H.loc - light_amount = T.get_lumcount() * 10 - if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) //Can survive in very small light levels. Also doesn't take damage while incorporeal, for shadow walk purposes - H.throw_alert("lightexposure", /obj/screen/alert/lightexposure) - H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN) - if(H.stat != DEAD) - to_chat(H, "The light burns you!")//Message spam to say "GET THE FUCK OUT" - H << 'sound/weapons/sear.ogg' - else if(light_amount < LIGHT_HEAL_THRESHOLD) - H.clear_alert("lightexposure") - var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) - if(istype(E)) - E.receive_damage(-1) - H.heal_overall_damage(5, 5) - H.adjustToxLoss(-5) - H.adjustBrainLoss(-25) //Shad O. Ling gibbers, "CAN U BE MY THRALL?!!" - H.AdjustEyeBlurry(-1) - H.CureNearsighted() - H.CureBlind() - H.adjustCloneLoss(-1) - H.SetWeakened(0) - H.SetStunned(0) - ..() - - -/datum/species/shadow/ling/lesser //Empowered thralls. Obvious, but powerful - name = "Lesser Shadowling" - - icobase = 'icons/mob/human_races/r_lshadowling.dmi' - deform = 'icons/mob/human_races/r_lshadowling.dmi' - - blood_color = "#CCCCCC" - flesh_color = "#AAAAAA" - - species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE) - burn_mod = 1.1 - oxy_mod = 0 - heatmod = 1.1 - -/datum/species/shadow/ling/lesser/handle_life(var/mob/living/carbon/human/H) - if(!H.weakeyes) - H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs - var/light_amount = 0 - H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry - if(isturf(H.loc)) - var/turf/T = H.loc - light_amount = T.get_lumcount() * 10 - if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) - H.throw_alert("lightexposure", /obj/screen/alert/lightexposure) - H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN/2) - else if(light_amount < LIGHT_HEAL_THRESHOLD) - H.clear_alert("lightexposure") - H.heal_overall_damage(2,2) - H.adjustToxLoss(-5) - H.adjustBrainLoss(-25) - H.adjustCloneLoss(-1) - ..() - /datum/game_mode/proc/update_shadow_icons_added(datum/mind/shadow_mind) var/datum/atom_hud/antag/shadow_hud = huds[ANTAG_HUD_SHADOW] shadow_hud.join_hud(shadow_mind.current) diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 89aee290422..f8f55f0e126 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -2,8 +2,10 @@ /obj/effect/proc_holder/spell/proc/shadowling_check(var/mob/living/carbon/human/H) if(!H || !istype(H)) return - if(H.get_species() == "Shadowling" && is_shadow(H)) return 1 - if(H.get_species() == "Lesser Shadowling" && is_thrall(H)) return 1 + if(isshadowling(H) && is_shadow(H)) + return 1 + if(isshadowlinglesser(H) && is_thrall(H)) + return 1 if(!is_shadow_or_thrall(usr)) to_chat(usr, "You can't wrap your head around how to do this.") else if(is_thrall(usr)) @@ -267,7 +269,7 @@ listclearnulls(ticker.mode.shadowling_thralls) if(!(ling.mind in ticker.mode.shadows)) return - if(ling.get_species() != "Shadowling") + if(!isshadowling(ling)) if(ticker.mode.shadowling_thralls.len >= 5) charge_counter = charge_max return @@ -371,7 +373,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(H), slot_gloves) H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(H), slot_wear_mask) H.equip_to_slot_or_del(new /obj/item/clothing/glasses/shadowling(H), slot_glasses) - H.set_species("Shadowling") + H.set_species(/datum/species/shadow/ling) /obj/effect/proc_holder/spell/targeted/collective_mind //Lets a shadowling bring together their thralls' strength, granting new abilities and a headcount name = "Collective Hivemind" @@ -610,7 +612,7 @@ to_chat(user, "[thrallToRevive] must be conscious to become empowered.") charge_counter = charge_max return - if(thrallToRevive.get_species() == "Lesser Shadowling") + if(isshadowlinglesser(thrallToRevive)) to_chat(user, "[thrallToRevive] is already empowered.") charge_counter = charge_max return @@ -619,7 +621,7 @@ if(!ishuman(M.current)) return var/mob/living/carbon/human/H = M.current - if(H.get_species() == "Lesser Shadowling") + if(isshadowlinglesser(H)) empowered_thralls++ if(empowered_thralls >= EMPOWERED_THRALL_LIMIT) to_chat(user, "You cannot spare this much energy. There are too many empowered thralls.") @@ -644,7 +646,7 @@ thrallToRevive.visible_message("[thrallToRevive] slowly rises, no longer recognizable as human.", \ "You feel new power flow into you. You have been gifted by your masters. You now closely resemble them. You are empowered in \ darkness but wither slowly in light. In addition, you now have glare and true shadow walk.") - thrallToRevive.set_species("Lesser Shadowling") + thrallToRevive.set_species(/datum/species/shadow/ling/lesser) thrallToRevive.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk) thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare(null)) thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk(null)) diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 4239b5db327..03780f7a47e 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -91,7 +91,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(user), slot_gloves) H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(user), slot_wear_mask) H.equip_to_slot_or_del(new /obj/item/clothing/glasses/shadowling(user), slot_glasses) - H.set_species("Shadowling") //can't be a shadowling without being a shadowling + H.set_species(/datum/species/shadow/ling) //can't be a shadowling without being a shadowling H.mind.RemoveSpell(src) diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index c9dad5c510d..6d82f6c48e1 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -239,7 +239,7 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user scramble(1, H, 100) - H.real_name = random_name(H.gender, H.species.name) //Give them a name that makes sense for their species. + H.real_name = random_name(H.gender, H.dna.species.name) //Give them a name that makes sense for their species. H.sync_organ_dna(assimilate = 1) H.update_body(0) H.reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover. diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 7c1a3526002..2ac4bc0b2f8 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -321,11 +321,11 @@ var/global/list/multiverse = list() to_chat(M, "You are an alternate version of [user.real_name] from another universe! Help [user.p_them()] accomplish [user.p_their()] goals at all costs.") M.faction = list("[user.real_name]") if(duplicate_self) - M.set_species(user.get_species()) //duplicate the sword user's species. + M.set_species(user.dna.species.type) //duplicate the sword user's species. else if(prob(50)) - var/list/all_species = list("Human","Unathi","Skrell","Tajaran","Kidan","Golem","Diona","Machine","Slime People","Grey","Vulpkanin") - M.set_species(pick(all_species)) + var/list/list_all_species = list(/datum/species/human, /datum/species/unathi, /datum/species/skrell, /datum/species/tajaran, /datum/species/kidan, /datum/species/golem, /datum/species/diona, /datum/species/machine, /datum/species/slime, /datum/species/grey, /datum/species/vulpkanin) + M.set_species(pick(list_all_species)) M.real_name = user.real_name //this is clear down here in case the user happens to become a golem; that way they have the proper name. M.name = user.real_name if(duplicate_self) @@ -429,7 +429,7 @@ var/global/list/multiverse = list() M.equip_to_slot_or_del(sword, slot_r_hand) //Don't duplicate what's equipped to hands, or else duplicate swords could be generated...or weird cases of factionless swords. else - if(M.get_species() == "Tajaran" || M.get_species() == "Unathi") + if(istajaran(M) || isunathi(M)) M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes) //If they can't wear shoes, give them a pair of sandals. var/randomize = pick("mobster","roman","wizard","cyborg","syndicate","assistant", "animu", "cultist", "highlander", "clown", "killer", "pirate", "soviet", "officer", "gladiator") @@ -461,7 +461,7 @@ var/global/list/multiverse = list() M.equip_to_slot_or_del(sword, slot_r_hand) if("cyborg") - if(M.get_species() != "Machine") + if(!ismachine(M)) for(var/obj/item/organ/O in M.bodyparts) O.robotize(make_tough = 1) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) @@ -584,10 +584,10 @@ var/global/list/multiverse = list() W.SetOwnerInfo(M) M.equip_to_slot_or_del(W, slot_wear_id) - if(M.get_species() == "Vox") - M.species.after_equip_job(null, M) //Voxygen(tm) - if(M.get_species() == "Plasmaman") - M.species.after_equip_job(null, M) //No fireballs from other dimensions. + if(isvox(M)) + M.dna.species.after_equip_job(null, M) //Nitrogen tanks + if(isplasmaman(M)) + M.dna.species.after_equip_job(null, M) //No fireballs from other dimensions. M.update_icons() @@ -646,7 +646,7 @@ var/global/list/multiverse = list() if(heresy) spawnheresy(M)//oh god why else - M.set_species("Skeleton") + M.set_species(/datum/species/skeleton) M.visible_message(" A massive amount of flesh sloughs off [M] and a skeleton rises up!") M.revive() equip_skeleton(M) @@ -713,7 +713,7 @@ var/global/list/multiverse = list() H.equip_to_slot_or_del(new /obj/item/twohanded/spear(H), slot_back) /obj/item/necromantic_stone/proc/spawnheresy(mob/living/carbon/human/H as mob) - H.set_species("Human") + H.set_species(/datum/species/human) if(H.gender == MALE) H.change_gender(FEMALE) diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index b5e798b95c7..18dda0fcbc4 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -141,7 +141,7 @@ wizard_mob.equip_to_slot_or_del(new /obj/item/radio/headset(wizard_mob), slot_l_ear) wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform) wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes) - if(wizard_mob.get_species() != "Plasmaman") //handled in the species file for plasmen on the afterjob equip proc for now + if(!isplasmaman(wizard_mob)) //handled in the species file for plasmen on the afterjob equip proc for now wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit) wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head) wizard_mob.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel(wizard_mob), slot_back) @@ -153,7 +153,7 @@ wizard_mob.faction = list("wizard") - wizard_mob.species.after_equip_job(null, wizard_mob) + wizard_mob.dna.species.after_equip_job(null, wizard_mob) to_chat(wizard_mob, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.") to_chat(wizard_mob, "The spellbook is bound to you, and others cannot use it.") diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index ffcb288c1c5..418539b5bed 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -74,12 +74,12 @@ if(!H) return 0 - H.species.before_equip_job(src, H, visualsOnly) + H.dna.species.before_equip_job(src, H, visualsOnly) if(outfit) H.equipOutfit(outfit, visualsOnly) - H.species.after_equip_job(src, H, visualsOnly) + H.dna.species.after_equip_job(src, H, visualsOnly) if(!visualsOnly && announce) announce(H) @@ -183,7 +183,7 @@ else permitted = TRUE - if(G.whitelisted && (G.whitelisted != H.species.name || !is_alien_whitelisted(H, G.whitelisted))) + if(G.whitelisted && (G.whitelisted != H.dna.species.name || !is_alien_whitelisted(H, G.whitelisted))) permitted = FALSE if(!permitted) diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 154a34750cd..5c4c559a8b0 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -244,7 +244,7 @@ if(visualsOnly) return - if(H.get_species() == "Machine") + if(ismachine(H)) var/obj/item/organ/internal/cyberimp/brain/clown_voice/implant = new implant.insert(H) diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm index b065c87b8ab..4876c904de7 100644 --- a/code/game/machinery/Freezer.dm +++ b/code/game/machinery/Freezer.dm @@ -57,9 +57,10 @@ if(exchange_parts(user, I)) return - default_deconstruction_crowbar(I) + if(default_deconstruction_crowbar(I)) + return - if(istype(I, /obj/item/wrench)) + if(iswrench(I)) if(!panel_open) to_chat(user, "Open the maintenance panel first.") return @@ -75,6 +76,8 @@ break build_network() update_icon() + else + return ..() /obj/machinery/atmospherics/unary/cold_sink/freezer/update_icon() if(panel_open) @@ -216,9 +219,10 @@ if(exchange_parts(user, I)) return - default_deconstruction_crowbar(I) + if(default_deconstruction_crowbar(I)) + return - if(istype(I, /obj/item/wrench)) + if(iswrench(I)) if(!panel_open) to_chat(user, "Open the maintenance panel first.") return @@ -234,6 +238,8 @@ break build_network() update_icon() + else + return ..() /obj/machinery/atmospherics/unary/heat_reservoir/heater/update_icon() if(panel_open) diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index f7925fecda5..360d5cc5aff 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -142,19 +142,20 @@ take_victim(usr,usr) -/obj/machinery/optable/attackby(obj/item/W as obj, mob/living/carbon/user as mob, params) - if(istype(W, /obj/item/grab)) - if(iscarbon(W:affecting)) - take_victim(W:affecting,usr) - qdel(W) - return - if(istype(W, /obj/item/wrench)) - playsound(src.loc, W.usesound, 50, 1) - if(do_after(user, 20 * W.toolspeed, target = src)) +/obj/machinery/optable/attackby(obj/item/I, mob/living/carbon/user, params) + if(istype(I, /obj/item/grab)) + var/obj/item/grab/G = I + if(iscarbon(G.affecting)) + take_victim(G.affecting, user) + qdel(G) + if(iswrench(I)) + playsound(loc, I.usesound, 50, 1) + if(do_after(user, 20 * I.toolspeed, target = src)) to_chat(user, "You deconstruct the table.") new /obj/item/stack/sheet/plasteel(loc, 5) qdel(src) - + else + return ..() /obj/machinery/optable/proc/check_table(mob/living/carbon/patient as mob) if(src.victim && get_turf(victim) == get_turf(src) && victim.lying) diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index a90bc66bce3..f3701945017 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -43,19 +43,21 @@ QDEL_NULL(storedpda) return ..() -/obj/machinery/pdapainter/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(istype(O, /obj/item/pda)) +/obj/machinery/pdapainter/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/pda)) if(storedpda) to_chat(user, "There is already a PDA inside.") return else - var/obj/item/pda/P = usr.get_active_hand() + var/obj/item/pda/P = user.get_active_hand() if(istype(P)) - user.drop_item() - storedpda = P - P.loc = src - P.add_fingerprint(usr) - update_icon() + if(user.drop_item()) + storedpda = P + P.forceMove(src) + P.add_fingerprint(user) + update_icon() + else + return ..() /obj/machinery/pdapainter/attack_hand(mob/user as mob) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 24311a8b12e..44ef4ee26da 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -11,7 +11,7 @@ var/base_icon = "sleeper" density = 1 anchored = 1 - dir = 8 + dir = WEST var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r" var/mob/living/carbon/human/occupant = null var/possible_chems = list(list("epinephrine", "ether", "salbutamol", "styptic_powder", "silver_sulfadiazine"), @@ -92,15 +92,15 @@ if(filtering > 0) if(beaker) // To prevent runtimes from drawing blood from runtime, and to prevent getting IPC blood. - if(!istype(occupant) || !occupant.dna || (NO_BLOOD in occupant.species.species_traits)) + if(!istype(occupant) || !occupant.dna || (NO_BLOOD in occupant.dna.species.species_traits)) filtering = 0 return if(beaker.reagents.total_volume < beaker.reagents.maximum_volume) - src.occupant.transfer_blood_to(beaker, 1) - for(var/datum/reagent/x in src.occupant.reagents.reagent_list) - src.occupant.reagents.trans_to(beaker, 3) - src.occupant.transfer_blood_to(beaker, 1) + occupant.transfer_blood_to(beaker, 1) + for(var/datum/reagent/x in occupant.reagents.reagent_list) + occupant.reagents.trans_to(beaker, 3) + occupant.transfer_blood_to(beaker, 1) if(occupant) for(var/A in occupant.reagents.addiction_list) @@ -117,7 +117,7 @@ if(M == occupant) continue else - M.forceMove(src.loc) + M.forceMove(loc) updateDialog() return @@ -167,10 +167,10 @@ occupantData["maxTemp"] = 1000 // If you get a burning vox armalis into the sleeper, congratulations // Because we can put simple_animals in here, we need to do something tricky to get things working nice occupantData["temperatureSuitability"] = 0 // 0 is the baseline - if(ishuman(occupant) && occupant.species) + if(ishuman(occupant) && occupant.dna.species) // I wanna do something where the bar gets bluer as the temperature gets lower // For now, I'll just use the standard format for the temperature status - var/datum/species/sp = occupant.species + var/datum/species/sp = occupant.dna.species if(occupant.bodytemperature < sp.cold_level_3) occupantData["temperatureSuitability"] = -3 else if(occupant.bodytemperature < sp.cold_level_2) @@ -197,7 +197,7 @@ crisis = (occupant.health < min_health) // I'm not sure WHY you'd want to put a simple_animal in a sleeper, but precedent is precedent // Runtime is aptly named, isn't she? - if(ishuman(occupant) && !(NO_BLOOD in occupant.species.species_traits)) + if(ishuman(occupant) && !(NO_BLOOD in occupant.dna.species.species_traits)) occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL) occupantData["hasBlood"] = 1 occupantData["bloodLevel"] = round(occupant.blood_volume) @@ -253,7 +253,7 @@ to_chat(usr, "Close the maintenance panel first.") return 0 - if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) + if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) if(href_list["chemical"]) if(occupant) if(occupant.stat == DEAD) @@ -268,7 +268,7 @@ toggle_filter() if(href_list["ejectify"]) eject() - src.add_fingerprint(usr) + add_fingerprint(usr) return 1 /obj/machinery/sleeper/blob_act() @@ -280,84 +280,84 @@ return -/obj/machinery/sleeper/attackby(var/obj/item/G as obj, var/mob/user as mob, params) - if(istype(G, /obj/item/reagent_containers/glass)) +/obj/machinery/sleeper/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/reagent_containers/glass)) if(!beaker) if(!user.drop_item()) - to_chat(user, "\The [G] is stuck to you!") + to_chat(user, "[I] is stuck to you!") return - beaker = G - G.forceMove(src) - user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!") + beaker = I + I.forceMove(src) + user.visible_message("[user] adds \a [I] to [src]!", "You add \a [I] to [src]!") return else to_chat(user, "The sleeper has a beaker already.") return - if(istype(G, /obj/item/screwdriver)) - if(src.occupant) + if(isscrewdriver(I)) + if(occupant) to_chat(user, "The maintenance panel is locked.") return - default_deconstruction_screwdriver(user, "[base_icon]-o", "[base_icon]-open", G) + default_deconstruction_screwdriver(user, "[base_icon]-o", "[base_icon]-open", I) return - if(istype(G, /obj/item/wrench)) - if(src.occupant) + if(iswrench(I)) + if(occupant) to_chat(user, "The scanner is occupied.") return if(panel_open) to_chat(user, "Close the maintenance panel first.") return - if(dir == 4) + if(dir == EAST) orient = "LEFT" - dir = 8 + setDir(WEST) else orient = "RIGHT" - dir = 4 - playsound(src.loc, G.usesound, 50, 1) + setDir(EAST) + playsound(loc, I.usesound, 50, 1) return - if(exchange_parts(user, G)) + if(exchange_parts(user, I)) return - if(istype(G, /obj/item/crowbar)) - default_deconstruction_crowbar(G) + if(default_deconstruction_crowbar(I)) return - if(istype(G, /obj/item/grab)) - var/obj/item/grab/GG = G + if(istype(I, /obj/item/grab)) + var/obj/item/grab/G = I if(panel_open) to_chat(user, "Close the maintenance panel first.") return - if(!ismob(GG.affecting)) + if(!ismob(G.affecting)) return - if(src.occupant) + if(occupant) to_chat(user, "The sleeper is already occupied!") return - for(var/mob/living/carbon/slime/M in range(1,GG.affecting)) - if(M.Victim == GG.affecting) - to_chat(usr, "[GG.affecting.name] will not fit into the sleeper because [GG.affecting.p_they()] [GG.affecting.p_have()] a slime latched onto [GG.affecting.p_their()] head.") + for(var/mob/living/carbon/slime/M in range(1, G.affecting)) + if(M.Victim == G.affecting) + to_chat(user, "[G.affecting.name] will not fit into the sleeper because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.") return - visible_message("[user] starts putting [GG.affecting.name] into the sleeper.") + visible_message("[user] starts putting [G.affecting.name] into the sleeper.") - if(do_after(user, 20, target = GG.affecting)) - if(src.occupant) + if(do_after(user, 20, target = G.affecting)) + if(occupant) to_chat(user, "The sleeper is already occupied!") return - if(!GG || !GG.affecting) return - var/mob/M = GG.affecting + if(!G || !G.affecting) + return + var/mob/M = G.affecting M.forceMove(src) - src.occupant = M - src.icon_state = "[base_icon]" + occupant = M + icon_state = "[base_icon]" to_chat(M, "You feel cool air surround you. You go numb as your senses turn inward.") + add_fingerprint(user) + qdel(G) + return - src.add_fingerprint(user) - qdel(GG) - return - return + return ..() /obj/machinery/sleeper/ex_act(severity) @@ -366,21 +366,21 @@ switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return if(2.0) if(prob(50)) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return if(3.0) if(prob(25)) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return @@ -423,10 +423,10 @@ to_chat(user, "The sleeper does not offer that chemical!") return - if(src.occupant) - if(src.occupant.reagents) - if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= max_chem) - src.occupant.reagents.add_reagent(chemical, amount) + if(occupant) + if(occupant.reagents) + if(occupant.reagents.get_reagent_amount(chemical) + amount <= max_chem) + occupant.reagents.add_reagent(chemical, amount) return else to_chat(user, "You can not inject any more of this chemical.") @@ -446,8 +446,8 @@ if(usr.incapacitated()) //are you cuffed, dying, lying, stunned or other return - src.icon_state = "[base_icon]-open" - src.go_out() + icon_state = "[base_icon]-open" + go_out() add_fingerprint(usr) return @@ -505,15 +505,15 @@ visible_message("[user] starts putting [L.name] into the sleeper.") if(do_after(user, 20, target = L)) - if(src.occupant) + if(occupant) to_chat(user, "The sleeper is already occupied!") return if(!L) return L.forceMove(src) - src.occupant = L - src.icon_state = "[base_icon]" + occupant = L + icon_state = "[base_icon]" to_chat(L, "You feel cool air surround you. You go numb as your senses turn inward.") - src.add_fingerprint(user) + add_fingerprint(user) if(user.pulling == L) user.stop_pulling() return @@ -528,7 +528,7 @@ set src in oview(1) if(usr.stat != 0 || !(ishuman(usr))) return - if(src.occupant) + if(occupant) to_chat(usr, "The sleeper is already occupied!") return if(panel_open) @@ -542,17 +542,17 @@ return visible_message("[usr] starts climbing into the sleeper.") if(do_after(usr, 20, target = usr)) - if(src.occupant) + if(occupant) to_chat(usr, "The sleeper is already occupied!") return usr.stop_pulling() usr.forceMove(src) - src.occupant = usr - src.icon_state = "[base_icon]" + occupant = usr + icon_state = "[base_icon]" for(var/obj/O in src) qdel(O) - src.add_fingerprint(usr) + add_fingerprint(usr) return return diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 59009e9930f..2566cc0f410 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -2,9 +2,9 @@ name = "body scanner" icon = 'icons/obj/Cryogenic2.dmi' icon_state = "bodyscanner-open" - density = 1 - dir = 8 - anchored = 1 + density = TRUE + dir = WEST + anchored = TRUE idle_power_usage = 1250 active_power_usage = 2500 @@ -32,7 +32,7 @@ if(M == occupant) continue else - M.forceMove(src.loc) + M.forceMove(loc) /obj/machinery/bodyscanner/New() ..() @@ -54,37 +54,36 @@ component_parts += new /obj/item/stack/cable_coil(null, 2) RefreshParts() -/obj/machinery/bodyscanner/attackby(var/obj/item/G as obj, var/mob/user as mob) - if(istype(G, /obj/item/screwdriver)) - if(src.occupant) +/obj/machinery/bodyscanner/attackby(obj/item/I, mob/user) + if(isscrewdriver(I)) + if(occupant) to_chat(user, "The maintenance panel is locked.") return - default_deconstruction_screwdriver(user, "bodyscanner-o", "bodyscanner-open", G) + default_deconstruction_screwdriver(user, "bodyscanner-o", "bodyscanner-open", I) return - if(istype(G, /obj/item/wrench)) - if(src.occupant) + if(iswrench(I)) + if(occupant) to_chat(user, "The scanner is occupied.") return if(panel_open) to_chat(user, "Close the maintenance panel first.") return - if(dir == 4) - dir = 8 + if(dir == EAST) + setDir(WEST) else - dir = 4 - playsound(src.loc, G.usesound, 50, 1) + setDir(EAST) + playsound(loc, I.usesound, 50, 1) return - if(exchange_parts(user, G)) + if(exchange_parts(user, I)) return - if(istype(G, /obj/item/crowbar)) - default_deconstruction_crowbar(G) + if(default_deconstruction_crowbar(I)) return - if(istype(G, /obj/item/grab)) - var/obj/item/grab/TYPECAST_YOUR_SHIT = G + if(istype(I, /obj/item/grab)) + var/obj/item/grab/TYPECAST_YOUR_SHIT = I if(panel_open) to_chat(user, "Close the maintenance panel first.") return @@ -105,7 +104,10 @@ occupant = M icon_state = "body_scanner_1" add_fingerprint(user) - qdel(G) + qdel(TYPECAST_YOUR_SHIT) + return + + return ..() /obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/human/O, mob/user as mob) @@ -123,7 +125,7 @@ to_chat(user, "Close the maintenance panel first.") return 0 //panel open if(occupant) - to_chat(user, "\The [src] is already occupied.") + to_chat(user, "[src] is already occupied.") return 0 //occupied if(O.buckled) @@ -137,7 +139,7 @@ return 0 if(O == user) - visible_message("[user] climbs into \the [src].") + visible_message("[user] climbs into [src].") else visible_message("[user] puts [O] into the body scanner.") @@ -175,21 +177,21 @@ switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return if(2.0) if(prob(50)) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return if(3.0) if(prob(25)) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return @@ -220,7 +222,7 @@ icon_state = "bodyscannerconsole" density = 1 anchored = 1 - dir = 8 + dir = WEST idle_power_usage = 250 active_power_usage = 500 var/obj/machinery/bodyscanner/connected = null @@ -238,7 +240,7 @@ stat &= ~NOPOWER else spawn(rand(0, 15)) - src.icon_state = "bodyscannerconsole-p" + icon_state = "bodyscannerconsole-p" stat |= NOPOWER /obj/machinery/body_scanconsole/New() @@ -292,33 +294,35 @@ break -/obj/machinery/body_scanconsole/attackby(var/obj/item/G as obj, var/mob/user as mob, params) - if(istype(G, /obj/item/screwdriver)) - default_deconstruction_screwdriver(user, "bodyscannerconsole-p", "bodyscannerconsole", G) +/obj/machinery/body_scanconsole/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "bodyscannerconsole-p", "bodyscannerconsole", I)) return - if(istype(G, /obj/item/wrench)) + if(iswrench(I)) if(panel_open) to_chat(user, "Close the maintenance panel first.") return - if(dir == 4) - dir = 8 + if(dir == EAST) + setDir(WEST) else - dir = 4 - playsound(loc, G.usesound, 50, 1) + setDir(EAST) + playsound(loc, I.usesound, 50, 1) - if(exchange_parts(user, G)) + if(exchange_parts(user, I)) return - default_deconstruction_crowbar(G) + if(default_deconstruction_crowbar(I)) + return + else + return ..() -/obj/machinery/body_scanconsole/attack_ai(user as mob) +/obj/machinery/body_scanconsole/attack_ai(user) return attack_hand(user) -/obj/machinery/body_scanconsole/attack_ghost(user as mob) +/obj/machinery/body_scanconsole/attack_ghost(user) return attack_hand(user) -/obj/machinery/body_scanconsole/attack_hand(user as mob) +/obj/machinery/body_scanconsole/attack_hand(user) if(stat & (NOPOWER|BROKEN)) return @@ -326,13 +330,13 @@ to_chat(user, "Close the maintenance panel first.") return - if(!src.connected) + if(!connected) findscanner() ui_interact(user) -/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "adv_med.tmpl", "Body Scanner", 690, 600) @@ -383,7 +387,7 @@ var/bloodData[0] bloodData["hasBlood"] = 0 - if(ishuman(H) && !(NO_BLOOD in H.species.species_traits)) + if(ishuman(H) && !(NO_BLOOD in H.dna.species.species_traits)) bloodData["hasBlood"] = 1 bloodData["volume"] = H.blood_volume bloodData["percent"] = round(((H.blood_volume / BLOOD_VOLUME_NORMAL)*100)) @@ -427,7 +431,7 @@ var/organStatus[0] if(E.status & ORGAN_BROKEN) organStatus["broken"] = E.broken_description - if(E.status & ORGAN_ROBOT) + if(E.is_robotic()) organStatus["robotic"] = 1 if(E.status & ORGAN_SPLINTED) organStatus["splinted"] = 1 @@ -456,7 +460,7 @@ organData["maxHealth"] = I.max_damage organData["bruised"] = I.min_broken_damage organData["broken"] = I.min_bruised_damage - organData["robotic"] = I.robotic + organData["robotic"] = I.is_robotic() organData["dead"] = (I.status & ORGAN_DEAD) intOrganData.Add(list(organData)) @@ -475,14 +479,14 @@ return 1 if(href_list["ejectify"]) - src.connected.eject() + connected.eject() if(href_list["print_p"]) generate_printing_text() if(!(printing) && printing_text) printing = 1 - visible_message("\The [src] rattles and prints out a sheet of paper.") + visible_message("[src] rattles and prints out a sheet of paper.") var/obj/item/paper/P = new /obj/item/paper(loc) playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) P.info = "
Body Scan - [href_list["name"]]

" @@ -596,8 +600,8 @@ splint = "Splinted:" if(e.status & ORGAN_BROKEN) AN = "[e.broken_description]:" - if(e.status & ORGAN_ROBOT) - robot = "Prosthetic:" + if(e.is_robotic()) + robot = "Robotic:" if(e.open) open = "Open:" switch(e.germ_level) @@ -654,7 +658,7 @@ if(occupant.disabilities & NEARSIGHTED) dat += "Retinal misalignment detected.
" else - dat += "\The [src] is empty." + dat += "[src] is empty." else dat = " Error: No Body Scanner connected." diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index f24197009bd..de32918c068 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -973,31 +973,30 @@ playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1) return -/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob, params) - src.add_fingerprint(user) +/obj/machinery/alarm/attackby(obj/item/I, mob/user, params) + add_fingerprint(user) switch(buildstage) if(2) - if(istype(W, /obj/item/screwdriver)) // Opening that Air Alarm up. -// to_chat(user, "You pop the Air Alarm's maintence panel open.") + if(isscrewdriver(I)) // Opening that Air Alarm up. wiresexposed = !wiresexposed to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"]") update_icon() return - if(istype(W, /obj/item/wirecutters)) // cutting the wires out + if(iswirecutter(I)) // cutting the wires out if(wires.wires_status == 31) // all wires cut var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil() new_coil.amount = 5 - new_coil.loc = user.loc + new_coil.forceMove(user.loc) buildstage = 1 update_icon() - return + return - if(wiresexposed && ((istype(W, /obj/item/multitool) || istype(W, /obj/item/wirecutters)))) + if(wiresexposed && ((ismultitool(I) || iswirecutter(I)))) return attack_hand(user) - if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))// trying to unlock the interface with an ID card + if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))// trying to unlock the interface with an ID card if(stat & (NOPOWER|BROKEN)) to_chat(user, "It does nothing") return @@ -1008,13 +1007,11 @@ updateUsrDialog() else to_chat(user, "Access denied.") - - - return + return if(1) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/coil = W + if(istype(I, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/coil = I if(coil.amount < 5) to_chat(user, "You need more cable for this!") return @@ -1030,34 +1027,35 @@ first_run() return - else if(istype(W, /obj/item/crowbar)) + else if(iscrowbar(I)) to_chat(user, "You start prying out the circuit.") - playsound(get_turf(src), W.usesound, 50, 1) - if(do_after(user, 20 * W.toolspeed, target = src)) + playsound(get_turf(src), I.usesound, 50, 1) + if(do_after(user, 20 * I.toolspeed, target = src)) if(buildstage != 1) return to_chat(user, "You pry out the circuit!") var/obj/item/airalarm_electronics/circuit = new /obj/item/airalarm_electronics() - circuit.loc = user.loc + circuit.forceMove(user.loc) buildstage = 0 update_icon() return if(0) - if(istype(W, /obj/item/airalarm_electronics)) + if(istype(I, /obj/item/airalarm_electronics)) to_chat(user, "You insert the circuit!") - playsound(get_turf(src), W.usesound, 50, 1) - qdel(W) + playsound(get_turf(src), I.usesound, 50, 1) + qdel(I) buildstage = 1 update_icon() return - else if(istype(W, /obj/item/wrench)) + else if(iswrench(I)) to_chat(user, "You remove the fire alarm assembly from the wall!") new /obj/item/mounted/frame/alarm_frame(get_turf(user)) - playsound(get_turf(src), W.usesound, 50, 1) + playsound(get_turf(src), I.usesound, 50, 1) qdel(src) + return - return 0 + return ..() /obj/machinery/alarm/power_change() if(powered(power_channel)) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index b61d5513561..9ad575f74d7 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -338,6 +338,7 @@ update_flag ..() /obj/machinery/portable_atmospherics/canister/attackby(var/obj/item/W as obj, var/mob/user as mob, params) + user.changeNext_move(CLICK_CD_MELEE) if(iswelder(W) && src.destroyed) if(weld(W, user)) to_chat(user, "You salvage whats left of \the [src]") diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 0e9f261d73d..e555ee91ce8 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -6,15 +6,18 @@ use_power = 2 idle_power_usage = 5 active_power_usage = 10 - layer = 5 + layer = WALL_OBJ_LAYER + armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0) var/datum/wires/camera/wires = null // Wires datum + max_integrity = 100 + integrity_failure = 50 var/list/network = list("SS13") var/c_tag = null var/c_tag_order = 999 var/status = 1 - anchored = 1 - var/start_active = 0 //If it ignores the random chance to start broken on round start + anchored = TRUE + var/start_active = FALSE //If it ignores the random chance to start broken on round start var/invuln = null var/obj/item/camera_bug/bug = null var/obj/item/camera_assembly/assembly = null @@ -24,17 +27,14 @@ var/view_range = 7 var/short_range = 2 - var/light_disabled = 0 - var/alarm_on = 0 - var/busy = 0 - var/emped = 0 //Number of consecutive EMP's on this camera + var/busy = FALSE + var/emped = FALSE //Number of consecutive EMP's on this camera - var/toggle_message = 'sound/items/Wirecutter.ogg' + var/toggle_sound = 'sound/items/Wirecutter.ogg' /obj/machinery/camera/New() ..() wires = new(src) - assembly = new(src) assembly.state = 4 assembly.anchored = 1 @@ -46,14 +46,14 @@ /obj/machinery/camera/Initialize() ..() if(is_station_level(z) && prob(3) && !start_active) - toggle_cam() + toggle_cam(null, FALSE) wires.CutAll() /obj/machinery/camera/Destroy() - toggle_cam(null, 0) //kick anyone viewing out + toggle_cam(null, FALSE) //kick anyone viewing out QDEL_NULL(assembly) if(istype(bug)) - bug.bugged_cameras -= src.c_tag + bug.bugged_cameras -= c_tag if(bug.current == src) bug.current = null bug = null @@ -71,147 +71,124 @@ return if(!isEmpProof()) if(prob(150/severity)) - icon_state = "[initial(icon_state)]emp" + update_icon() var/list/previous_network = network network = list() cameranet.removeCamera(src) stat |= EMPED set_light(0) emped = emped+1 //Increase the number of consecutive EMP's + update_icon() var/thisemp = emped //Take note of which EMP this proc is for spawn(900) - if(loc) //qdel limbo + if(!QDELETED(src)) triggerCameraAlarm() //camera alarm triggers even if multiple EMPs are in effect. if(emped == thisemp) //Only fix it if the camera hasn't been EMP'd again network = previous_network - icon_state = initial(icon_state) stat &= ~EMPED - cancelCameraAlarm() + update_icon() if(can_use()) cameranet.addCamera(src) emped = 0 //Resets the consecutive EMP count spawn(100) if(!QDELETED(src)) cancelCameraAlarm() - for(var/mob/O in mob_list) - if(O.client && O.client.eye == src) - O.unset_machine() - O.reset_perspective(null) - to_chat(O, "The screen bursts into static.") + for(var/mob/M in player_list) + if(M.client && M.client.eye == src) + M.unset_machine() + M.reset_perspective(null) + to_chat(M, "The screen bursts into static.") ..() -/obj/machinery/camera/tesla_act(var/power)//EMP proof upgrade also makes it tesla immune +/obj/machinery/camera/tesla_act(power)//EMP proof upgrade also makes it tesla immune if(isEmpProof()) return ..() qdel(src)//to prevent bomb testing camera from exploding over and over forever -/obj/machinery/camera/ex_act(severity, target) - if(src.invuln) +/obj/machinery/camera/ex_act(severity) + if(invuln) return - else - ..() - return - -/obj/machinery/camera/blob_act() - qdel(src) - return - -/obj/machinery/camera/attack_ghost(mob/user) - if(panel_open) - wires.Interact(user) - -/obj/machinery/camera/attack_alien(mob/living/carbon/alien/humanoid/user) - if(!istype(user)) - return - user.do_attack_animation(src) - add_hiddenprint(user) - status = 0 - visible_message("\The [user] slashes at [src]!") - playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) - toggle_cam(user, 0) - + ..() /obj/machinery/camera/proc/setViewRange(num = 7) - src.view_range = num + view_range = num cameranet.updateVisibility(src, 0) -/obj/machinery/camera/attackby(obj/item/W, mob/living/user as mob, params) - var/msg = "You attach [W] into the assembly inner circuits." +/obj/machinery/camera/attackby(obj/item/I, mob/living/user, params) + var/msg = "You attach [I] into the assembly inner circuits." var/msg2 = "The camera already has that upgrade!" // DECONSTRUCTION - if(istype(W, /obj/item/screwdriver)) -// to_chat(user, "You start to [panel_open ? "close" : "open"] the camera's panel.") - //if(toggle_panel(user)) // No delay because no one likes screwdrivers trying to be hip and have a duration cooldown + if(isscrewdriver(I)) panel_open = !panel_open - user.visible_message("[user] screws the camera's panel [panel_open ? "open" : "closed"]!", - "You screw the camera's panel [panel_open ? "open" : "closed"].") - playsound(src.loc, W.usesound, 50, 1) + to_chat(user, "You screw the camera's panel [panel_open ? "open" : "closed"].") + playsound(loc, I.usesound, 50, 1) - else if((istype(W, /obj/item/wirecutters) || istype(W, /obj/item/multitool)) && panel_open) + else if((iswirecutter(I) || ismultitool(I)) && panel_open) wires.Interact(user) - else if(istype(W, /obj/item/weldingtool) && wires.CanDeconstruct()) - if(weld(W, user)) - to_chat(user, "You unweld the camera leaving it as just a frame screwed to the wall.") - if(!assembly) - assembly = new() - assembly.loc = src.loc - assembly.state = 1 - assembly.dir = src.dir - assembly.update_icon() - assembly = null - qdel(src) + else if(iswelder(I) && panel_open && wires.CanDeconstruct()) + var/obj/item/weldingtool/WT = I + if(!WT.remove_fuel(0, user)) return - else if(istype(W, /obj/item/analyzer) && panel_open) //XRay - if(!user.unEquip(W)) - to_chat(user, "[W] is stuck!") + to_chat(user, "You start to weld [src]...") + playsound(loc, WT.usesound, 50, 1) + if(do_after(user, 100 * WT.toolspeed, target = src)) + user.visible_message("[user] unwelds [src], leaving it as just a frame bolted to the wall.", + "You unweld [src], leaving it as just a frame bolted to the wall") + deconstruct(TRUE) + + else if(istype(I, /obj/item/analyzer) && panel_open) //XRay + if(!user.drop_item()) + to_chat(user, "[I] is stuck to your hand!") return if(!isXRay()) upgradeXRay() - qdel(W) + qdel(I) to_chat(user, "[msg]") else to_chat(user, "[msg2]") - else if(istype(W, /obj/item/stack/sheet/mineral/plasma) && panel_open) - if(!user.unEquip(W)) - to_chat(user, "[W] is stuck!") + else if(istype(I, /obj/item/stack/sheet/mineral/plasma) && panel_open) + if(!user.drop_item()) + to_chat(user, "[I] is stuck to your hand!") return if(!isEmpProof()) + var/obj/item/stack/sheet/mineral/plasma/P = I upgradeEmpProof() to_chat(user, "[msg]") - qdel(W) + P.use(1) else to_chat(user, "[msg2]") - else if(istype(W, /obj/item/assembly/prox_sensor) && panel_open) - if(!user.unEquip(W)) + else if(istype(I, /obj/item/assembly/prox_sensor) && panel_open) + if(!user.drop_item()) + to_chat(user, "[I] is stuck to your hand!") return if(!isMotion()) upgradeMotion() to_chat(user, "[msg]") - qdel(W) + qdel(I) else to_chat(user, "[msg2]") // OTHER - else if((istype(W, /obj/item/paper) || istype(W, /obj/item/pda)) && isliving(user)) + else if((istype(I, /obj/item/paper) || istype(I, /obj/item/pda)) && isliving(user)) var/mob/living/U = user var/obj/item/paper/X = null - var/obj/item/pda/P = null + var/obj/item/pda/PDA = null var/itemname = "" var/info = "" - if(istype(W, /obj/item/paper)) - X = W + if(istype(I, /obj/item/paper)) + X = I itemname = X.name info = X.info else - P = W - var/datum/data/pda/app/notekeeper/N = P.find_program(/datum/data/pda/app/notekeeper) + PDA = I + var/datum/data/pda/app/notekeeper/N = PDA.find_program(/datum/data/pda/app/notekeeper) if(N) - itemname = P.name + itemname = PDA.name info = N.notehtml to_chat(U, "You hold \the [itemname] up to the camera ...") U.changeNext_move(CLICK_CD_MELEE) @@ -229,37 +206,59 @@ to_chat(O, "[U] holds \a [itemname] up to one of the cameras ...") O << browse(text("[][]", itemname, info), text("window=[]", itemname)) - else if(istype(W, /obj/item/camera_bug)) - if(!src.can_use()) + else if(istype(I, /obj/item/camera_bug)) + if(!can_use()) to_chat(user, "Camera non-functional.") return - if(istype(src.bug)) + if(istype(bug)) to_chat(user, "Camera bug removed.") - src.bug.bugged_cameras -= src.c_tag - src.bug = null + bug.bugged_cameras -= c_tag + bug = null else to_chat(user, "Camera bugged.") - src.bug = W - src.bug.bugged_cameras[src.c_tag] = src + bug = I + bug.bugged_cameras[c_tag] = src - else if(istype(W, /obj/item/melee/energy/blade))//Putting it here last since it's a special case. I wonder if there is a better way to do these than type casting. - toggle_cam(user, 1) - var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread() - spark_system.set_up(5, 0, loc) - spark_system.start() - playsound(loc, W.usesound, 50, 1) - playsound(loc, "sparks", 50, 1) - visible_message("[user] has sliced the camera apart with an energy blade!") - qdel(src) - - else if(istype(W, /obj/item/laser_pointer)) - var/obj/item/laser_pointer/L = W + else if(istype(I, /obj/item/laser_pointer)) + var/obj/item/laser_pointer/L = I L.laser_act(src, user) else - ..() - return + return ..() -/obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = 1) +/obj/machinery/camera/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) + if(damage_flag == "melee" && damage_amount < 12 && !(stat & BROKEN)) + return 0 + . = ..() + +/obj/machinery/camera/obj_break(damage_flag) + if(status) + triggerCameraAlarm() + toggle_cam(null, FALSE) + wires.CutAll() + +/obj/machinery/camera/deconstruct(disassembled = TRUE) + if(disassembled) + if(!assembly) + assembly = new() + assembly.forceMove(loc) + assembly.state = 1 + assembly.setDir(dir) + assembly.update_icon() + assembly = null + else + new /obj/item/camera_assembly(loc) + new /obj/item/stack/cable_coil(loc, 2) + qdel(src) + +/obj/machinery/camera/update_icon() + if(!status) + icon_state = "[initial(icon_state)]1" + else if(stat & EMPED) + icon_state = "[initial(icon_state)]emp" + else + icon_state = "[initial(icon_state)]" + +/obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = TRUE) status = !status if(can_use()) cameranet.addCamera(src) @@ -268,10 +267,7 @@ cameranet.removeCamera(src) cameranet.updateChunk(x, y, z) var/change_msg = "deactivates" - if(!status) - icon_state = "[initial(icon_state)]1" - else - icon_state = initial(icon_state) + if(status) change_msg = "reactivates" triggerCameraAlarm() spawn(100) @@ -284,7 +280,8 @@ else visible_message("\The [src] [change_msg]!") - playsound(src.loc, toggle_message, 100, 1) + playsound(loc, toggle_sound, 100, 1) + update_icon() // now disconnect anyone using the camera //Apparently, this will disconnect anyone even if the camera was re-activated. @@ -295,16 +292,11 @@ O.reset_perspective(null) to_chat(O, "The screen bursts into static.") -/obj/machinery/camera/proc/triggerCameraAlarm(var/duration = 0) - alarm_on = 1 - motion_alarm.triggerAlarm(loc, src) +/obj/machinery/camera/proc/triggerCameraAlarm() + camera_alarm.triggerAlarm(loc, src) /obj/machinery/camera/proc/cancelCameraAlarm() - if(wires.IsIndexCut(CAMERA_WIRE_ALARM)) - return - - alarm_on = 0 - motion_alarm.clearAlarm(loc, src) + camera_alarm.clearAlarm(loc, src) /obj/machinery/camera/proc/can_use() if(!status) @@ -331,25 +323,25 @@ //If someone knows a better way to do this, let me know. -Giacom switch(i) if(NORTH) - src.dir = SOUTH + setDir(SOUTH) if(SOUTH) - src.dir = NORTH + setDir(NORTH) if(WEST) - src.dir = EAST + setDir(EAST) if(EAST) - src.dir = WEST + setDir(WEST) break //Return a working camera that can see a given mob //or null if none -/proc/seen_by_camera(var/mob/M) +/proc/seen_by_camera(mob/M) for(var/obj/machinery/camera/C in oview(4, M)) if(C.can_use()) // check if camera disabled return C break return null -/proc/near_range_camera(var/mob/M) +/proc/near_range_camera(mob/M) for(var/obj/machinery/camera/C in range(4, M)) if(C.can_use()) // check if camera disabled return C @@ -357,32 +349,15 @@ return null -/obj/machinery/camera/proc/weld(var/obj/item/weldingtool/WT, var/mob/user) - if(busy) - return 0 - if(!WT.remove_fuel(0, user)) - return 0 - - to_chat(user, "You start to weld [src]...") - playsound(src.loc, WT.usesound, 50, 1) - busy = 1 - if(do_after(user, 100 * WT.toolspeed, target = src)) - busy = 0 - if(!WT.isOn()) - return 0 - return 1 - busy = 0 - return 0 - -/obj/machinery/camera/proc/Togglelight(on=0) +/obj/machinery/camera/proc/Togglelight(on = FALSE) for(var/mob/living/silicon/ai/A in ai_list) for(var/obj/machinery/camera/cam in A.lit_cameras) if(cam == src) return if(on) - src.set_light(AI_CAMERA_LUMINOSITY) + set_light(AI_CAMERA_LUMINOSITY) else - src.set_light(0) + set_light(0) /obj/machinery/camera/proc/nano_structure() var/cam[0] diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index dc5a0141b27..8baf02088bb 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -6,7 +6,8 @@ w_class = WEIGHT_CLASS_SMALL anchored = 0 materials = list(MAT_METAL=400, MAT_GLASS=250) - + max_integrity = 150 + can_be_hit = TRUE // Motion, EMP-Proof, X-Ray var/list/obj/item/possible_upgrades = list(/obj/item/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/analyzer) var/list/upgrades = list() @@ -24,13 +25,13 @@ QDEL_LIST(upgrades) return ..() -/obj/item/camera_assembly/attackby(obj/item/W, mob/living/user, params) +/obj/item/camera_assembly/attackby(obj/item/I, mob/living/user, params) switch(state) if(0) // State 0 - if(iswrench(W) && isturf(src.loc)) - playsound(src.loc, W.usesound, 50, 1) + if(iswrench(I) && isturf(loc)) + playsound(loc, I.usesound, 50, 1) to_chat(user, "You wrench the assembly into place.") anchored = 1 state = 1 @@ -40,15 +41,15 @@ if(1) // State 1 - if(iswelder(W)) - if(weld(W, user)) + if(iswelder(I)) + if(weld(I, user)) to_chat(user, "You weld the assembly securely into place.") anchored = 1 state = 2 return - else if(iswrench(W)) - playsound(src.loc, W.usesound, 50, 1) + else if(iswrench(I)) + playsound(loc, I.usesound, 50, 1) to_chat(user, "You unattach the assembly from it's place.") anchored = 0 update_icon() @@ -57,19 +58,18 @@ if(2) // State 2 - if(iscoil(W)) - var/obj/item/stack/cable_coil/C = W + if(iscoil(I)) + var/obj/item/stack/cable_coil/C = I if(C.use(2)) to_chat(user, "You add wires to the assembly.") - playsound(loc, W.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) state = 3 else to_chat(user, "You need 2 coils of wire to wire the assembly.") return - else if(iswelder(W)) - - if(weld(W, user)) + else if(iswelder(I)) + if(weld(I, user)) to_chat(user, "You unweld the assembly from it's place.") state = 1 anchored = 1 @@ -78,8 +78,8 @@ if(3) // State 3 - if(isscrewdriver(W)) - playsound(src.loc, W.usesound, 50, 1) + if(isscrewdriver(I)) + playsound(loc, I.usesound, 50, 1) var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")) if(!input) @@ -96,8 +96,8 @@ input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag)) state = 4 - var/obj/machinery/camera/C = new(src.loc) - src.loc = C + var/obj/machinery/camera/C = new(loc) + loc = C C.assembly = src C.auto_turn() @@ -119,35 +119,36 @@ break return - else if(iswirecutter(W)) + else if(iswirecutter(I)) new/obj/item/stack/cable_coil(get_turf(src), 2) - playsound(src.loc, W.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) to_chat(user, "You cut the wires from the circuits.") state = 2 return // Upgrades! - if(is_type_in_list(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. - if(!user.unEquip(W)) - to_chat(user, "[W] is stuck!") + if(is_type_in_list(I, possible_upgrades) && !is_type_in_list(I, upgrades)) // Is a possible upgrade and isn't in the camera already. + if(!user.unEquip(I)) + to_chat(user, "[I] is stuck!") return - to_chat(user, "You attach \the [W] into the assembly inner circuits.") - upgrades += W + to_chat(user, "You attach [I] into the assembly inner circuits.") + upgrades += I user.drop_item() - W.loc = src + I.loc = src return // Taking out upgrades - else if(iscrowbar(W) && upgrades.len) + else if(iscrowbar(I) && upgrades.len) var/obj/U = locate(/obj) in upgrades if(U) to_chat(user, "You unattach an upgrade from the assembly.") - playsound(src.loc, W.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) U.loc = get_turf(src) upgrades -= U return - ..() + else + return ..() /obj/item/camera_assembly/update_icon() if(anchored) @@ -159,7 +160,7 @@ if(!anchored) ..() -/obj/item/camera_assembly/proc/weld(var/obj/item/weldingtool/WT, var/mob/living/user) +/obj/item/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user) if(busy) return 0 @@ -167,7 +168,7 @@ return 0 to_chat(user, "You start to weld the [src]..") - playsound(src.loc, WT.usesound, 50, 1) + playsound(loc, WT.usesound, 50, 1) busy = 1 if(do_after(user, 20 * WT.toolspeed, target = src)) busy = 0 @@ -176,3 +177,7 @@ return 1 busy = 0 return 0 + +/obj/item/camera_assembly/deconstruct(disassembled = TRUE) + new /obj/item/stack/sheet/metal(loc) + qdel(src) \ No newline at end of file diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 57ade18dab3..6b728f2a20b 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -36,8 +36,8 @@ if(charging) to_chat(user, "Current charge: [round(charging.percent(), 1)]%") -/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/stock_parts/cell)) +/obj/machinery/cell_charger/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/stock_parts/cell)) if(stat & BROKEN) to_chat(user, "[src] is broken!") return @@ -57,19 +57,19 @@ if(!user.drop_item()) return - W.forceMove(src) - charging = W + I.forceMove(src) + charging = I user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.") chargelevel = -1 updateicon() - else if(iswrench(W)) + else if(iswrench(I)) if(charging) to_chat(user, "Remove the cell first!") return anchored = !anchored to_chat(user, "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground") - playsound(src.loc, W.usesound, 75, 1) + playsound(src.loc, I.usesound, 75, 1) else return ..() diff --git a/code/game/machinery/chiller.dm b/code/game/machinery/chiller.dm index f48d59593ca..d2f76a7c42a 100644 --- a/code/game/machinery/chiller.dm +++ b/code/game/machinery/chiller.dm @@ -68,8 +68,8 @@ user << browse(null, "window=aircond") user.unset_machine() else - ..() - return + return ..() + /obj/machinery/space_heater/air_conditioner/attack_hand(mob/user as mob) src.add_fingerprint(user) interact(user) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index ee53fdbce8b..798a01f2bda 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -231,7 +231,7 @@ R.dna = new /datum/dna() var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) - H.set_species(R.dna.species) + H.set_species(R.dna.species.type) occupant = H if(!R.dna.real_name) //to prevent null names @@ -349,19 +349,19 @@ use_power(200) //Let's unlock this early I guess. Might be too early, needs tweaking. -/obj/machinery/clonepod/attackby(obj/item/W, mob/user, params) +/obj/machinery/clonepod/attackby(obj/item/I, mob/user, params) if(!(occupant || mess)) - if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", W)) + if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", I)) return - if(exchange_parts(user, W)) + if(exchange_parts(user, I)) return - if(default_deconstruction_crowbar(W)) + if(default_deconstruction_crowbar(I)) return - if(W.GetID()) - if(!check_access(W)) + if(I.GetID()) + if(!check_access(I)) to_chat(user, "Access Denied.") return if(!(occupant || mess)) @@ -374,34 +374,33 @@ go_out() //Removing cloning pod biomass - else if(istype(W, /obj/item/reagent_containers/food/snacks/meat)) - to_chat(user, "\The [src] processes \the [W].") - biomass += BIOMASS_MEAT_AMOUNT - user.drop_item() - qdel(W) - return - else if(istype(W, /obj/item/wrench)) + else if(istype(I, /obj/item/reagent_containers/food/snacks/meat)) + if(user.drop_item()) + to_chat(user, "[src] processes [I].") + biomass += BIOMASS_MEAT_AMOUNT + qdel(I) + else if(iswrench(I)) if(occupant) to_chat(user, "Can not do that while [src] is in use.") else if(anchored) - anchored = 0 + anchored = FALSE connected.pods -= src connected = null else - anchored = 1 - playsound(loc, W.usesound, 100, 1) + anchored = TRUE + playsound(loc, I.usesound, 100, 1) if(anchored) user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.") else user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.") - else if(istype(W, /obj/item/multitool)) - var/obj/item/multitool/M = W + else if(ismultitool(I)) + var/obj/item/multitool/M = I M.buffer = src to_chat(user, "You load connection data from [src] to [M].") return else - ..() + return ..() /obj/machinery/clonepod/emag_act(user) if(isnull(occupant)) diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 42061760d92..00bd309b21e 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -123,8 +123,8 @@ occupantData["maxTemp"] = 1000 // If you get a burning vox armalis into the sleeper, congratulations // Because we can put simple_animals in here, we need to do something tricky to get things working nice occupantData["temperatureSuitability"] = 0 // 0 is the baseline - if(ishuman(occupant) && occupant.species) - var/datum/species/sp = occupant.species + if(ishuman(occupant) && occupant.dna.species) + var/datum/species/sp = occupant.dna.species if(occupant.bodytemperature < sp.cold_level_3) occupantData["temperatureSuitability"] = -3 else if(occupant.bodytemperature < sp.cold_level_2) @@ -147,7 +147,7 @@ occupantData["btCelsius"] = occupant.bodytemperature - T0C occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32 - if(ishuman(occupant) && !(NO_BLOOD in occupant.species.species_traits)) + if(ishuman(occupant) && !(NO_BLOOD in occupant.dna.species.species_traits)) occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL) occupantData["hasBlood"] = 1 occupantData["bloodLevel"] = round(occupant.blood_volume) diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 2b3c338fa3d..67f1dba85f0 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -117,7 +117,7 @@ return laws = M.laws - if(istype(P, /obj/item/mmi) || istype(P, /obj/item/mmi/posibrain)) + if(istype(P, /obj/item/mmi)) if(!P:brainmob) to_chat(user, "Sticking an empty [P] into the frame would sort of defeat the purpose.") return diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 00f6a98f2bc..99eaeae3fe6 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -31,6 +31,7 @@ for(var/V in actions) var/datum/action/A = V A.Remove(user) + actions.Cut() if(user.client) user.reset_perspective(null) eyeobj.RemoveImages() @@ -52,6 +53,7 @@ if(current_user) current_user.unset_machine() QDEL_NULL(eyeobj) + QDEL_LIST(actions) return ..() /obj/machinery/computer/camera_advanced/on_unset_machine(mob/M) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 95aee7cb9fe..c134747cd41 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -356,15 +356,14 @@ return if(scan_brain && !can_brainscan()) return - if((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna) || (NO_SCAN in subject.species.species_traits)) + if((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna) || (NO_SCAN in subject.dna.species.species_traits)) scantemp = "Error: Unable to locate valid genetic data." SSnanoui.update_uis(src) return if(subject.get_int_organ(/obj/item/organ/internal/brain)) var/obj/item/organ/internal/brain/Brn = subject.get_int_organ(/obj/item/organ/internal/brain) if(istype(Brn)) - var/datum/species/S = all_species[Brn.dna.species] // stepladder code wooooo - if(NO_SCAN in S.species_traits) + if(NO_SCAN in Brn.dna.species.species_traits) scantemp = "Error: Subject's brain is incompatible." SSnanoui.update_uis(src) return @@ -402,10 +401,9 @@ var/obj/item/organ/B = subject.get_int_organ(/obj/item/organ/internal/brain) B.dna.check_integrity() R.dna=B.dna.Clone() - var/datum/species/S = all_species[R.dna.species] - if(NO_SCAN in S.species_traits) + if(NO_SCAN in R.dna.species.species_traits) extra_info = "Proper genetic interface not found, defaulting to genetic data of the body." - R.dna.species = subject.species.name + R.dna.species = new subject.dna.species.type R.id= copytext(md5(B.dna.real_name), 2, 6) R.name=B.dna.real_name else diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 8bdc6b87243..bcbe7a07e5d 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -22,7 +22,7 @@ var/defaultmsg = "Welcome. Please select an option." var/rebootmsg = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!" //Computer properties - var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message, 4 = chat room selection, 5 = chat room logs + var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message var/hacking = 0 // Is it being hacked into by the AI/Cyborg var/emag = 0 // When it is emagged. var/message = "System bootup complete. Please select an option." // The message that shows on the main menu. @@ -33,7 +33,6 @@ var/obj/item/pda/customrecepient = null var/customjob = "Admin" var/custommessage = "This is a test, please ignore." - var/datum/chatroom/current_chatroom = null light_color = LIGHT_COLOR_DARKGREEN @@ -129,7 +128,6 @@ dat += "
[++i]. Clear Request Console Logs
" dat += "
[++i]. Set Custom Key
" dat += "
[++i]. Send Admin Message
" - dat += "
[++i]. View Chatrooms
" else for(var/n = ++i; n <= optioncount; n++) dat += "
[n]. ---------------
" @@ -247,42 +245,6 @@ dat += {"
X
[rc.send_dpt] [rc.rec_dpt][rc.message][rc.stamp][rc.id_auth][rc.priority]"} dat += "" - //Chat room list - if(5) - dat += "
Back - Refresh

" - dat += {" - - - - - - "} - for(var/datum/chatroom/C in chatrooms) - var/list/invites = (C.invites - C.users) - dat += {" - - - - - "} - dat += "
Room NameUsersInvitesMessages
[C.name][C.users.len][invites.len][C.logs.len]
" - //View chat room logs - if(6) - dat += "
Back - Refresh

" - dat += {" - - - - "} - if(current_chatroom) - for(var/M in current_chatroom.logs) - var/list/message = M - dat += {" - - - "} - dat += "
NameMessage
[message["username"]][message["message"]]
" - dat += "" message = defaultmsg user << browse(dat, "window=message;size=700x700") @@ -520,19 +482,6 @@ if(href_list["back"]) src.screen = 0 - // View chat room list - if(href_list["chatroom"]) - if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else if(auth) - screen = 5 - if(href_list["viewroom"]) - if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else if(auth) - current_chatroom = locate(href_list["viewroom"]) - if(current_chatroom) - screen = 6 return src.attack_hand(usr) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 36a05e0442e..2cf9de49571 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -115,6 +115,7 @@ visible_message("[user] climbs into the cryo cell.") else visible_message("[user] puts [L.name] into the cryo cell.") + add_attack_logs(user, L, "put into a cryo cell at [COORD(src)].", ATKLOG_ALL) if(user.pulling == L) user.stop_pulling() @@ -262,6 +263,7 @@ if(href_list["ejectOccupant"]) if(!occupant || isslime(usr) || ispAI(usr)) return 0 // don't update UIs attached to this object + add_attack_logs(usr, occupant, "ejected from cryo cell at [COORD(src)]", ATKLOG_ALL) go_out() add_fingerprint(usr) @@ -269,16 +271,18 @@ /obj/machinery/atmospherics/unary/cryo_cell/attackby(var/obj/item/G as obj, var/mob/user as mob, params) if(istype(G, /obj/item/reagent_containers/glass)) + var/obj/item/reagent_containers/B = G if(beaker) to_chat(user, "A beaker is already loaded into the machine.") return if(!user.drop_item()) - to_chat(user, "The [G] is stuck to you!") + to_chat(user, "[B] is stuck to you!") return - G.forceMove(src) - beaker = G + B.forceMove(src) + beaker = B + add_attack_logs(user, null, "Added [B] containing [B.reagentlist()] to a cryo cell at [COORD(src)]") + user.visible_message("[user] adds \a [B] to [src]!", "You add \a [B] to [src]!") - user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!") if(istype(G, /obj/item/screwdriver)) if(occupant || on) @@ -453,6 +457,7 @@ else if(usr.incapacitated()) //are you cuffed, dying, lying, stunned or other return + add_attack_logs(usr, occupant, "Ejected from cryo cell at [COORD(src)]") go_out() add_fingerprint(usr) return diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 80db23c59f7..332dc2854e1 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -112,7 +112,7 @@ to_chat(user, "\The [I] is no longer in storage.") return - visible_message("The console beeps happily as it disgorges \the [I].") + visible_message("The console beeps happily as it disgorges [I].") dispense_item(I) @@ -120,7 +120,8 @@ if(!allowed(user)) to_chat(user, "Access Denied.") return - if(!allow_items) return + if(!allow_items) + return if(frozen_items.len == 0) to_chat(user, "There is nothing to recover from storage.") @@ -238,7 +239,7 @@ ) // These items will NOT be preserved var/list/do_not_preserve_items = list ( - /obj/item/mmi/posibrain + /obj/item/mmi/robotic_brain ) /obj/machinery/cryopod/right @@ -323,15 +324,15 @@ // Also make sure there is a valid control computer /obj/machinery/cryopod/proc/despawn_occupant() //Drop all items into the pod. - for(var/obj/item/W in occupant) - occupant.unEquip(W) - W.forceMove(src) + for(var/obj/item/I in occupant) + occupant.unEquip(I) + I.forceMove(src) - if(W.contents.len) //Make sure we catch anything not handled by qdel() on the items. - if(should_preserve_item(W) != CRYO_DESTROY) // Don't remove the contents of things that need preservation + if(I.contents.len) //Make sure we catch anything not handled by qdel() on the items. + if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation continue - for(var/obj/item/O in W.contents) - if(istype(O,/obj/item/tank)) //Stop eating pockets, you fuck! + for(var/obj/item/O in I.contents) + if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck! continue O.forceMove(src) @@ -345,23 +346,23 @@ items -= occupant // Don't delete the occupant items -= announce // or the autosay radio. - for(var/obj/item/W in items) - if(istype(W,/obj/item/pda)) - var/obj/item/pda/P = W + for(var/obj/item/I in items) + if(istype(I, /obj/item/pda)) + var/obj/item/pda/P = I QDEL_NULL(P.id) qdel(P) continue - var/preserve = should_preserve_item(W) + var/preserve = should_preserve_item(I) if(preserve == CRYO_DESTROY) - qdel(W) + qdel(I) else if(control_computer && control_computer.allow_items) - control_computer.frozen_items += W + control_computer.frozen_items += I if(preserve == CRYO_OBJECTIVE) - control_computer.objective_items += W - W.loc = null + control_computer.objective_items += I + I.loc = null else - W.forceMove(loc) + I.forceMove(loc) // Skip past any cult sacrifice objective using this person if(GAMEMODE_IS_CULT && is_sacrifice_target(occupant.mind)) @@ -461,22 +462,23 @@ #undef CRYO_PRESERVE #undef CRYO_OBJECTIVE -/obj/machinery/cryopod/attackby(var/obj/item/G as obj, var/mob/user as mob, params) +/obj/machinery/cryopod/attackby(obj/item/I, mob/user, params) - if(istype(G, /obj/item/grab)) + if(istype(I, /obj/item/grab)) + var/obj/item/grab/G = I if(occupant) - to_chat(user, "\The [src] is in use.") + to_chat(user, "[src] is in use.") return - if(!ismob(G:affecting)) + if(!ismob(G.affecting)) return - if(!check_occupant_allowed(G:affecting)) + if(!check_occupant_allowed(G.affecting)) return var/willing = null //We don't want to allow people to be forced into despawning. - var/mob/living/M = G:affecting + var/mob/living/M = G.affecting time_till_despawn = initial(time_till_despawn) if(!istype(M) || M.stat == DEAD) @@ -485,20 +487,21 @@ if(M.client) if(alert(M,"Would you like to enter long-term storage?",,"Yes","No") == "Yes") - if(!M || !G || !G:affecting) return + if(!M || !G || !G.affecting) return willing = willing_time_divisor else willing = 1 if(willing) - visible_message("[user] starts putting [G:affecting:name] into \the [src].") + visible_message("[user] starts putting [G.affecting.name] into [src].") - if(do_after(user, 20, target = G:affecting)) - if(!M || !G || !G:affecting) return + if(do_after(user, 20, target = G.affecting)) + if(!M || !G || !G.affecting) + return if(occupant) - to_chat(user, "\The [src] is in use.") + to_chat(user, "[src] is in use.") return take_occupant(M, willing) @@ -516,6 +519,8 @@ to_chat(M, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.") take_occupant(M, willing) + else + return ..() /obj/machinery/cryopod/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) @@ -567,7 +572,7 @@ if(willing) if(!Adjacent(L)) - to_chat(user, "You're not close enough to \the [src].") + to_chat(user, "You're not close enough to [src].") return if(L == user) visible_message("[user] starts climbing into the cryo pod.") @@ -633,14 +638,13 @@ if(occupant) items -= occupant if(announce) items -= announce - for(var/obj/item/W in items) - W.loc = get_turf(src) + for(var/obj/item/I in items) + I.forceMove(get_turf(src)) go_out() add_fingerprint(usr) name = initial(name) - return /obj/machinery/cryopod/verb/move_inside() set name = "Enter Pod" @@ -659,7 +663,7 @@ to_chat(usr, "You're too busy getting your life sucked out of you.") return - visible_message("[usr] starts climbing into \the [src].") + visible_message("[usr] starts climbing into [src].") if(do_after(usr, 20, target = usr)) diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index f8d7432c540..f06f7ac1b37 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -8,6 +8,20 @@ var/list/doppler_arrays = list() density = 1 anchored = 1 atom_say_verb = "states coldly" + var/list/logged_explosions = list() + +/datum/explosion_log + var/logged_time + var/epicenter + var/actual_size_message + var/theoretical_size_message + +/datum/explosion_log/New(var/log_time, var/log_epicenter, var/log_actual_size_message, var/log_theoretical_size_message) + ..() + logged_time = log_time + epicenter = log_epicenter + actual_size_message = log_actual_size_message + theoretical_size_message = log_theoretical_size_message /obj/machinery/doppler_array/New() ..() @@ -15,70 +29,122 @@ var/list/doppler_arrays = list() /obj/machinery/doppler_array/Destroy() doppler_arrays -= src + logged_explosions.Cut() return ..() /obj/machinery/doppler_array/process() return PROCESS_KILL -/obj/machinery/doppler_array/attackby(var/obj/item/O, var/mob/user, params) - if(istype(O, /obj/item/wrench)) +/obj/machinery/doppler_array/attackby(obj/item/I, mob/user, params) + if(iswrench(I)) if(!anchored && !isinspace()) - anchored = 1 + anchored = TRUE power_change() to_chat(user, "You fasten [src].") else if(anchored) - anchored = 0 + anchored = FALSE power_change() to_chat(user, "You unfasten [src].") - playsound(loc, O.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) + else + return ..() -/obj/machinery/doppler_array/verb/rotate() +/obj/machinery/doppler_array/attack_hand(mob/user) + if(..()) + return + add_fingerprint(user) + ui_interact(user) + +/obj/machinery/doppler_array/attack_ghost(mob/user) + ui_interact(user) + +/obj/machinery/doppler_array/AltClick(mob/user) + rotate(user) + +/obj/machinery/doppler_array/verb/rotate(mob/user) set name = "Rotate Tachyon-doppler Dish" set category = "Object" set src in oview(1) - if(!usr || !isturf(usr.loc)) + if(user.incapacitated()) return - if(usr.stat || usr.restrained() || !usr.canmove) + if(!Adjacent(user)) return - src.dir = turn(src.dir, 90) - return + if(!user.IsAdvancedToolUser()) + to_chat(user, "You don't have the dexterity to do that!") + return + dir = turn(dir, 90) + to_chat(user, "You rotate [src].") + +/obj/machinery/doppler_array/proc/print_explosive_logs(mob/user) + if(!logged_explosions.len) + atom_say("No logs currently stored in internal database.") + return + if(active_timers) + to_chat(user, "[src] is already printing something, please wait.") + return + atom_say("Printing explosive log. Standby...") + addtimer(CALLBACK(src, .print), 50) + +/obj/machinery/doppler_array/proc/print() + visible_message("[src] prints a piece of paper!") + playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) + var/obj/item/paper/explosive_log/P = new(get_turf(src)) + for(var/D in logged_explosions) + var/datum/explosion_log/E = D + P.info += "\ + [E.logged_time]\ + [E.epicenter]\ + [E.actual_size_message]\ + [E.theoretical_size_message]\ + " + P.info += "
\ + Printed at [station_time_timestamp()]." /obj/machinery/doppler_array/proc/sense_explosion(var/x0,var/y0,var/z0,var/devastation_range,var/heavy_impact_range,var/light_impact_range, var/took,var/orig_dev_range,var/orig_heavy_range,var/orig_light_range) - if(stat & NOPOWER) return - if(z != z0) return + if(stat & NOPOWER) + return + if(z != z0) + return var/dx = abs(x0-x) var/dy = abs(y0-y) var/distance var/direct + var/capped = FALSE if(dx > dy) distance = dx - if(x0 > x) direct = EAST - else direct = WEST + if(x0 > x) + direct = EAST + else + direct = WEST else distance = dy - if(y0 > y) direct = NORTH - else direct = SOUTH - - if(distance > 100) return - if(!(direct & dir)) return + if(y0 > y) + direct = NORTH + else + direct = SOUTH + if(distance > 100) + return + if(!(direct & dir)) + return var/list/messages = list("Explosive disturbance detected.", \ "Epicenter at: grid ([x0],[y0]). Temporal displacement of tachyons: [took] seconds.", \ "Factual: Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range].") - // If the bomb was capped, say it's theoretical size. + // If the bomb was capped, say its theoretical size. if(devastation_range < orig_dev_range || heavy_impact_range < orig_heavy_range || light_impact_range < orig_light_range) + capped = TRUE messages += "Theoretical: Epicenter radius: [orig_dev_range]. Outer radius: [orig_heavy_range]. Shockwave radius: [orig_light_range]." - + logged_explosions.Insert(1, new /datum/explosion_log(station_time_timestamp(), "[x0],[y0]", "[devastation_range], [heavy_impact_range], [light_impact_range]", capped ? "[orig_dev_range], [orig_heavy_range], [orig_light_range]" : "n/a")) //Newer logs appear first + messages += "Event successfully logged in internal database." for(var/message in messages) atom_say(message) - /obj/machinery/doppler_array/power_change() if(stat & BROKEN) icon_state = "[initial(icon_state)]-broken" @@ -88,4 +154,55 @@ var/list/doppler_arrays = list() stat &= ~NOPOWER else icon_state = "[initial(icon_state)]-off" - stat |= NOPOWER \ No newline at end of file + stat |= NOPOWER + +/obj/machinery/doppler_array/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "doppler_array.tmpl", "Tachyon-doppler array", 500, 650) + ui.open() + ui.set_auto_update(1) + +/obj/machinery/doppler_array/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state) + var/data[0] + var/list/explosion_data = list() + for(var/D in logged_explosions) + var/datum/explosion_log/E = D + explosion_data += list(list( + "logged_time" = E.logged_time, + "epicenter" = E.epicenter, + "actual_size_message" = E.actual_size_message, + "theoretical_size_message" = E.theoretical_size_message, + "unique_datum_id" = E.UID())) + data["explosion_data"] = explosion_data + data["printing"] = active_timers + return data + +/obj/machinery/doppler_array/Topic(href, href_list) + if(..()) + return + if(href_list["log_to_delete"]) + var/log_to_delete = sanitize(href_list["log_to_delete"]) + for(var/D in logged_explosions) + var/datum/explosion_log/E = D + if(E.UID() == log_to_delete) + logged_explosions -= E + qdel(E) + to_chat(usr, "Log deletion successful.") + break + else if(href_list["print_logs"]) + print_explosive_logs(usr) + else + return + SSnanoui.update_uis(src) + +/obj/item/paper/explosive_log + name = "explosive log" + info = "

Explosive Log Report

\ + \ + \ + \ + \ + \ + \ + " //NB: the
Time loggedEpicenterActualTheoretical
tag is left open, it is closed later on, when the doppler array adds its data diff --git a/code/game/machinery/dye_generator.dm b/code/game/machinery/dye_generator.dm index bb47a4939ec..52b11da599b 100644 --- a/code/game/machinery/dye_generator.dm +++ b/code/game/machinery/dye_generator.dm @@ -41,7 +41,7 @@ stat |= BROKEN icon_state = "[initial(icon_state)]-broken" -/obj/machinery/dye_generator/attack_hand(mob/user as mob) +/obj/machinery/dye_generator/attack_hand(mob/user) ..() src.add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) @@ -50,18 +50,18 @@ dye_color = temp set_light(2, l_color = temp) -/obj/machinery/dye_generator/attackby(obj/item/W, mob/user, params) +/obj/machinery/dye_generator/attackby(obj/item/I, mob/user, params) - if(default_unfasten_wrench(user, W, time = 60)) + if(default_unfasten_wrench(user, I, time = 60)) return - if(istype(W, /obj/item/hair_dye_bottle)) - user.visible_message("[user] fills the [W] up with some dye.","You fill the [W] up with some hair dye.") - var/obj/item/hair_dye_bottle/HD = W + if(istype(I, /obj/item/hair_dye_bottle)) + var/obj/item/hair_dye_bottle/HD = I + user.visible_message("[user] fills the [HD] up with some dye.","You fill the [HD] up with some hair dye.") HD.dye_color = dye_color HD.update_dye_overlay() else - ..() + return ..() //Hair Dye Bottle @@ -87,7 +87,7 @@ I.color = dye_color overlays += I -/obj/item/hair_dye_bottle/attack(mob/living/carbon/M as mob, mob/user as mob) +/obj/item/hair_dye_bottle/attack(mob/living/carbon/M, mob/user) if(user.a_intent != INTENT_HELP) ..() return @@ -98,11 +98,11 @@ var/mob/living/carbon/human/H = M var/dye_list = list("hair", "alt. hair theme") - if(H.gender == MALE || H.get_species() == "Vulpkanin") + if(H.gender == MALE || isvulpkanin(H)) dye_list += "facial hair" dye_list += "alt. facial hair theme" - if(H && (H.species.bodyflags & HAS_SKIN_COLOR)) + if(H && (H.dna.species.bodyflags & HAS_SKIN_COLOR)) dye_list += "body" var/what_to_dye = input(user, "Choose an area to apply the dye", "Dye Application") in dye_list diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 8cb98021576..b3664c58cd6 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -45,7 +45,7 @@ FIRE ALARM /obj/machinery/firealarm/emag_act(mob/user) if(!emagged) - emagged = 1 + emagged = TRUE if(user) user.visible_message("Sparks fly out of the [src]!", "You emag [src], disabling its thermal sensors.") @@ -62,19 +62,15 @@ FIRE ALARM /obj/machinery/firealarm/attack_ghost(mob/user) ui_interact(user) -/obj/machinery/firealarm/bullet_act(BLAH) - return alarm() - - /obj/machinery/firealarm/emp_act(severity) if(prob(50/severity)) alarm(rand(30/severity, 60/severity)) ..() -/obj/machinery/firealarm/attackby(obj/item/W, mob/user, params) +/obj/machinery/firealarm/attackby(obj/item/I, mob/user, params) add_fingerprint(user) - if(istype(W, /obj/item/screwdriver) && buildstage == 2) + if(iswirecutter(I) && buildstage == 2) wiresexposed = !wiresexposed update_icon() return @@ -82,37 +78,37 @@ FIRE ALARM if(wiresexposed) switch(buildstage) if(2) - if(istype(W, /obj/item/multitool)) + if(ismultitool(I)) detecting = !detecting if(detecting) user.visible_message("[user] has reconnected [src]'s detecting unit!", "You have reconnected [src]'s detecting unit.") else user.visible_message("[user] has disconnected [src]'s detecting unit!", "You have disconnected [src]'s detecting unit.") - else if(istype(W, /obj/item/wirecutters)) // cutting the wires out + else if(iswirecutter(I)) // cutting the wires out to_chat(user, "You cut the wires!") - playsound(loc, W.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil() new_coil.amount = 5 - new_coil.loc = user.loc + new_coil.forceMove(user.loc) buildstage = 1 update_icon() if(1) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/coil = W + if(istype(I, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/coil = I if(!coil.use(5)) to_chat(user, "You cut the wires!") return buildstage = 2 - playsound(get_turf(src), W.usesound, 50, 1) - to_chat(user, "You wire \the [src]!") + playsound(get_turf(src), I.usesound, 50, 1) + to_chat(user, "You wire [src]!") update_icon() - else if(istype(W, /obj/item/crowbar)) + else if(iscrowbar(I)) to_chat(user, "You pry out the circuit!") - playsound(get_turf(src), W.usesound, 50, 1) - if(do_after(user, 20 * W.toolspeed, target = src)) + playsound(get_turf(src), I.usesound, 50, 1) + if(do_after(user, 20 * I.toolspeed, target = src)) if(buildstage != 1) return var/obj/item/firealarm_electronics/circuit = new /obj/item/firealarm_electronics() @@ -120,20 +116,20 @@ FIRE ALARM buildstage = 0 update_icon() if(0) - if(istype(W, /obj/item/firealarm_electronics)) + if(istype(I, /obj/item/firealarm_electronics)) to_chat(user, "You insert the circuit!") - qdel(W) + qdel(I) buildstage = 1 update_icon() - else if(istype(W, /obj/item/wrench)) + else if(iswrench(I)) to_chat(user, "You remove the fire alarm assembly from the wall!") new /obj/item/mounted/frame/firealarm(get_turf(user)) - playsound(get_turf(src), W.usesound, 50, 1) + playsound(get_turf(src), I.usesound, 50, 1) qdel(src) - return - alarm() + else + return ..() /obj/machinery/firealarm/process()//Note: this processing was mostly phased out due to other code, and only runs when needed if(stat & (NOPOWER|BROKEN)) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 2b0691d5801..7a13b0bf796 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -38,14 +38,16 @@ // sd_set_light(0) //Don't want to render prison breaks impossible -/obj/machinery/flasher/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/wirecutters)) +/obj/machinery/flasher/attackby(obj/item/I, mob/user, params) + if(iswirecutter(I)) add_fingerprint(user) disable = !disable if(disable) - user.visible_message("[user] has disconnected the [src]'s flashbulb!", "You disconnect the [src]'s flashbulb!") + user.visible_message("[user] has disconnected [src]'s flashbulb!", "You disconnect [src]'s flashbulb!") if(!disable) - user.visible_message("[user] has connected the [src]'s flashbulb!", "You connect the [src]'s flashbulb!") + user.visible_message("[user] has connected [src]'s flashbulb!", "You connect [src]'s flashbulb!") + else + return ..() //Let the AI trigger them directly. /obj/machinery/flasher/attack_ai(mob/user) @@ -95,8 +97,8 @@ if((M.m_intent != MOVE_INTENT_WALK) && (anchored)) flash() -/obj/machinery/flasher/portable/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/wrench)) +/obj/machinery/flasher/portable/attackby(obj/item/I, mob/user, params) + if(iswrench(I)) add_fingerprint(user) anchored = !anchored @@ -107,6 +109,8 @@ else if(anchored) user.show_message(text("[src] is now secured.")) overlays += "[base_state]-s" + else + return ..() // Flasher button /obj/machinery/flasher_button diff --git a/code/game/machinery/gameboard.dm b/code/game/machinery/gameboard.dm index f1bd8b65a10..526a935cf90 100644 --- a/code/game/machinery/gameboard.dm +++ b/code/game/machinery/gameboard.dm @@ -93,8 +93,11 @@ if(href_list["close"]) close_game() -/obj/machinery/gameboard/attackby(var/obj/item/G as obj, var/mob/user as mob, params) - if(istype(G, /obj/item/wrench)) - default_unfasten_wrench(user, G) - else if(istype(G, /obj/item/crowbar)) - default_deconstruction_crowbar(G, ignore_panel = 1) +/obj/machinery/gameboard/attackby(obj/item/I, mob/user, params) + if(default_unfasten_wrench(user, I)) + return + + if(default_deconstruction_crowbar(I, ignore_panel = TRUE)) + return + else + return ..() \ No newline at end of file diff --git a/code/game/machinery/guestpass.dm b/code/game/machinery/guestpass.dm index 6d90de7bf4d..450260f5f79 100644 --- a/code/game/machinery/guestpass.dm +++ b/code/game/machinery/guestpass.dm @@ -48,20 +48,22 @@ var/list/internal_log = list() var/mode = 0 // 0 - making pass, 1 - viewing logs -/obj/machinery/computer/guestpass/attackby(obj/O, mob/user, params) - if(istype(O, /obj/item/card/id)) +/obj/machinery/computer/guestpass/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/card/id)) if(!giver) - user.drop_item() - O.loc = src - giver = O - updateUsrDialog() + if(user.drop_item()) + I.forceMove(src) + giver = I + updateUsrDialog() else to_chat(user, "There is already ID card inside.") + else + return ..() /obj/machinery/computer/guestpass/proc/get_changeable_accesses() return giver.access -/obj/machinery/computer/guestpass/attack_ai(var/mob/user as mob) +/obj/machinery/computer/guestpass/attack_ai(mob/user) return attack_hand(user) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 0fc532ab0e4..bda66a55622 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -91,17 +91,20 @@ var/list/holopads = list() holograph_range += 1 * B.rating holo_range = holograph_range -/obj/machinery/hologram/holopad/attackby(obj/item/P as obj, mob/user as mob, params) - if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", P)) +/obj/machinery/hologram/holopad/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", I)) return - if(exchange_parts(user, P)) + if(exchange_parts(user, I)) return - if(default_unfasten_wrench(user, P)) + if(default_unfasten_wrench(user, I)) return - default_deconstruction_crowbar(P) + if(default_deconstruction_crowbar(I)) + return + else + return ..() /obj/machinery/hologram/holopad/attack_hand(mob/living/carbon/human/user) diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 411543b662f..22d1177c437 100755 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -68,21 +68,23 @@ icon_state = "[base_state]-p" // src.sd_set_light(0) -/obj/machinery/sparker/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/detective_scanner)) +/obj/machinery/sparker/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/detective_scanner)) return - if(istype(W, /obj/item/screwdriver)) + if(isscrewdriver(I)) add_fingerprint(user) - src.disable = !src.disable - if(src.disable) - user.visible_message("[user] has disabled the [src]!", "You disable the connection to the [src].") + disable = !disable + if(disable) + user.visible_message("[user] has disabled [src]!", "You disable the connection to [src].") icon_state = "[base_state]-d" - if(!src.disable) - user.visible_message("[user] has reconnected the [src]!", "You fix the connection to the [src].") - if(src.powered()) + if(!disable) + user.visible_message("[user] has reconnected [src]!", "You fix the connection to [src].") + if(powered()) icon_state = "[base_state]" else icon_state = "[base_state]-p" + else + return ..() /obj/machinery/sparker/attack_ai() if(src.anchored) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index d7a4a3e2b04..4ccaa246578 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -88,17 +88,17 @@ to_chat(usr, "There's nothing attached to the IV drip!") -/obj/machinery/iv_drip/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers)) +/obj/machinery/iv_drip/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/reagent_containers)) if(beaker) to_chat(user, "There is already a reagent container loaded!") return if(!user.drop_item()) return - W.forceMove(src) - beaker = W - to_chat(user, "You attach [W] to [src].") + I.forceMove(src) + beaker = I + to_chat(user, "You attach [I] to [src].") update_icon() else return ..() diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 18fc505a49b..aef8de7c306 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -117,7 +117,7 @@ Class Procs: var/use_log = list() var/list/settagwhitelist = list()//WHITELIST OF VARIABLES THAT THE set_tag HREF CAN MODIFY, DON'T PUT SHIT YOU DON'T NEED ON HERE, AND IF YOU'RE GONNA USE set_tag (format_tag() proc), ADD TO THIS LIST. atom_say_verb = "beeps" - var/speed_process = 0 // Process as fast as possible? + var/defer_process = 0 /obj/machinery/Initialize() addAtProcessing() @@ -128,13 +128,16 @@ Class Procs: if(use_power) myArea = get_area_master(src) if(!speed_process) - START_PROCESSING(SSmachines, src) + if(!defer_process) + START_PROCESSING(SSmachines, src) + else + START_DEFERRED_PROCESSING(SSmachines, src) else fast_processing += src isprocessing = TRUE // all of these isprocessing = TRUE can be removed when the PS is dead // gotta go fast -/obj/machinery/proc/makeSpeedProcess() +/obj/machinery/makeSpeedProcess() if(speed_process) return speed_process = 1 @@ -143,7 +146,7 @@ Class Procs: isprocessing = TRUE // gotta go slow -/obj/machinery/proc/makeNormalProcess() +/obj/machinery/makeNormalProcess() if(!speed_process) return speed_process = 0 @@ -558,7 +561,7 @@ Class Procs: if(istype(perp.belt, /obj/item/gun) || istype(perp.belt, /obj/item/melee)) threatcount += 2 - if(perp.species.name != "Human") //beepsky so racist. + if(!ishumanbasic(perp)) //beepsky so racist. threatcount += 2 if(check_records || check_arrest) diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index ee4f2e6eb62..116a0f8dbe1 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -97,17 +97,18 @@ updateicon() - else if(istype(I, /obj/item/card/id)||istype(I, /obj/item/pda)) + else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda)) if(open) - if(src.allowed(user)) - src.locked = !src.locked - to_chat(user, "Controls are now [src.locked ? "locked" : "unlocked"].") + if(allowed(user)) + locked = !locked + to_chat(user, "Controls are now [locked ? "locked" : "unlocked"].") else to_chat(user, "Access denied.") updateDialog() else to_chat(user, "You must open the cover first!") - return + else + return ..() /obj/machinery/navbeacon/attack_ai(mob/user) interact(user, 1) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 2d5a885aba1..270b2a99411 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -1,44 +1,3 @@ -#define PIPE_SIMPLE_STRAIGHT 0 -#define PIPE_SIMPLE_BENT 1 -#define PIPE_HE_STRAIGHT 2 -#define PIPE_HE_BENT 3 -#define PIPE_CONNECTOR 4 -#define PIPE_MANIFOLD 5 -#define PIPE_JUNCTION 6 -#define PIPE_UVENT 7 -#define PIPE_MVALVE 8 -#define PIPE_PUMP 9 -#define PIPE_SCRUBBER 10 -#define PIPE_INSULATED_STRAIGHT 11 -#define PIPE_INSULATED_BENT 12 -#define PIPE_GAS_FILTER 13 -#define PIPE_GAS_MIXER 14 -#define PIPE_PASSIVE_GATE 15 -#define PIPE_VOLUME_PUMP 16 -#define PIPE_HEAT_EXCHANGE 17 -#define PIPE_TVALVE 18 -#define PIPE_MANIFOLD4W 19 -#define PIPE_CAP 20 -#define PIPE_OMNI_MIXER 21 -#define PIPE_OMNI_FILTER 22 -#define PIPE_UNIVERSAL 23 -#define PIPE_SUPPLY_STRAIGHT 24 -#define PIPE_SUPPLY_BENT 25 -#define PIPE_SCRUBBERS_STRAIGHT 26 -#define PIPE_SCRUBBERS_BENT 27 -#define PIPE_SUPPLY_MANIFOLD 28 -#define PIPE_SCRUBBERS_MANIFOLD 29 -#define PIPE_SUPPLY_MANIFOLD4W 30 -#define PIPE_SCRUBBERS_MANIFOLD4W 31 -#define PIPE_SUPPLY_CAP 32 -#define PIPE_SCRUBBERS_CAP 33 -#define PIPE_INJECTOR 34 -#define PIPE_DVALVE 35 -#define PIPE_DP_VENT 36 -#define PIPE_PASV_VENT 37 -#define PIPE_DTVALVE 38 -#define PIPE_CIRCULATOR 39 - /obj/item/pipe name = "pipe" desc = "A pipe" @@ -180,93 +139,19 @@ //update the name and icon of the pipe item depending on the type +/obj/item/pipe/rpd_act(mob/user, obj/item/rpd/our_rpd) + if(our_rpd.mode == RPD_ROTATE_MODE) + rotate() + else if(our_rpd.mode == RPD_FLIP_MODE) + flip() + else if(our_rpd.mode == RPD_DELETE_MODE) + our_rpd.delete_single_pipe(user, src) + else + ..() + /obj/item/pipe/proc/update(var/obj/machinery/atmospherics/make_from) - var/list/nlist = list( \ - "pipe", \ - "bent pipe", \ - "h/e pipe", \ - "bent h/e pipe", \ - "connector", \ - "manifold", \ - "junction", \ - "uvent", \ - "mvalve", \ - "pump", \ - "scrubber", \ - "insulated pipe", \ - "bent insulated pipe", \ - "gas filter", \ - "gas mixer", \ - "passive gate", \ - "volume pump", \ - "heat exchanger", \ - "t-valve", \ - "4-way manifold", \ - "pipe cap", \ - "omni mixer", \ - "omni filter", \ - "universal pipe adapter", \ - "supply pipe", \ - "bent supply pipe", \ - "scrubbers pipe", \ - "bent scrubbers pipe", \ - "supply manifold", \ - "scrubbers manifold", \ - "supply 4-way manifold", \ - "scrubbers 4-way manifold", \ - "supply pipe cap", \ - "scrubbers pipe cap", \ - "air injector", \ - "digital valve", \ - "dual-port vent", \ - "passive vent", \ - "digital t-valve", \ - "circulator/heat exchanger", \ - ) - name = nlist[pipe_type+1] + " fitting" - var/list/islist = list( \ - "simple", \ - "simple", \ - "he", \ - "he", \ - "connector", \ - "manifold", \ - "junction", \ - "uvent", \ - "mvalve", \ - "pump", \ - "scrubber", \ - "insulated", \ - "insulated", \ - "filter", \ - "mixer", \ - "passivegate", \ - "volumepump", \ - "heunary", \ - "tvalve", \ - "manifold4w", \ - "cap", \ - "omni_mixer", \ - "omni_filter", \ - "universal", \ - "simple", \ - "simple", \ - "simple", \ - "simple", \ - "manifold", \ - "manifold", \ - "manifold4w", \ - "manifold4w", \ - "cap", \ - "cap", \ - "injector", \ - "dvalve", \ - "dual-port vent", \ - "passive vent", \ - "dtvalve", \ - "circ", \ - ) - icon_state = islist[pipe_type + 1] + name = "[get_pipe_name(pipe_type, PIPETYPE_ATMOS)] fitting" + icon_state = get_pipe_icon(pipe_type) var/obj/machinery/atmospherics/trinary/triP = make_from if(istype(triP) && triP.flipped) icon_state = "m_[icon_state]" @@ -650,6 +535,12 @@ to_chat(user, "You have fastened the meter to the pipe.") qdel(src) +/obj/item/pipe_meter/rpd_act(mob/user, obj/item/rpd/our_rpd) + if(our_rpd.mode == RPD_DELETE_MODE) + our_rpd.delete_single_pipe(user, src) + else + ..() + /obj/item/pipe_gsensor name = "gas sensor" desc = "A sensor that can be hooked to a computer" @@ -667,43 +558,8 @@ to_chat(user, "You have fastened the gas sensor.") qdel(src) -#undef PIPE_SIMPLE_STRAIGHT -#undef PIPE_SIMPLE_BENT -#undef PIPE_HE_STRAIGHT -#undef PIPE_HE_BENT -#undef PIPE_CONNECTOR -#undef PIPE_MANIFOLD -#undef PIPE_JUNCTION -#undef PIPE_UVENT -#undef PIPE_MVALVE -#undef PIPE_PUMP -#undef PIPE_SCRUBBER -#undef PIPE_INSULATED_STRAIGHT -#undef PIPE_INSULATED_BENT -#undef PIPE_GAS_FILTER -#undef PIPE_GAS_MIXER -#undef PIPE_PASSIVE_GATE -#undef PIPE_VOLUME_PUMP -#undef PIPE_HEAT_EXCHANGE -#undef PIPE_TVALVE -#undef PIPE_MANIFOLD4W -#undef PIPE_CAP -#undef PIPE_OMNI_MIXER -#undef PIPE_OMNI_FILTER -#undef PIPE_UNIVERSAL -#undef PIPE_SUPPLY_STRAIGHT -#undef PIPE_SUPPLY_BENT -#undef PIPE_SCRUBBERS_STRAIGHT -#undef PIPE_SCRUBBERS_BENT -#undef PIPE_SUPPLY_MANIFOLD -#undef PIPE_SCRUBBERS_MANIFOLD -#undef PIPE_SUPPLY_MANIFOLD4W -#undef PIPE_SCRUBBERS_MANIFOLD4W -#undef PIPE_SUPPLY_CAP -#undef PIPE_SCRUBBERS_CAP -#undef PIPE_INJECTOR -#undef PIPE_DVALVE -#undef PIPE_DP_VENT -#undef PIPE_PASV_VENT -#undef PIPE_DTVALVE -#undef PIPE_CIRCULATOR +/obj/item/pipe_gsensor/rpd_act(mob/user, obj/item/rpd/our_rpd) + if(our_rpd.mode == RPD_DELETE_MODE) + our_rpd.delete_single_pipe(user, src) + else + ..() diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index cb2892722aa..43613ef4990 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -10,12 +10,12 @@ /obj/machinery/pipedispenser/attack_hand(mob/user) if(..()) return 1 - + interact(user) - + /obj/machinery/pipedispenser/attack_ghost(mob/user) interact(user) - + /obj/machinery/pipedispenser/interact(mob/user) var/dat = {" Regular pipes:
@@ -163,22 +163,22 @@ /obj/machinery/pipedispenser/disposal/attack_hand(mob/user) if(..()) return - + interact(user) - + /obj/machinery/pipedispenser/disposal/attack_ghost(mob/user) interact(user) - + /obj/machinery/pipedispenser/disposal/interact(mob/user) var/dat = {"Disposal Pipes

-Pipe
-Bent Pipe
-Junction
-Y-Junction
-Trunk
-Bin
-Outlet
-Chute
+Pipe
+Bent Pipe
+Junction
+Y-Junction
+Trunk
+Bin
+Outlet
+Chute
"} var/datum/browser/popup = new(user, "pipedispenser", name, 400, 400) @@ -194,29 +194,10 @@ if(!wait) var/p_type = text2num(href_list["dmake"]) - var/obj/structure/disposalconstruct/C = new (loc) - switch(p_type) - if(0) - C.ptype = 0 - if(1) - C.ptype = 1 - if(2) - C.ptype = 2 - if(3) - C.ptype = 4 - if(4) - C.ptype = 5 - if(5) - C.ptype = 6 - C.density = 1 - if(6) - C.ptype = 7 - C.density = 1 - if(7) - C.ptype = 8 - C.density = 1 + var/obj/structure/disposalconstruct/C = new(loc, p_type) + if(p_type in list(PIPE_DISPOSALS_BIN, PIPE_DISPOSALS_OUTLET, PIPE_DISPOSALS_CHUTE)) + C.density = TRUE C.add_fingerprint(usr) - C.update() wait = 1 spawn(15) - wait = 0 \ No newline at end of file + wait = 0 diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index de5552e6a75..3d7f6a52e70 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -31,18 +31,18 @@ emagged = 1 //Set the emag var to true. -/obj/machinery/poolcontroller/attackby(obj/item/P as obj, mob/user as mob, params) //Proc is called when a user hits the pool controller with something. - if(istype(P,/obj/item/multitool)) //If the mob hits the pool controller with a multitool, reset the emagged status +/obj/machinery/poolcontroller/attackby(obj/item/I, mob/user, params) //Proc is called when a user hits the pool controller with something. + if(ismultitool(I)) //If the mob hits the pool controller with a multitool, reset the emagged status if(emagged) //Check the emag status - to_chat(user, "You re-enable \the [src]'s temperature safeguards.")//Inform the user that they have just fixed the safeguards. + to_chat(user, "You re-enable [src]'s temperature safeguards.")//Inform the user that they have just fixed the safeguards. - emagged = 0 //Set the emagged var to false. + emagged = FALSE //Set the emagged var to false. else to_chat(user, "Nothing happens.")//If not emagged, don't do anything, and don't tell the user that it can be emagged. else //If it's not a multitool, defer to /obj/machinery/attackby - ..() + return ..() /obj/machinery/poolcontroller/attack_hand(mob/user as mob) ui_interact(user) @@ -90,9 +90,9 @@ if(drownee && (drownee.lying || deep_water)) //Mob lying down or water is deep (determined by controller) if(drownee.internal) return //Has internals, no drowning - if((NO_BREATHE in drownee.species.species_traits) || (BREATHLESS in drownee.mutations)) + if((NO_BREATHE in drownee.dna.species.species_traits) || (BREATHLESS in drownee.mutations)) return //doesn't breathe, no drowning - if(drownee.get_species() == "Skrell" || drownee.get_species() == "Neara") + if(isskrell(drownee) || isneara(drownee)) return //fish things don't drown if(drownee.stat == DEAD) //Dead spacemen don't drown more diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 68e6eaf2ad2..abc8d137679 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -54,7 +54,7 @@ to_chat(user, "[src] isn't connected to anything!") return 1 else - ..() + return ..() /obj/machinery/recharger/attack_hand(mob/user) if(issilicon(user)) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index fd973290244..f987b698772 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -136,18 +136,21 @@ else icon_state = "borgcharger0" -/obj/machinery/recharge_station/attackby(obj/item/P as obj, mob/user as mob, params) - if(istype(P, /obj/item/screwdriver)) - if(src.occupant) +/obj/machinery/recharge_station/attackby(obj/item/I, mob/user, params) + if(isscrewdriver(I)) + if(occupant) to_chat(user, "The maintenance panel is locked.") return - default_deconstruction_screwdriver(user, "borgdecon2", "borgcharger0", P) + default_deconstruction_screwdriver(user, "borgdecon2", "borgcharger0", I) return - if(exchange_parts(user, P)) + if(exchange_parts(user, I)) return - default_deconstruction_crowbar(P) + if(default_deconstruction_crowbar(I)) + return + else + return ..() /obj/machinery/recharge_station/proc/process_occupant() if(src.occupant) diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index d80a628927b..72c0cd91002 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -51,6 +51,7 @@ var/const/SAFETY_COOLDOWN = 100 /obj/machinery/recycler/attackby(obj/item/I, mob/user, params) + add_fingerprint(user) if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I)) return @@ -60,9 +61,10 @@ var/const/SAFETY_COOLDOWN = 100 if(default_unfasten_wrench(user, I)) return - default_deconstruction_crowbar(I) - ..() - add_fingerprint(user) + if(default_deconstruction_crowbar(I)) + return + else + return ..() /obj/machinery/recycler/emag_act(mob/user) if(!emagged) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index e9c7c497d72..3aae4af4405 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -269,7 +269,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() return //err... hacking code, which has no reason for existing... but anyway... it was once supposed to unlock priority 3 messanging on that console (EXTREME priority...), but the code for that was removed. -/obj/machinery/requests_console/attackby(var/obj/item/O as obj, var/mob/user as mob) +/obj/machinery/requests_console/attackby(obj/item/I, mob/user) /* if(istype(O, /obj/item/crowbar)) if(open) @@ -292,14 +292,15 @@ var/list/obj/machinery/requests_console/allConsoles = list() else to_chat(user, "You can't do much with that.")*/ - if(istype(O, /obj/item/card/id)) - if(inoperable(MAINT)) return + if(istype(I, /obj/item/card/id)) + if(inoperable(MAINT)) + return if(screen == RCS_MESSAUTH) - var/obj/item/card/id/T = O + var/obj/item/card/id/T = I msgVerified = text("Verified by [T.registered_name] ([T.assignment])") updateUsrDialog() if(screen == RCS_ANNOUNCE) - var/obj/item/card/id/ID = O + var/obj/item/card/id/ID = I if(access_RC_announce in ID.GetAccess()) announceAuth = 1 announcement.announcer = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name @@ -308,16 +309,18 @@ var/list/obj/machinery/requests_console/allConsoles = list() to_chat(user, "You are not authorized to send announcements.") updateUsrDialog() if(screen == RCS_SHIPPING) - var/obj/item/card/id/T = O + var/obj/item/card/id/T = I msgVerified = text("Sender verified as [T.registered_name] ([T.assignment])") updateUsrDialog() - if(istype(O, /obj/item/stamp)) - if(inoperable(MAINT)) return + if(istype(I, /obj/item/stamp)) + if(inoperable(MAINT)) + return if(screen == RCS_MESSAUTH) - var/obj/item/stamp/T = O + var/obj/item/stamp/T = I msgStamped = text("Stamped with the [T.name]") updateUsrDialog() - return + else + return ..() /obj/machinery/requests_console/proc/reset_message(var/mainmenu = 0) message = "" diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 1962e3631fb..3777dfc866d 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -56,27 +56,26 @@ return else // insert cell - var/obj/item/stock_parts/cell/C = usr.get_active_hand() + var/obj/item/stock_parts/cell/C = user.get_active_hand() if(istype(C)) - user.drop_item() - cell = C - C.loc = src - C.add_fingerprint(usr) + if(user.drop_item()) + cell = C + C.forceMove(src) + C.add_fingerprint(user) - user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].") + user.visible_message("[user] inserts a power cell into [src].", "You insert the power cell into [src].") else to_chat(user, "The hatch must be open to insert a power cell.") return - else if(istype(I, /obj/item/screwdriver)) + else if(isscrewdriver(I)) open = !open - user.visible_message("[user] [open ? "opens" : "closes"] the hatch on the [src].", "You [open ? "open" : "close"] the hatch on the [src].") + user.visible_message("[user] [open ? "opens" : "closes"] the hatch on [src].", "You [open ? "open" : "close"] the hatch on [src].") update_icon() if(!open && user.machine == src) user << browse(null, "window=spaceheater") user.unset_machine() else - ..() - return + return ..() /obj/machinery/space_heater/attack_hand(mob/user as mob) src.add_fingerprint(user) @@ -106,7 +105,7 @@ else on = !on - user.visible_message("[user] switches [on ? "on" : "off"] the [src].","You switch [on ? "on" : "off"] the [src].") + user.visible_message("[user] switches [on ? "on" : "off"] [src].","You switch [on ? "on" : "off"] [src].") update_icon() return @@ -131,7 +130,7 @@ usr.put_in_hands(cell) cell.add_fingerprint(usr) cell = null - usr.visible_message("[usr] removes the power cell from \the [src].", "You remove the power cell from \the [src].") + usr.visible_message("[usr] removes the power cell from [src].", "You remove the power cell from [src].") if("cellinstall") @@ -143,7 +142,7 @@ C.loc = src C.add_fingerprint(usr) - usr.visible_message("[usr] inserts a power cell into \the [src].", "You insert the power cell into \the [src].") + usr.visible_message("[usr] inserts a power cell into [src].", "You insert the power cell into [src].") updateDialog() else diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 7ec64373373..37d1c3ae93c 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -158,14 +158,14 @@ return -/obj/machinery/power/singularity_beacon/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/screwdriver)) +/obj/machinery/power/singularity_beacon/attackby(obj/item/I, mob/user, params) + if(isscrewdriver(I)) if(active) to_chat(user, "You need to deactivate the beacon first!") return if(anchored) - anchored = 0 + anchored = FALSE to_chat(user, "You unscrew the beacon from the floor.") disconnect_from_network() return @@ -173,11 +173,10 @@ if(!connect_to_network()) to_chat(user, "This device must be placed over an exposed cable.") return - anchored = 1 + anchored = TRUE to_chat(user, "You screw the beacon to the floor and attach the cable.") - return - ..() - return + else + return ..() /obj/machinery/power/singularity_beacon/Destroy() diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 247a40a3425..b5806d1472e 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -487,7 +487,8 @@ else to_chat(user, "The [I] wont fit! The [src] can only hold up to [max_beakers] containers.") return - ..() + else + return ..() /obj/item/bombcore/chemical/CheckParts(list/parts_list) ..() diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index a1248fc0b6d..46671a9f4fa 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -38,21 +38,20 @@ break return power_station -/obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob, params) +/obj/machinery/computer/teleporter/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/gps)) var/obj/item/gps/L = I if(L.locked_location && !(stat & (NOPOWER|BROKEN))) if(!user.unEquip(L)) - to_chat(user, "\the [I] is stuck to your hand, you cannot put it in \the [src]") + to_chat(user, "[I] is stuck to your hand, you cannot put it in [src]") return - L.loc = src + L.forceMove(src) locked = L - to_chat(user, "You insert the GPS device into the [name]'s slot.") + to_chat(user, "You insert the GPS device into the [src]'s slot.") else - ..() - return + return ..() -/obj/machinery/computer/teleporter/emag_act(user as mob) +/obj/machinery/computer/teleporter/emag_act(mob/user) if(!emagged) emagged = 1 to_chat(user, "The teleporter can now lock on to Syndicate beacons!") @@ -341,14 +340,17 @@ //--FalseIncarnate return -/obj/machinery/teleport/hub/attackby(obj/item/W, mob/user, params) - if(default_deconstruction_screwdriver(user, "tele-o", "tele0", W)) +/obj/machinery/teleport/hub/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "tele-o", "tele0", I)) return - if(exchange_parts(user, W)) + if(exchange_parts(user, I)) return - default_deconstruction_crowbar(W) + if(default_deconstruction_crowbar(I)) + return + + return ..() /obj/machinery/teleport/hub/proc/teleport(atom/movable/M as mob|obj, turf/T) var/obj/machinery/computer/teleporter/com = power_station.teleporter_console @@ -438,14 +440,17 @@ else icon_state = "tele0" -/obj/machinery/teleport/perma/attackby(obj/item/W, mob/user, params) - if(default_deconstruction_screwdriver(user, "tele-o", "tele0", W)) +/obj/machinery/teleport/perma/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "tele-o", "tele0", I)) return - if(exchange_parts(user, W)) + if(exchange_parts(user, I)) return - default_deconstruction_crowbar(W) + if(default_deconstruction_crowbar(I)) + return + + return ..() /obj/machinery/teleport/station name = "station" @@ -506,41 +511,46 @@ teleporter_console = null return ..() -/obj/machinery/teleport/station/attackby(var/obj/item/W, mob/user, params) - if(istype(W, /obj/item/multitool) && !panel_open) - var/obj/item/multitool/M = W +/obj/machinery/teleport/station/attackby(obj/item/I, mob/user, params) + if(ismultitool(I) && !panel_open) + var/obj/item/multitool/M = I if(M.buffer && istype(M.buffer, /obj/machinery/teleport/station) && M.buffer != src) if(linked_stations.len < efficiency) linked_stations.Add(M.buffer) M.buffer = null - to_chat(user, "You upload the data from the [W.name]'s buffer.") + to_chat(user, "You upload the data from [M]'s buffer.") else to_chat(user, "This station can't hold more information, try to use better parts.") - if(default_deconstruction_screwdriver(user, "controller-o", "controller", W)) + return + + if(default_deconstruction_screwdriver(user, "controller-o", "controller", I)) update_icon() return - if(exchange_parts(user, W)) + if(exchange_parts(user, I)) return - default_deconstruction_crowbar(W) + if(default_deconstruction_crowbar(I)) + return if(panel_open) - if(istype(W, /obj/item/multitool)) - var/obj/item/multitool/M = W + if(ismultitool(I)) + var/obj/item/multitool/M = I M.buffer = src - to_chat(user, "You download the data to the [W.name]'s buffer.") + to_chat(user, "You download the data to the [M]'s buffer.") return - if(istype(W, /obj/item/wirecutters)) + if(iswirecutter(I)) link_console_and_hub() to_chat(user, "You reconnect the station to nearby machinery.") return - if(istype(W, /obj/item/circuitboard/teleporter_perma)) - var/obj/item/circuitboard/teleporter_perma/C = W + if(istype(I, /obj/item/circuitboard/teleporter_perma)) + var/obj/item/circuitboard/teleporter_perma/C = I C.target = teleporter_console.target - to_chat(user, "You copy the targeting information from \the [src] to \the [W]") + to_chat(user, "You copy the targeting information from [src] to [C]") return + return ..() + /obj/machinery/teleport/station/attack_ai() src.attack_hand() diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index 45294f01286..5e99a954650 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -289,18 +289,18 @@ qdel(I) H.equipOutfit(selected_outfit) - H.species.after_equip_job(null, H) + H.dna.species.after_equip_job(null, H) /obj/machinery/transformer/transmogrifier name = "species transmogrifier" desc = "As promoted in Calvin & Hobbes!" - var/target_species = "Human" + var/datum/species/target_species = /datum/species/human /obj/machinery/transformer/transmogrifier/do_transform(mob/living/carbon/human/H) if(!istype(H)) return - if(!(target_species in all_species)) + if(!ispath(target_species)) to_chat(H, "'[target_species]' is not a valid species!") return H.set_species(target_species) @@ -336,7 +336,7 @@ to_chat(H, "No genetic template configured!") return var/prev_ue = H.dna.unique_enzymes - H.set_species(template.species) + H.set_species(template.species.type) H.dna = template.Clone() H.real_name = template.real_name H.sync_organ_dna(assimilate = 0, old_ue = prev_ue) @@ -344,12 +344,12 @@ domutcheck(H, null, MUTCHK_FORCED) H.update_mutations() -/obj/machinery/transformer/gene_applier/attackby(obj/item/W, mob/living/user, params) - if(istype(W, /obj/item/disk/data)) +/obj/machinery/transformer/gene_applier/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/disk/data)) if(locked) to_chat(user, "Access Denied.") return FALSE - var/obj/item/disk/data/D = W + var/obj/item/disk/data/D = I if(!D.buf) to_chat(user, "Error: No data found.") return FALSE diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index f7b2e8bbd05..7fe19960100 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -288,7 +288,7 @@ insert_item(user, I) return else - ..() + return ..() //Override this proc to do per-machine checks on the inserted item, but remember to call the parent to handle these generic checks before your logic! /obj/machinery/vending/proc/item_slot_check(mob/user, obj/item/I) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 2ff4f478e2d..d0af747dc64 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -158,15 +158,16 @@ overlays -= "fab-active" desc = initial(desc) - var/obj/item/I = new D.build_path + var/obj/item/I = new D.build_path(loc) if(D.locked) - var/obj/item/storage/lockbox/large/L = new /obj/item/storage/lockbox/large(get_step(src,SOUTH)) //(Don't use capitals in paths, or single letters. - I.loc = L + var/obj/item/storage/lockbox/large/L = new /obj/item/storage/lockbox/large(get_step(src, SOUTH)) //(Don't use capitals in paths, or single letters. + I.forceMove(L) L.name += " [initial(I.name)]" L.origin_tech = I.origin_tech else - I.loc = get_step(src,SOUTH) - I.materials = res_coef + I.forceMove(get_step(src, SOUTH)) + if(istype(I)) + I.materials = res_coef atom_say("[I] is complete.") being_built = null diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index ca43f87ae46..a2fa4220c3c 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1206,6 +1206,10 @@ occupant = brainmob brainmob.forceMove(src) //should allow relaymove brainmob.canmove = 1 + if(istype(mmi_as_oc, /obj/item/mmi/robotic_brain)) + var/obj/item/mmi/robotic_brain/R = mmi_as_oc + if(R.imprinted_master) + to_chat(brainmob, "Your imprint to [R.imprinted_master] has been temporarily disabled. You should help the crew and not commit harm.") mmi_as_oc.loc = src mmi_as_oc.mecha = src verbs -= /obj/mecha/verb/eject @@ -1305,6 +1309,10 @@ mmi.mecha = null mmi.update_icon() L.canmove = 0 + if(istype(mmi, /obj/item/mmi/robotic_brain)) + var/obj/item/mmi/robotic_brain/R = mmi + if(R.imprinted_master) + to_chat(L, "Imprint re-enabled, you are once again bound to [R.imprinted_master]'s commands.") icon_state = initial(icon_state)+"-open" dir = dir_in diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 0e8bd6691f2..5836136401e 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -6,6 +6,7 @@ icon = 'icons/effects/effects.dmi' burn_state = LAVA_PROOF | FIRE_PROOF resistance_flags = INDESTRUCTIBLE + can_be_hit = FALSE /obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) return diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index a11236df0e5..18506a5c882 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -60,7 +60,7 @@ victim.apply_effect(radiation_amount, IRRADIATE, 0) if(ishuman(victim)) var/mob/living/carbon/human/V = victim - if(NO_DNA in V.species.species_traits) + if(NO_DNA in V.dna.species.species_traits) return randmutb(victim) domutcheck(victim ,null) diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index cf65c0b912f..9ffca668c28 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -130,7 +130,7 @@ ////////////////CONTRABAND STUFF////////////////// /obj/item/grenade/clown_grenade = 3, /obj/item/seeds/ambrosia/cruciatus = 3, - /obj/item/gun/projectile/automatic/pistol/empty = 1, + /obj/item/gun/projectile/automatic/pistol = 1, /obj/item/ammo_box/magazine/m10mm = 4, /obj/item/soap/syndie = 7, /obj/item/gun/syringe/syndicate = 2, diff --git a/code/game/objects/effects/spawners/random_barrier.dm b/code/game/objects/effects/spawners/random_barrier.dm index 3fd81bcf9b0..e337df8df27 100644 --- a/code/game/objects/effects/spawners/random_barrier.dm +++ b/code/game/objects/effects/spawners/random_barrier.dm @@ -11,7 +11,7 @@ // This needs to come before the initialization wave because // the thing it creates might need to be initialized too -/obj/effect/spawner/random_barrier/New() +/obj/effect/spawner/random_barrier/Initialize() . = ..() var/turf/T = get_turf(src) if(!T) diff --git a/code/game/objects/effects/spawners/random_spawners.dm b/code/game/objects/effects/spawners/random_spawners.dm index 621c8799cc2..4e381c96c3b 100644 --- a/code/game/objects/effects/spawners/random_spawners.dm +++ b/code/game/objects/effects/spawners/random_spawners.dm @@ -12,7 +12,7 @@ // This needs to come before the initialization wave because // the thing it creates might need to be initialized too -/obj/effect/spawner/random_spawners/New() +/obj/effect/spawner/random_spawners/Initialize() . = ..() var/turf/T = get_turf(src) if(!T) diff --git a/code/game/objects/effects/spawners/windowspawner.dm b/code/game/objects/effects/spawners/windowspawner.dm index 6d271039070..e6e2aaa1a21 100644 --- a/code/game/objects/effects/spawners/windowspawner.dm +++ b/code/game/objects/effects/spawners/windowspawner.dm @@ -8,33 +8,34 @@ anchored = 1 // No sliding out while you prime /obj/effect/spawner/window/Initialize() - ..() - spawn(0) - var/turf/T = get_turf(src) - for(var/obj/structure/grille/G in get_turf(src)) - // Complain noisily - log_runtime(EXCEPTION("Extra grille on turf: ([T.x],[T.y],[T.z])"), src) - qdel(G) //just in case mappers don't know what they are doing + . = ..() + var/turf/T = get_turf(src) + for(var/obj/structure/grille/G in get_turf(src)) + // Complain noisily + log_runtime(EXCEPTION("Extra grille on turf: ([T.x],[T.y],[T.z])"), src) + qdel(G) //just in case mappers don't know what they are doing - if(!useFull) - for(var/cdir in cardinal) - for(var/obj/effect/spawner/window/WS in get_step(src,cdir)) - cdir = null - break - if(!cdir) continue - var/obj/structure/window/WI = new windowtospawn(get_turf(src)) - WI.dir = cdir - else - var/obj/structure/window/W = new windowtospawn(get_turf(src)) - W.dir = SOUTHWEST + if(!useFull) + for(var/cdir in cardinal) + for(var/obj/effect/spawner/window/WS in get_step(src,cdir)) + cdir = null + break + if(!cdir) continue + var/obj/structure/window/WI = new windowtospawn(get_turf(src)) + WI.dir = cdir + else + var/obj/structure/window/W = new windowtospawn(get_turf(src)) + W.dir = SOUTHWEST - if(useGrille) - new /obj/structure/grille(get_turf(src)) + if(useGrille) + new /obj/structure/grille(get_turf(src)) - src.air_update_turf(1) //atmos can pass otherwise - - spawn(10) - qdel(src) + src.air_update_turf(1) //atmos can pass otherwise + // Give some time for nearby window spawners to initialize + spawn(10) + qdel(src) + // why is this line a no-op + // QDEL_IN(src, 10) /obj/effect/spawner/window/reinforced diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d83660e4de6..03b4f4adfaa 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -15,6 +15,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d var/inhand_x_dimension = 32 var/inhand_y_dimension = 32 + can_be_hit = FALSE + var/r_speed = 1.0 var/health = null var/hitsound = null @@ -277,25 +279,25 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d // Due to storage type consolidation this should get used more now. // I have cleaned it up a little, but it could probably use more. -Sayu -/obj/item/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/storage)) - var/obj/item/storage/S = W +/obj/item/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/storage)) + var/obj/item/storage/S = I if(S.use_to_pickup) if(S.collection_mode) //Mode is set to collect all items on a tile and we clicked on a valid one. - if(isturf(src.loc)) + if(isturf(loc)) var/list/rejections = list() var/success = 0 var/failure = 0 - for(var/obj/item/I in src.loc) - if(I.type in rejections) // To limit bag spamming: any given type only complains once + for(var/obj/item/IT in loc) + if(IT.type in rejections) // To limit bag spamming: any given type only complains once continue - if(!S.can_be_inserted(I)) // Note can_be_inserted still makes noise when the answer is no - rejections += I.type // therefore full bags are still a little spammy + if(!S.can_be_inserted(IT)) // Note can_be_inserted still makes noise when the answer is no + rejections += IT.type // therefore full bags are still a little spammy failure = 1 continue success = 1 - S.handle_item_insertion(I, 1) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed. + S.handle_item_insertion(IT, 1) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed. if(success && !failure) to_chat(user, "You put everything in [S].") else if(success) @@ -305,8 +307,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d else if(S.can_be_inserted(src)) S.handle_item_insertion(src) - - return + else + return ..() /obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) if(prob(final_block_chance)) @@ -465,7 +467,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d eyes.receive_damage(rand(3,4), 1) if(eyes.damage >= eyes.min_bruised_damage) if(M.stat != 2) - if(!(eyes.status & ORGAN_ROBOT) || !(eyes.status & ORGAN_ASSISTED)) //robot eyes bleeding might be a bit silly + if(!eyes.is_robotic()) //robot eyes bleeding might be a bit silly to_chat(M, "Your eyes start to bleed profusely!") if(prob(50)) if(M.stat != DEAD) diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index c8ab2e1fc4f..32b548c38aa 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -81,7 +81,7 @@ return if(ishuman(user)) var/mob/living/carbon/human/H = user - if((HULK in H.mutations) || (NOGUNS in H.species.species_traits)) + if((HULK in H.mutations) || (NOGUNS in H.dna.species.species_traits)) user << "Your fingers can't press the button!" return diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 4bbdaa2f723..4fea8e93a39 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -24,7 +24,7 @@ return if(ishuman(user)) var/mob/living/carbon/human/abductor/H = user - if(H && H.mind.abductor) + if(isabductor(H)) to_chat(user, "Megaphones can't project psionic communication!") return if(ishuman(user)) diff --git a/code/game/objects/items/devices/pizza_bomb.dm b/code/game/objects/items/devices/pizza_bomb.dm index 12ffe91cef5..b69c1114bd6 100644 --- a/code/game/objects/items/devices/pizza_bomb.dm +++ b/code/game/objects/items/devices/pizza_bomb.dm @@ -1,7 +1,7 @@ /obj/item/pizza_bomb name = "pizza box" desc = "A box suited for pizzas." - icon = 'icons/obj/food/food.dmi' + icon = 'icons/obj/food/pizza.dmi' icon_state = "pizzabox1" var/timer = 10 //Adjustable timer var/timer_set = 0 diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 9912957c2bb..62d8dc6c87d 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -245,7 +245,7 @@ REAGENT SCANNER user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.") var/implant_detect for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs) - if(CI.status == ORGAN_ROBOT) + if(CI.is_robotic()) implant_detect += "[H.name] is modified with a [CI.name].
" if(implant_detect) user.show_message("Detected cybernetic modifications:") diff --git a/code/game/objects/items/random_items.dm b/code/game/objects/items/random_items.dm index 2625d2b865a..ded05d6f795 100644 --- a/code/game/objects/items/random_items.dm +++ b/code/game/objects/items/random_items.dm @@ -130,8 +130,7 @@ /obj/item/storage/pill_bottle/random_meds/New() ..() - var/i = 1 - while(i < storage_slots) + for(var/i in 1 to storage_slots) var/list/possible_medicines = standard_medicines.Copy() if(prob(50)) possible_medicines += rare_medicines.Copy() @@ -144,7 +143,6 @@ P.reagents.add_reagent(R, rand(2, 5)*10) P.name = "Unlabelled Pill" P.desc = "Something about this pill entices you to try it, against your better judgement." - i++ pixel_x = rand(-10, 10) pixel_y = rand(-10, 10) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 2ae1a2d6e00..622b0b230c9 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -12,6 +12,7 @@ var/self_delay = 20 var/unique_handling = 0 //some things give a special prompt, do we want to bypass some checks in parent? var/stop_bleeding = 0 + var/healverb = "bandage" /obj/item/stack/medical/attack(mob/living/M, mob/user) if(!iscarbon(M) && !isanimal(M)) @@ -34,7 +35,7 @@ to_chat(user, "That limb is missing!") return 1 - if(affecting.status & ORGAN_ROBOT) + if(affecting.is_robotic()) to_chat(user, "This can't be used on a robotic limb.") return 1 @@ -77,6 +78,42 @@ "You apply [src] on [M].") use(1) +/obj/item/stack/medical/proc/heal(mob/living/M, mob/user) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting) + user.visible_message("[user] [healverb]s the wounds on [H]'s [affecting.name].", \ + "You [healverb] the wounds on [H]'s [affecting.name]." ) + + var/rembrute = max(0, heal_brute - affecting.brute_dam) // Maxed with 0 since heal_damage let you pass in a negative value + var/remburn = max(0, heal_burn - affecting.burn_dam) // And deduct it from their health (aka deal damage) + var/nrembrute = rembrute + var/nremburn = remburn + affecting.heal_damage(heal_brute, heal_burn) + var/list/achildlist + if(!isnull(affecting.children)) + achildlist = affecting.children.Copy() + var/parenthealed = FALSE + while(rembrute + remburn > 0) // Don't bother if there's not enough leftover heal + var/obj/item/organ/external/E + if(LAZYLEN(achildlist)) + E = pick_n_take(achildlist) // Pick a random children and then remove it from the list + else if(affecting.parent && !parenthealed) // If there's a parent and no healing attempt was made on it + E = affecting.parent + parenthealed = TRUE + else + break // If the organ have no child left and no parent / parent healed, break + if(E.status & ORGAN_ROBOT || E.open) // Ignore robotic or open limb + continue + else if(!E.brute_dam && !E.burn_dam) // Ignore undamaged limb + continue + nrembrute = max(0, rembrute - E.brute_dam) // Deduct the healed damage from the remain + nremburn = max(0, remburn - E.burn_dam) + E.heal_damage(rembrute, remburn) + rembrute = nrembrute + remburn = nremburn + user.visible_message("[user] [healverb]s the wounds on [H]'s [E.name] with the remaining medication.", \ + "You [healverb] the wounds on [H]'s [E.name] with the remaining medication." ) + //Bruise Packs// /obj/item/stack/medical/bruise_pack @@ -98,13 +135,12 @@ if(affecting.open == 0) affecting.germ_level = 0 - user.visible_message("[user] bandages the wounds on [H]'s [affecting.name].", \ - "You bandage the wounds on [H]'s [affecting.name]." ) - if(stop_bleeding) if(!H.bleedsuppress) //so you can't stack bleed suppression H.suppress_bloodloss(stop_bleeding) - affecting.heal_damage(heal_brute, heal_burn) + + heal(H, user) + H.UpdateDamageIcon() use(1) else @@ -131,6 +167,7 @@ singular_name = "ointment" icon_state = "ointment" origin_tech = "biotech=2" + healverb = "salve" /obj/item/stack/medical/ointment/attack(mob/living/M, mob/user) if(..()) @@ -143,9 +180,8 @@ if(affecting.open == 0) affecting.germ_level = 0 - user.visible_message("[user] salves the wounds on [H]'s [affecting.name].", \ - "You salve the wounds on [H]'s [affecting.name]." ) - affecting.heal_damage(heal_brute, heal_burn) + heal(H, user) + H.UpdateDamageIcon() use(1) else diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm index 593ef9a820f..ec5ba4ef684 100644 --- a/code/game/objects/items/stacks/nanopaste.dm +++ b/code/game/objects/items/stacks/nanopaste.dm @@ -28,7 +28,7 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting) - if(S && (S.status & ORGAN_ROBOT)) + if(S && S.is_robotic()) if(S.get_damage()) S.heal_damage(15, 15, robo_repair = 1) H.updatehealth() diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index 835de7617ee..62b203e43b1 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -57,16 +57,13 @@ RSF if(!proximity) return if(!(istype(A, /obj/structure/table) || istype(A, /turf/simulated/floor))) return - var spawn_location - if(istype(A, /obj/structure/table)) - spawn_location = A.loc - else if (istype(A, /obj/structure/table)) - spawn_location = A + var/turf/T = get_turf(A) + if(istype(T) && !T.density) + spawn_location = T else to_chat(user, "The RSF can only create service items on tables, or floors.") return - if(isrobot(user)) var/mob/living/silicon/robot/engy = user if(!engy.cell.use(configured_items[mode][2])) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 8566fac6a3c..daaa5c3e4c4 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -86,7 +86,7 @@ icon_state = "id" item_state = "card-id" var/mining_points = 0 //For redeeming at mining equipment lockers - var/access = list() + var/list/access = list() var/registered_name = "Unknown" // The name registered_name on the card slot_flags = SLOT_ID var/untrackable // Can not be tracked by AI's @@ -463,7 +463,7 @@ var/new_job = "Civilian" if(department == "Custom") - new_job = sanitize(stripped_input(user,"Choose a custom jon title:","Agent Card Occupation", "Civilian", MAX_MESSAGE_LEN)) + new_job = sanitize(stripped_input(user,"Choose a custom job title:","Agent Card Occupation", "Civilian", MAX_MESSAGE_LEN)) else if(department != "Civilian") switch(department) if("Engineering") diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index ec8a2a5e325..c28fd68fc62 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -99,7 +99,7 @@ if(!get_location_accessible(H, "mouth")) to_chat(user, "The mask is in the way.") return - if((C.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... + if((C.dna.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... to_chat(user, "You find yourself disappointed at the appalling lack of facial hair.") return if(C.f_style == "Shaved") @@ -130,13 +130,13 @@ if(!get_location_accessible(H, "head")) to_chat(user, "The headgear is in the way.") return - if((C.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... + if((C.dna.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... to_chat(user, "You find yourself disappointed at the appalling lack of hair.") return if(C.h_style == "Bald" || C.h_style == "Balding Hair" || C.h_style == "Skinhead") to_chat(user, "There is not enough hair left to shave...") return - if(M.get_species() == "Skrell") + if(isskrell(M)) to_chat(user, "Your razor isn't going to cut through tentacles.") return if(H == user) //shaving yourself diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 99a62b83131..b1fc3398af0 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -375,6 +375,13 @@ update_icon() return else + var/obj/item/organ/internal/heart/heart = H.get_int_organ(/obj/item/organ/internal/heart) + if(heart.status & ORGAN_DEAD) + user.visible_message("[defib] buzzes: Resuscitation failed - Heart necrosis detected.") + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + busy = 0 + update_icon() + return H.set_heartattack(FALSE) user.visible_message("[defib] pings: Cardiac arrhythmia corrected.") M.visible_message("[M]'s body convulses a bit.") diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 3a8bf12b143..3a7e203101d 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -74,7 +74,7 @@ H = M spawn(0) //Some mutations have sleeps in them, like monkey - if(!(NOCLONE in M.mutations) && !(H && (NO_DNA in H.species.species_traits))) // prevents drained people from having their DNA changed + if(!(NOCLONE in M.mutations) && !(H && (NO_DNA in H.dna.species.species_traits))) // prevents drained people from having their DNA changed var/prev_ue = M.dna.unique_enzymes var/mutflags = 0 // UI in syringe. @@ -113,7 +113,7 @@ if(ishuman(M)) // Would've done this via species instead of type, but the basic mob doesn't have a species, go figure. var/mob/living/carbon/human/H = M - if(NO_DNA in H.species.species_traits) + if(NO_DNA in H.dna.species.species_traits) return 0 if(!user.IsAdvancedToolUser()) diff --git a/code/game/objects/items/weapons/dnascrambler.dm b/code/game/objects/items/weapons/dnascrambler.dm index 2866e8d06ec..fc13fa69f79 100644 --- a/code/game/objects/items/weapons/dnascrambler.dm +++ b/code/game/objects/items/weapons/dnascrambler.dm @@ -24,7 +24,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - if(NO_DNA in H.species.species_traits) + if(NO_DNA in H.dna.species.species_traits) to_chat(user, "You failed to inject [M], as [M.p_they()] [M.p_have()] no DNA to scramble, nor flesh to inject.") return @@ -43,7 +43,7 @@ if(istype(target)) var/mob/living/carbon/human/H = target scramble(1, H, 100) - H.real_name = random_name(H.gender, H.species.name) //Give them a name that makes sense for their species. + H.real_name = random_name(H.gender, H.dna.species.name) //Give them a name that makes sense for their species. H.sync_organ_dna(assimilate = 1) H.update_body(0) H.reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover. diff --git a/code/game/objects/items/weapons/implants/implant_abductor.dm b/code/game/objects/items/weapons/implants/implant_abductor.dm index 0d5bc869e44..3ec571c94a6 100644 --- a/code/game/objects/items/weapons/implants/implant_abductor.dm +++ b/code/game/objects/items/weapons/implants/implant_abductor.dm @@ -28,8 +28,9 @@ var/obj/machinery/abductor/console/console if(ishuman(source)) var/mob/living/carbon/human/H = source - if(H.get_species() == "Abductor") - console = get_team_console(H.mind.abductor.team) + if(isabductor(H)) + var/datum/species/abductor/S = H.dna.species + console = get_team_console(S.team) home = console.pad if(!home) diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm index aaaf034b933..e130c3ed606 100644 --- a/code/game/objects/items/weapons/rpd.dm +++ b/code/game/objects/items/weapons/rpd.dm @@ -2,28 +2,8 @@ Rapid Pipe Dispenser */ -#define SIMPLE_CAP 20 -#define SUPPLY_CAP 32 -#define SCRUBBERS_CAP 33 -#define HE_EXCHANGER 17 -#define CONNECTOR 4 -#define UNARY_VENT 7 -#define PASSIVE_VENT 37 -#define GAS_SCRUBBER 10 -#define INJECTOR 34 -#define GAS_SENSOR 98 -#define METER 99 -#define DISPOSALS_JUNCTION 2 -#define ATMOS_MODE 1 -#define DISPOSALS_MODE 2 -#define ROTATION_MODE 3 -#define FLIP_MODE 4 -#define DELETE_MODE 5 -#define ATMOS_PIPING 1 -#define SUPPLY_PIPING 2 -#define SCRUBBERS_PIPING 3 -#define DEVICES 4 -#define HEAT_PIPING 5 +#define RPD_COOLDOWN_TIME 4 //How long should we have to wait between dispensing pipes? +#define RPD_WALLBUILD_TIME 40 //How long should drilling into a wall take? /obj/item/rpd name = "rapid pipe dispenser" @@ -43,13 +23,13 @@ origin_tech = "engineering=4;materials=2" var/datum/effect_system/spark_spread/spark_system var/lastused - var/iconrotation = 0 //used to orient icons and pipes - var/mode = 1 //Disposals, atmospherics, etc. - var/pipetype = 1//For nanoUI menus - var/whatpipe = 0 //What kind of pipe is it? See code/game/machinery/pipe/construction.dm for a list of defines - var/whatdpipe = 0 //What kind of disposals pipe is it? See code/game/machinery/pipe/dispenser.dm for a list of defines - var/spawndelay = 4 //How long should we have to wait between dispensing pipes? - var/walldelay = 40 //How long should drilling into a wall take? + var/iconrotation = 0 //Used to orient icons and pipes + var/mode = RPD_ATMOS_MODE //Disposals, atmospherics, etc. + var/pipe_category = RPD_ATMOS_PIPING//For nanoUI menus, this is a subtype of pipes e.g. scrubbers pipes, devices + var/whatpipe = PIPE_SIMPLE_STRAIGHT //What kind of atmos pipe is it? + var/whatdpipe = PIPE_DISPOSALS_STRAIGHT //What kind of disposals pipe is it? + var/spawndelay = RPD_COOLDOWN_TIME + var/walldelay = RPD_WALLBUILD_TIME /obj/item/rpd/New() ..() @@ -57,82 +37,112 @@ spark_system.set_up(1, 0, src) spark_system.attach(src) +/obj/item/rpd/Destroy() + QDEL_NULL(spark_system) + return ..() + //Procs -/obj/item/rpd/proc/Activaterpd(delay) +/obj/item/rpd/proc/activate_rpd(delay) //Maybe makes sparks and activates cooldown if there is a delay playsound(loc, "sound/machines/click.ogg", 50, 1) if(prob(15)) spark_system.start() if(delay) lastused = world.time -/obj/item/rpd/proc/Manipulatepipes(subject, atmosverb, disposalsverb) - if(istype(subject, /obj/item/pipe)) - call(subject, atmosverb)() - else if(istype(subject, /obj/structure/disposalconstruct/)) - call(subject, disposalsverb)() +/obj/item/rpd/proc/can_dispense_pipe(var/pipe_id, var/pipe_type) //Returns TRUE if this is a legit pipe we can dispense, otherwise returns FALSE + for(var/list/L in GLOB.rpd_pipe_list) + if(pipe_type != L["pipe_type"]) //Sometimes pipes in different categories have the same pipe_id, so we need to skip anything not in the category we want + continue + if(pipe_id == L["pipe_id"]) //Found the pipe, we can dispense it + return TRUE + +/obj/item/rpd/proc/create_atmos_pipe(mob/user, turf/T) //Make an atmos pipe, meter, or gas sensor + if(!can_dispense_pipe(whatpipe, RPD_ATMOS_MODE)) + log_runtime(EXCEPTION("Failed to spawn [get_pipe_name(whatpipe, PIPETYPE_ATMOS)] - possible tampering detected")) //Damn dirty apes -- I mean hackers + return + var/obj/item/pipe/P + if(whatpipe == PIPE_GAS_SENSOR) + P = new /obj/item/pipe_gsensor(T) + else if(whatpipe == PIPE_METER) + P = new /obj/item/pipe_meter(T) + else + P = new(T, whatpipe, iconrotation) //Make the pipe, BUT WAIT! There's more! + if(!iconrotation && P.is_bent_pipe()) //Automatically rotates dispensed pipes if the user selected auto-rotation + P.dir = turn(user.dir, 135) + else if(!iconrotation && P.pipe_type in list(PIPE_CONNECTOR, PIPE_UVENT, PIPE_SCRUBBER, PIPE_HEAT_EXCHANGE, PIPE_CAP, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP, PIPE_INJECTOR, PIPE_PASV_VENT)) //Some pipes dispense oppositely to what you'd expect, but we don't want to do anything if they selected a direction + P.flip() + else if(iconrotation && P.is_bent_pipe()) //If user selected a rotation and the pipe is bent + P.dir = turn(iconrotation, -45) + else if(!iconrotation) //If user selected a rotation + P.dir = user.dir + to_chat(user, "[src] rapidly dispenses [P]!") + activate_rpd(TRUE) + +/obj/item/rpd/proc/create_disposals_pipe(mob/user, turf/T) //Make a disposals pipe / construct + if(!can_dispense_pipe(whatdpipe, RPD_DISPOSALS_MODE)) + log_runtime(EXCEPTION("Failed to spawn [get_pipe_name(whatdpipe, PIPETYPE_DISPOSAL)] - possible tampering detected")) + return + var/obj/structure/disposalconstruct/P = new(T, whatdpipe, iconrotation) + if(!iconrotation) //Automatic rotation + P.dir = user.dir + if(!iconrotation && whatdpipe != PIPE_DISPOSALS_JUNCTION_RIGHT) //Disposals pipes are in the opposite direction to atmos pipes, so we need to flip them. Junctions don't have this quirk though + P.flip() + to_chat(user, "[src] rapidly dispenses [P]!") + activate_rpd(TRUE) + +/obj/item/rpd/proc/rotate_all_pipes(mob/user, turf/T) //Rotate all pipes on a turf + for(var/obj/item/pipe/P in T) + P.rotate() + for(var/obj/structure/disposalconstruct/D in T) + D.rotate() + +/obj/item/rpd/proc/flip_all_pipes(mob/user, turf/T) //Flip all pipes on a turf + for(var/obj/item/pipe/P in T) + P.flip() + for(var/obj/structure/disposalconstruct/D in T) + D.flip() + +/obj/item/rpd/proc/delete_all_pipes(mob/user, turf/T) //Delete all pipes on a turf + var/eaten + for(var/obj/item/pipe/P in T) + QDEL_NULL(P) + eaten = TRUE + for(var/obj/item/pipe_gsensor/G in T) + QDEL_NULL(G) + eaten = TRUE + for(var/obj/item/pipe_meter/M in T) + QDEL_NULL(M) + eaten = TRUE + for(var/obj/structure/disposalconstruct/D in T) + if(!D.anchored) + QDEL_NULL(D) + eaten = TRUE + if(eaten) + to_chat(user, "[src] sucks up the loose pipes on [T].") + activate_rpd() + else + to_chat(user, "There were no loose pipes on [T].") + +/obj/item/rpd/proc/delete_single_pipe(mob/user, obj/P) //Delete a single pipe + to_chat(user, "[src] sucks up [P].") + QDEL_NULL(P) + activate_rpd() //Lists of things -var/list/pipelist = list( //id refers to the pipe_type found in construction.dm, icon refers to the name of the icon state in icons/obj/pipe-item.dmi. Icons are made with the asset-cache - list("pipename" = "Straight pipe", "id" = 0, "category" = ATMOS_PIPING, "orientations" = 2, "icon" = "simple"), - list("pipename" = "Bent pipe", "id" = 1, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "simple", "bendy" = 1), - list("pipename" = "T-manifold", "id" = 5, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "manifold"), - list("pipename" = "4-way manifold", "id" = 19, "category" = ATMOS_PIPING, "orientations" = 1, "icon" = "manifold4w"), - list("pipename" = "Pipe cap", "id" = 20, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "cap"), - list("pipename" = "Manual valve", "id" = 8, "category" = ATMOS_PIPING, "orientations" = 2, "icon" = "mvalve"), - list("pipename" = "Digital valve", "id" = 35, "category" = ATMOS_PIPING, "orientations" = 2, "icon" = "dvalve"), - list("pipename" = "Manual T-valve", "id" = 18, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "tvalve"), - list("pipename" = "Digital T-valve", "id" = 38, "category" = ATMOS_PIPING, "orientations" = 4, "icon" = "dtvalve"), - list("pipename" = "Straight supply pipe", "id" = 24, "category" = SUPPLY_PIPING, "orientations" = 2, "icon" = "simple"), - list("pipename" = "Bent supply pipe", "id" = 25, "category" = SUPPLY_PIPING, "orientations" = 4, "icon" = "simple", "bendy" = 1), - list("pipename" = "Supply T-manifold", "id" = 28, "category" = SUPPLY_PIPING, "orientations" = 4, "icon" = "manifold"), - list("pipename" = "4-way supply manifold", "id" = 30, "category" = SUPPLY_PIPING, "orientations" = 1, "icon" = "manifold4w"), - list("pipename" = "Supply pipe cap", "id" = 32, "category" = SUPPLY_PIPING, "orientations" = 4, "icon" = "cap"), - list("pipename" = "Straight scrubbers pipe", "id" = 26, "category" = SCRUBBERS_PIPING, "orientations" = 2, "icon" = "simple"), - list("pipename" = "Bent scrubbers pipe", "id" = 27, "category" = SCRUBBERS_PIPING, "orientations" = 4, "icon" = "simple", "bendy" = 1), - list("pipename" = "Scrubbers T-manifold", "id" = 29, "category" = SCRUBBERS_PIPING, "orientations" = 4, "icon" = "manifold"), - list("pipename" = "4-way scrubbers manifold", "id" = 31, "category" = SCRUBBERS_PIPING, "orientations" = 1, "icon" = "manifold4w"), - list("pipename" = "Scrubbers pipe cap", "id" = 33, "category" = SCRUBBERS_PIPING, "orientations" = 4, "icon" = "cap"), - list("pipename" = "Universal pipe adapter", "id" = 23, "category" = DEVICES, "orientations" = 2, "icon" = "universal"), - list("pipename" = "Connector", "id" = 4, "category" = DEVICES, "orientations" = 4, "icon" = "connector"), - list("pipename" = "Unary vent", "id" = 7, "category" = DEVICES, "orientations" = 4, "icon" = "uvent"), - list("pipename" = "Scrubber", "id" = 10, "category" = DEVICES, "orientations" = 4, "icon" = "scrubber"), - list("pipename" = "Gas pump", "id" = 9, "category" = DEVICES, "orientations" = 4, "icon" = "pump"), - list("pipename" = "Volume pump", "id" = 16, "category" = DEVICES, "orientations" = 4, "icon" = "volumepump"), - list("pipename" = "Passive gate", "id" = 15, "category" = DEVICES, "orientations" = 4, "icon" = "passivegate"), - list("pipename" = "Gas filter", "id" = 13, "category" = DEVICES, "orientations" = 4, "icon" = "filter"), - list("pipename" = "Gas mixer", "id" = 14, "category" = DEVICES, "orientations" = 4, "icon" = "mixer"), - list("pipename" = "Gas sensor", "id" = 98, "category" = DEVICES, "orientations" = 1, "icon" = "sensor"), - list("pipename" = "Meter", "id" = 99, "category" = DEVICES, "orientations" = 1, "icon" = "meter"), - list("pipename" = "Passive vent", "id" = 37, "category" = DEVICES, "orientations" = 4, "icon" = "passive vent"), - list("pipename" = "Dual-port vent pump", "id" = 36, "category" = DEVICES, "orientations" = 2, "icon" = "dual-port vent"), - list("pipename" = "Air injector", "id" = 34, "category" = DEVICES, "orientations" = 4, "icon" = "injector"), - list("pipename" = "Straight HE pipe", "id" = 2, "category" = HEAT_PIPING, "orientations" = 2, "icon" = "he"), - list("pipename" = "Bent HE pipe", "id" = 3, "category" = HEAT_PIPING, "orientations" = 4, "icon" = "he", "bendy" = 1), - list("pipename" = "Junction", "id" = 6, "category" = HEAT_PIPING, "orientations" = 4, "icon" = "junction"), - list("pipename" = "Heat exchanger", "id" = 17, "category" = HEAT_PIPING, "orientations" = 4, "icon" = "heunary")) -var/list/dpipelist = list( - list("pipename" = "Straight pipe", "id" = 0, "orientations" = 2, "icon" = "conpipe-s"), - list("pipename" = "Bent pipe", "id" = 1, "orientations" = 4, "icon" = "conpipe-c"), - list("pipename" = "Junction", "id" = 2, "orientations" = 4, "icon" = "conpipe-j1"), - list("pipename" = "Y-junction", "id" = 4, "orientations" = 4, "icon" = "conpipe-y"), - list("pipename" = "Trunk", "id" = 5, "orientations" = 4, "icon" = "conpipe-t"), - list("pipename" = "Bin", "id" = 6, "orientations" = 1, "icon" = "condisposal"), - list("pipename" = "Outlet", "id" = 7, "orientations" = 4, "icon" = "outlet"), - list("pipename" = "Chute", "id" = 8, "orientations" = 4, "icon" = "intake")) var/list/mainmenu = list( - list("category" = "Atmospherics", "mode" = 1, "icon" = "wrench"), - list("category" = "Disposals", "mode" = 2, "icon" = "recycle"), - list("category" = "Rotate", "mode" = 3, "icon" = "rotate-right"), - list("category" = "Flip", "mode" = 4, "icon" = "exchange"), - list("category" = "Recycle", "mode" = 5, "icon" = "trash")) + list("category" = "Atmospherics", "mode" = RPD_ATMOS_MODE, "icon" = "wrench"), + list("category" = "Disposals", "mode" = RPD_DISPOSALS_MODE, "icon" = "recycle"), + list("category" = "Rotate", "mode" = RPD_ROTATE_MODE, "icon" = "rotate-right"), + list("category" = "Flip", "mode" = RPD_FLIP_MODE, "icon" = "exchange"), + list("category" = "Recycle", "mode" = RPD_DELETE_MODE, "icon" = "trash")) var/list/pipemenu = list( - list("pipecategory" = "Normal", "pipemode" = 1), - list("pipecategory" = "Supply", "pipemode" = 2), - list("pipecategory" = "Scrubber", "pipemode" = 3), - list("pipecategory" = "Devices", "pipemode" = 4), - list("pipecategory" = "Heat exchange", "pipemode" = 5)) + list("category" = "Normal", "pipemode" = RPD_ATMOS_PIPING), + list("category" = "Supply", "pipemode" = RPD_SUPPLY_PIPING), + list("category" = "Scrubber", "pipemode" = RPD_SCRUBBERS_PIPING), + list("category" = "Devices", "pipemode" = RPD_DEVICES), + list("category" = "Heat exchange", "pipemode" = RPD_HEAT_PIPING)) //NanoUI stuff @@ -148,13 +158,12 @@ var/list/pipemenu = list( /obj/item/rpd/ui_data(mob/user, ui_key = "main", datum/topic_state/state = inventory_state) var/data[0] - data["dpipelist"] = dpipelist data["iconrotation"] = iconrotation data["mainmenu"] = mainmenu data["mode"] = mode - data["pipelist"] = pipelist + data["pipelist"] = GLOB.rpd_pipe_list data["pipemenu"] = pipemenu - data["pipetype"] = pipetype + data["pipe_category"] = pipe_category data["whatdpipe"] = whatdpipe data["whatpipe"] = whatpipe return data @@ -167,99 +176,23 @@ var/list/pipemenu = list( whatpipe = text2num(sanitize(href_list["whatpipe"])) else if(href_list["whatdpipe"]) whatdpipe = text2num(sanitize(href_list["whatdpipe"])) - else if(href_list["pipetype"]) - pipetype = text2num(sanitize(href_list["pipetype"])) + else if(href_list["pipe_category"]) + pipe_category = text2num(sanitize(href_list["pipe_category"])) else if(href_list["mode"]) mode = text2num(sanitize(href_list["mode"])) else return SSnanoui.update_uis(src) -//What the RPD actually does - /obj/item/rpd/afterattack(atom/target, mob/user, proximity) ..() - var/turf/T = get_turf(target) - if(loc != user || ismob(target) || istype(target, /obj/structure/window) || !proximity || world.time < lastused + spawndelay) + if(loc != user) return - if(!(T.flags & RPD_ALLOWED_HERE)) - to_chat(user, "[src] beeps, \"Unable to interface with [T]. Please try again later.\"") + if(!proximity) return - if(mode == ATMOS_MODE) - if(istype(T, /turf/simulated/wall)) //Drilling into walls takes time - playsound(loc, "sound/weapons/circsawhit.ogg", 50, 1) - user.visible_message("[user] starts drilling a hole in [T]...", "You start drilling a hole in [T]...", "You hear a drill.") - if(!do_after(user, walldelay, target = T)) - return - user.visible_message("[user] finishes drilling a hole in [T]!", "You finish drilling a hole in [T]!", "You hear clanking.") - var/obj/item/pipe/P - if(whatpipe == GAS_SENSOR) - P = new /obj/item/pipe_gsensor(T) - else if(whatpipe == METER) - P = new /obj/item/pipe_meter(T) - else - P = new(T, pipe_type = whatpipe, dir = user.dir) - if(iconrotation == 0 && P.is_bent_pipe()) //Automatic rotation of dispensed pipes - P.dir = turn(user.dir, 135) - else if(iconrotation == 0 && P.pipe_type in list(CONNECTOR, UNARY_VENT, GAS_SCRUBBER, HE_EXCHANGER, SIMPLE_CAP, SUPPLY_CAP, SCRUBBERS_CAP, INJECTOR, PASSIVE_VENT)) //Some pipes dispense oppositely to what you'd expect, but we don't want to do anything if they selected a direction - P.flip() - else if(iconrotation != 0 && P.is_bent_pipe()) //If they selected a rotation and the pipe is bent - P.dir = turn(iconrotation, -45) - else if(iconrotation != 0) - P.dir = iconrotation - to_chat(user, "[src] rapidly dispenses [P]!") - Activaterpd(1) - else if(mode == DISPOSALS_MODE && !istype(T, /turf/simulated/shuttle)) - if(istype(T, /turf/simulated/wall)) //No disposals pipes on walls - to_chat(user, "That type of pipe won't fit on [T]!") - return - var/obj/structure/disposalconstruct/P = new(T) //Now we make the pipe - P.dir = iconrotation - P.ptype = whatdpipe - if(iconrotation == 0) //Automatic rotation - P.dir = user.dir - if(iconrotation == 0 && whatdpipe != DISPOSALS_JUNCTION) //Disposals pipes are in the opposite direction to atmos pipes, so we need to flip them. Junctions don't have this quirk though - P.flip() - P.update() - to_chat(user, "[src] rapidly dispenses [P]!") - Activaterpd(1) - else if(mode == ROTATION_MODE) - for(var/obj/W in T) - Manipulatepipes(W, /obj/item/pipe/verb/rotate, /obj/structure/disposalconstruct/verb/rotate) - else if(mode == FLIP_MODE) - for(var/obj/W in T) - Manipulatepipes(W, /obj/item/pipe/verb/flip, /obj/structure/disposalconstruct/verb/flip) - else if(mode == DELETE_MODE) - var/eaten - for(var/obj/W in T) - if(istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter) || istype(W, /obj/item/pipe_gsensor) || istype(W, /obj/structure/disposalconstruct) && !W.anchored) - QDEL_NULL(W) - eaten = TRUE - if(eaten) - to_chat(user, "[src] sucks up the loose pipes on [T].") - Activaterpd() - else - to_chat(user, "There were no loose pipes on [T].") + if(world.time < lastused + spawndelay) + return + target.rpd_act(user, src) //Handle RPD effects in separate procs -#undef SIMPLE_CAP -#undef SUPPLY_CAP -#undef SCRUBBERS_CAP -#undef HE_EXCHANGER -#undef CONNECTOR -#undef UNARY_VENT -#undef PASSIVE_VENT -#undef GAS_SCRUBBER -#undef INJECTOR -#undef GAS_SENSOR -#undef METER -#undef DISPOSALS_JUNCTION -#undef ATMOS_MODE -#undef DISPOSALS_MODE -#undef ROTATION_MODE -#undef FLIP_MODE -#undef DELETE_MODE -#undef ATMOS_PIPING -#undef SUPPLY_PIPING -#undef SCRUBBERS_PIPING -#undef DEVICES -#undef HEAT_PIPING +#undef RPD_COOLDOWN_TIME +#undef RPD_WALLBUILD_TIME diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm index 6ff1fbe95b0..2f53a1200a9 100644 --- a/code/game/objects/items/weapons/scissors.dm +++ b/code/game/objects/items/weapons/scissors.dm @@ -33,19 +33,19 @@ var/list/species_facial_hair = list() var/obj/item/organ/external/head/C = H.get_organ("head") var/datum/robolimb/robohead = all_robolimbs[C.model] - if(H.gender == MALE || H.get_species() == "Vulpkanin") - if(C.species) + if(H.gender == MALE || isvulpkanin(H)) + if(C.dna.species) for(var/i in facial_hair_styles_list) var/datum/sprite_accessory/facial_hair/tmp_facial = facial_hair_styles_list[i] - if(C.species.name in tmp_facial.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human hair styles. - if(C.species.bodyflags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. + if(C.dna.species.name in tmp_facial.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human hair styles. + if(C.dna.species.bodyflags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. if(robohead.is_monitor) to_chat(user, "You are unable to find anything on [H]'s face worth cutting. How disappointing.") return continue //If the head DOES support human hair wigs, make sure they don't get monitor-oriented styles. species_facial_hair += i else - if(C.species.bodyflags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. + if(C.dna.species.bodyflags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. if(!robohead.is_monitor) if("Human" in tmp_facial.species_allowed) species_facial_hair += i @@ -57,18 +57,18 @@ var/f_new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in species_facial_hair //handle normal hair var/list/species_hair = list() - if(C.species) + if(C.dna.species) for(var/i in hair_styles_public_list) var/datum/sprite_accessory/hair/tmp_hair = hair_styles_public_list[i] - if(C.species.name in tmp_hair.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human facial hair styles. - if(C.species.bodyflags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. + if(C.dna.species.name in tmp_hair.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human facial hair styles. + if(C.dna.species.bodyflags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. if(robohead.is_monitor) to_chat(user, "You are unable to find anything on [H]'s head worth cutting. How disappointing.") return continue //If the head DOES support human hair wigs, make sure they don't get monitor-oriented styles. species_hair += i else - if(C.species.bodyflags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. + if(C.dna.species.bodyflags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. if(!robohead.is_monitor) if("Human" in tmp_hair.species_allowed) species_hair += i diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm index b0d7477bbbb..0f771fee03d 100644 --- a/code/game/objects/items/weapons/shards.dm +++ b/code/game/objects/items/weapons/shards.dm @@ -45,7 +45,7 @@ var/mob/living/carbon/human/H = user if(!H.gloves) var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_hand") - if(affecting.status & ORGAN_ROBOT) + if(affecting.is_robotic()) return to_chat(H, "[src] cuts into your hand!") if(affecting.receive_damage(force*0.5)) @@ -82,7 +82,7 @@ var/obj/item/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot")) if(!affecting) return - if(affecting.status & ORGAN_ROBOT) + if(affecting.is_robotic()) return H.Weaken(3) if(affecting.receive_damage(5, 0)) diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm index a6046b575f7..742f5b3d0c0 100644 --- a/code/game/objects/items/weapons/soap.dm +++ b/code/game/objects/items/weapons/soap.dm @@ -26,7 +26,7 @@ to_chat(user, "You need to take that [target.name] off before cleaning it.") else if(target == user && user.a_intent == INTENT_GRAB && ishuman(target)) var/mob/living/carbon/human/muncher = user - if(muncher && muncher.get_species() == "Drask") + if(muncher && isdrask(muncher)) to_chat(user, "You take a bite of the [name]. Delicious!") playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0) user.nutrition += 2 diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 26793a8165b..3e7f2f6f8c9 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -371,7 +371,7 @@ */ /obj/item/storage/bag/tray name = "tray" - icon = 'icons/obj/food/food.dmi' + icon = 'icons/obj/food/containers.dmi' icon_state = "tray" desc = "A metal tray to lay food on." force = 5 diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index e0e43bfbda6..a78bc40dd3a 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -26,6 +26,7 @@ item_state = "syringe_kit" burn_state = FLAMMABLE var/foldable = /obj/item/stack/sheet/cardboard + var/amt = 1 /obj/item/storage/box/attack_self(mob/user) ..() @@ -49,7 +50,7 @@ return to_chat(user, "You fold [src] flat.") - var/obj/item/I = new foldable(get_turf(src)) + var/obj/item/stack/I = new foldable(get_turf(src), amt) user.put_in_hands(I) qdel(src) @@ -59,6 +60,7 @@ icon_state = "largebox" w_class = 42 // Big, bulky. foldable = /obj/item/stack/sheet/cardboard + amt = 4 storage_slots = 21 max_combined_w_class = 42 // 21*2 diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 4896f2cfb60..03b5ac86870 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -14,7 +14,7 @@ */ /obj/item/storage/fancy/ - icon = 'icons/obj/food/food.dmi' + icon = 'icons/obj/food/containers.dmi' icon_state = "donutbox6" name = "donut box" burn_state = FLAMMABLE @@ -43,7 +43,6 @@ */ /obj/item/storage/fancy/donut_box - icon = 'icons/obj/food/food.dmi' icon_state = "donutbox6" icon_type = "donut" name = "donut box" @@ -61,7 +60,6 @@ */ /obj/item/storage/fancy/egg_box - icon = 'icons/obj/food/food.dmi' icon_state = "eggbox" icon_type = "egg" name = "egg box" diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 93f230a07e8..66316b6f7ef 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -357,19 +357,22 @@ remove_from_storage(Item, loc, burn) //This proc is called when you want to place an item into the storage item. -/obj/item/storage/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/storage/attackby(obj/item/I, mob/user, params) ..() - + if(istype(I, /obj/item/hand_labeler)) + var/obj/item/hand_labeler/labeler = I + if(labeler.mode) + return FALSE + . = 1 //no afterattack if(isrobot(user)) - to_chat(user, "You're a robot. No.") - return 1//Robots can't interact with storage items. + return //Robots can't interact with storage items. - if(!can_be_inserted(W)) - return 0 - - handle_item_insertion(W) - return 1 + if(!can_be_inserted(I)) + if(contents.len >= storage_slots) //don't use items on the backpack if they don't fit + return TRUE + return FALSE + handle_item_insertion(I) /obj/item/storage/attack_hand(mob/user as mob) playsound(src.loc, "rustle", 50, 1, -5) diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 867cc473932..43904d27359 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -400,7 +400,7 @@ if(!S) return - if(!(S.status & ORGAN_ROBOT) || user.a_intent != INTENT_HELP || S.open == 2) + if(!S.is_robotic() || user.a_intent != INTENT_HELP || S.open == 2) return ..() if(!isOn()) //why wasn't this being checked already? diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 8de83f6344a..3e7f3eaffe3 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -58,7 +58,7 @@ return if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.species.is_small) + if(H.dna.species.is_small) to_chat(user, "It's too heavy for you to wield fully.") return if(user.get_inactive_hand()) @@ -313,7 +313,6 @@ sharp = TRUE no_spin_thrown = TRUE var/obj/item/grenade/explosive = null - var/war_cry = "AAAAARGH!!!" /obj/item/twohanded/spear/update_icon() if(explosive) @@ -327,7 +326,6 @@ if(isturf(AM)) //So you can actually melee with it return if(explosive && wielded) - user.say("[war_cry]") explosive.forceMove(AM) explosive.prime() qdel(src) @@ -338,30 +336,6 @@ explosive.prime() qdel(src) -/obj/item/twohanded/spear/AltClick(mob/user) - ..() - if(!explosive) - return - if(ishuman(loc)) - var/mob/living/carbon/human/M = loc - var/input = stripped_input(M, "What do you want your war cry to be? You will shout it when you hit someone in melee.", ,"", 50) - if(input) - war_cry = input - -/obj/item/twohanded/spear/CheckParts(list/parts_list) - ..() - if(explosive) - explosive.forceMove(get_turf(loc)) - explosive = null - update_icon() - var/obj/item/grenade/G = locate() in contents - if(G) - explosive = G - name = "explosive lance" - embed_chance = 0 - desc = "A makeshift spear with [G] attached to it. Alt+click on the spear to set your war cry!" - update_icon() - //GREY TIDE /obj/item/twohanded/spear/grey_tide icon_state = "spearglass0" diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 856a77395d9..1a5fe872251 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -179,7 +179,7 @@ obj/item/wirerod/attackby(obj/item/I, mob/user, params) return to_chat(user, "You begin gathering strength...") playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1) - if(do_after(user, 90, target = src)) + if(do_after(user, 90, target = user)) to_chat(user, "You gather power! Time for a home run!") homerun_ready = 1 ..() diff --git a/code/game/objects/items/weapons/whetstone.dm b/code/game/objects/items/weapons/whetstone.dm index 6cbc2e0e972..fcb2fab2d4e 100644 --- a/code/game/objects/items/weapons/whetstone.dm +++ b/code/game/objects/items/weapons/whetstone.dm @@ -10,6 +10,7 @@ var/max = 30 var/prefix = "sharpened" var/requires_sharpness = 1 + var/claw_damage_increase = 1 /obj/item/whetstone/attackby(obj/item/I, mob/user, params) @@ -46,16 +47,24 @@ playsound(get_turf(src), usesound, 50, 1) name = "worn out [name]" desc = "[desc] At least, it used to." - used = 1 + used = TRUE update_icon() -/obj/item/whetstone/attack_self(mob/user as mob) //This is just fluff for now. Species datums are global and not newly created instances, so we can't adjust unarmed damage on a per mob basis. +/obj/item/whetstone/attack_self(mob/user) + if(used) + to_chat(user, "The whetstone is too worn to use again!") + return if(ishuman(user)) var/mob/living/carbon/human/H = user - var/datum/unarmed_attack/attack = H.species.unarmed + var/datum/unarmed_attack/attack = H.dna.species.unarmed if(istype(attack, /datum/unarmed_attack/claws)) - H.visible_message("[H] sharpens [H.p_their()] claws on the [src]!", "You sharpen your claws on the [src].") + attack.damage += claw_damage_increase + H.visible_message("[H] sharpens [H.p_their()] claws on [src]!", "You sharpen your claws on [src].") playsound(get_turf(H), usesound, 50, 1) + name = "worn out [name]" + desc = "[desc] At least, it used to." + used = TRUE + update_icon() /obj/item/whetstone/super name = "super whetstone block" @@ -64,3 +73,4 @@ max = 200 prefix = "super-sharpened" requires_sharpness = 0 + claw_damage_increase = 200 diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 49e043b4159..3fddd8cc838 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -17,6 +17,7 @@ var/integrity_failure = 0 //0 if we have no special broken behavior var/resistance_flags = NONE // INDESTRUCTIBLE + var/can_be_hit = TRUE //can this be bludgeoned by items? var/Mtoollink = 0 // variable to decide if an object should show the multitool menu linking menu, not all objects use it @@ -24,6 +25,7 @@ var/burntime = 10 //How long it takes to burn to ashes, in seconds var/burn_world_time //What world time the object will burn up completely var/being_shocked = 0 + var/speed_process = FALSE var/on_blueprints = FALSE //Are we visible on the station blueprints at roundstart? var/force_blueprints = FALSE //forces the obj to be on the blueprints, regardless of when it was created. @@ -65,9 +67,14 @@ /obj/Destroy() machines -= src processing_objects -= src + fast_processing -= src SSnanoui.close_uis(src) return ..() +/obj/rpd_act(mob/user, obj/item/rpd/our_rpd) + var/turf/T = get_turf(src) //This preserves RPD behaviour on specific turfs + T.rpd_act(user, our_rpd) + /obj/proc/process() set waitfor = 0 processing_objects.Remove(src) @@ -279,9 +286,27 @@ a { /obj/proc/on_mob_move(dir, mob/user) return +/obj/proc/makeSpeedProcess() + if(speed_process) + return + speed_process = TRUE + processing_objects.Remove(src) + fast_processing.Add(src) + +/obj/proc/makeNormalProcess() + if(!speed_process) + return + speed_process = FALSE + processing_objects.Add(src) + fast_processing.Remove(src) + /obj/vv_get_dropdown() . = ..() .["Delete all of type"] = "?_src_=vars;delall=[UID()]" + if(!speed_process) + .["Make speed process"] = "?_src_=vars;makespeedy=[UID()]" + else + .["Make normal process"] = "?_src_=vars;makenormalspeed=[UID()]" /obj/proc/check_uplink_validity() return 1 diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index 37ab3977755..19e08c15bde 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -10,6 +10,7 @@ burntime = 20 sound = 'sound/effects/rustle2.ogg' material_drop = /obj/item/stack/sheet/cardboard + var/amt = 4 cutting_sound = 'sound/items/poster_ripped.ogg' var/move_delay = 0 var/egged = 0 @@ -60,7 +61,7 @@ return if(istype(W, /obj/item/wirecutters)) var/obj/item/wirecutters/WC = W - new /obj/item/stack/sheet/cardboard(src.loc) + new /obj/item/stack/sheet/cardboard(src.loc, amt) for(var/mob/M in viewers(src)) M.show_message("\The [src] has been cut apart by [user] with \the [WC].", 3, "You hear cutting.", 2) qdel(src) diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 348c92a5335..a7233bf6a82 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -23,7 +23,7 @@ var/list/valid_underwear = list() for(var/underwear in underwear_list) var/datum/sprite_accessory/S = underwear_list[underwear] - if(!(H.species.name in S.species_allowed)) + if(!(H.dna.species.name in S.species_allowed)) continue valid_underwear[underwear] = underwear_list[underwear] var/new_underwear = input(user, "Choose your underwear:", "Changing") as null|anything in valid_underwear @@ -34,7 +34,7 @@ var/list/valid_undershirts = list() for(var/undershirt in undershirt_list) var/datum/sprite_accessory/S = undershirt_list[undershirt] - if(!(H.species.name in S.species_allowed)) + if(!(H.dna.species.name in S.species_allowed)) continue valid_undershirts[undershirt] = undershirt_list[undershirt] var/new_undershirt = input(user, "Choose your undershirt:", "Changing") as null|anything in valid_undershirts @@ -45,7 +45,7 @@ var/list/valid_sockstyles = list() for(var/sockstyle in socks_list) var/datum/sprite_accessory/S = socks_list[sockstyle] - if(!(H.species.name in S.species_allowed)) + if(!(H.dna.species.name in S.species_allowed)) continue valid_sockstyles[sockstyle] = socks_list[sockstyle] var/new_socks = input(user, "Choose your socks:", "Changing") as null|anything in valid_sockstyles diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 8d22732e5dd..3911d366ad6 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -86,7 +86,7 @@ return ..() if(istype(A, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - if(H.species.is_small) + if(H.dna.species.is_small) return ..() return 0 diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 199691aa4db..6168d637c56 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -48,7 +48,10 @@ /obj/item/sign/attackby(obj/item/tool as obj, mob/user as mob) //construction if(istype(tool, /obj/item/screwdriver) && isturf(user.loc)) var/direction = input("In which direction?", "Select direction.") in list("North", "East", "South", "West", "Cancel") - if(direction == "Cancel") return + if(direction == "Cancel") + return + if(QDELETED(src)) + return var/obj/structure/sign/S = new(user.loc) switch(direction) if("North") @@ -59,7 +62,8 @@ S.pixel_y = -32 if("West") S.pixel_x = -32 - else return + else + return S.name = name S.desc = desc S.icon_state = sign_state diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 32ceefbd834..4a1ecdb08d7 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -186,7 +186,7 @@ buildstackamount = 1 /obj/structure/stool/bed/chair/sofa - name = "old ratty sofa" + name = "sofa" icon_state = "sofamiddle" anchored = 1 buildstackamount = 1 diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 8a30f18f7bd..25c78f6e972 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -123,6 +123,9 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f new/obj/structure/window/reinforced/clockwork/fulltile(get_turf(src)) qdel(src) +/obj/structure/window/rpd_act() + return + /obj/structure/window/singularity_pull(S, current_size) if(current_size >= STAGE_FIVE) deconstruct(FALSE) diff --git a/code/game/response_team.dm b/code/game/response_team.dm index c59dd7bd78f..646adfa2038 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -143,7 +143,7 @@ var/ert_request_answered = 0 else M.change_gender(FEMALE) - M.set_species("Human",1) + M.set_species(/datum/species/human, TRUE) M.dna.ready_dna(M) M.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ERT. M.overeatduration = 0 @@ -158,8 +158,8 @@ var/ert_request_answered = 0 head_organ.sec_hair_colour = hair_c M.change_eye_color(eye_c) M.s_tone = skin_tone - head_organ.h_style = random_hair_style(M.gender, head_organ.species.name) - head_organ.f_style = random_facial_hair_style(M.gender, head_organ.species.name) + head_organ.h_style = random_hair_style(M.gender, head_organ.dna.species.name) + head_organ.f_style = random_facial_hair_style(M.gender, head_organ.dna.species.name) M.rename_character(null, "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(last_names)]") M.age = rand(23,35) diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 89c40be8641..61f622c071f 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -4,7 +4,6 @@ var/image/wet_overlay = null var/thermite = 0 - flags = RPD_ALLOWED_HERE oxygen = MOLES_O2STANDARD nitrogen = MOLES_N2STANDARD var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed diff --git a/code/game/turfs/simulated/shuttle.dm b/code/game/turfs/simulated/shuttle.dm index 0c5e6c08f6b..7a781679173 100644 --- a/code/game/turfs/simulated/shuttle.dm +++ b/code/game/turfs/simulated/shuttle.dm @@ -1,7 +1,6 @@ /turf/simulated/shuttle name = "shuttle" icon = 'icons/turf/shuttle.dmi' - flags = null thermal_conductivity = 0.05 heat_capacity = 0 layer = 2 @@ -13,6 +12,9 @@ density = 1 blocks_air = 1 +/turf/simulated/shuttle/rpd_act(mob/user, obj/item/rpd/our_rpd) + if(our_rpd.mode == RPD_DELETE_MODE)//No pipes on shuttles + our_rpd.delete_all_pipes(user, src) /turf/simulated/shuttle/narsie_act() if(prob(20)) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index db85329f8c1..a24e6f2953f 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -168,6 +168,18 @@ if(prob(50)) dismantle_wall() +/turf/simulated/wall/rpd_act(mob/user, obj/item/rpd/our_rpd) + if(our_rpd.mode == RPD_ATMOS_MODE) + playsound(src, "sound/weapons/circsawhit.ogg", 50, 1) + user.visible_message("[user] starts drilling a hole in [src]...", "You start drilling a hole in [src]...", "You hear drilling.") + if(!do_after(user, our_rpd.walldelay, target = src)) //Drilling into walls takes time + return + our_rpd.create_atmos_pipe(user, src) + else if(our_rpd.mode == RPD_DISPOSALS_MODE) + return + else + ..() + /turf/simulated/wall/mech_melee_attack(obj/mecha/M) if(M.damtype == "brute") playsound(src, 'sound/weapons/punch4.ogg', 50, 1) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 60c63d0f221..58911d952b4 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -3,7 +3,6 @@ name = "\proper space" icon_state = "0" dynamic_lighting = 0 - flags = RPD_ALLOWED_HERE luminosity = 1 temperature = TCMB diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index 2831894e3ea..c08189e4d93 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -1,5 +1,4 @@ /turf/space/transit - flags = null var/pushdirection // push things that get caught in the transit tile this direction //Overwrite because we dont want people building rods in space. @@ -118,7 +117,8 @@ AM.newtonian_move(dir) - +/turf/space/transit/rpd_act() + return //Overwrite because we dont want people building rods in space. /turf/space/transit/attackby() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index f70aee9740f..337233b5bf4 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -71,6 +71,21 @@ /turf/ex_act(severity) return 0 +/turf/rpd_act(mob/user, obj/item/rpd/our_rpd) //This is the default turf behaviour for the RPD; override it as required + if(our_rpd.mode == RPD_ATMOS_MODE) + our_rpd.create_atmos_pipe(user, src) + else if(our_rpd.mode == RPD_DISPOSALS_MODE) + for(var/obj/machinery/door/airlock/A in src) + if(A.density) + to_chat(user, "That type of pipe won't fit under [A]!") + return + our_rpd.create_disposals_pipe(user, src) + else if(our_rpd.mode == RPD_ROTATE_MODE) + our_rpd.rotate_all_pipes(user, src) + else if(our_rpd.mode == RPD_FLIP_MODE) + our_rpd.flip_all_pipes(user, src) + else if(our_rpd.mode == RPD_DELETE_MODE) + our_rpd.delete_all_pipes(user, src) /turf/bullet_act(var/obj/item/projectile/Proj) if(istype(Proj ,/obj/item/projectile/beam/pulse)) diff --git a/code/game/turfs/unsimulated.dm b/code/game/turfs/unsimulated.dm index 5c9509a3d68..35b6c2056e3 100644 --- a/code/game/turfs/unsimulated.dm +++ b/code/game/turfs/unsimulated.dm @@ -7,6 +7,9 @@ /turf/unsimulated/can_lay_cable() return 0 +/turf/unsimulated/rpd_act() + return + /turf/unsimulated/floor/plating/vox icon_state = "plating" name = "plating" diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index 32d5824c4d5..da843d8e53c 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -37,7 +37,7 @@ // Failing that... if(!(damagetype & BRUTELOSS) && !(damagetype & FIRELOSS) && !(damagetype & TOXLOSS) && !(damagetype & OXYLOSS)) - if(NO_BREATHE in species.species_traits) + if(NO_BREATHE in dna.species.species_traits) // the ultimate fallback take_overall_damage(max(dmgamt - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0), 0) else @@ -84,7 +84,7 @@ do_suicide(damagetype, held_item) return - to_chat(viewers(src), "[src] [replacetext(pick(species.suicide_messages), "their", p_their())] It looks like [p_theyre()] trying to commit suicide.") + to_chat(viewers(src), "[src] [replacetext(pick(dna.species.suicide_messages), "their", p_their())] It looks like [p_theyre()] trying to commit suicide.") do_suicide(0) updatehealth() diff --git a/code/game/world.dm b/code/game/world.dm index ffb9dfb1ecd..516346aeca3 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -21,14 +21,13 @@ var/global/list/map_transition_config = MAP_TRANSITION_CONFIG src.update_status() + space_manager.initialize() //Before the MC starts up . = ..() // Create robolimbs for chargen. populate_robolimb_list() - space_manager.initialize() //Before the MC starts up - Master.Initialize(10, FALSE) processScheduler = new @@ -494,4 +493,3 @@ proc/establish_db_connection() return 1 #undef FAILED_DB_CONNECTION_CUTOFF - diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 91c237a0328..72334496ea5 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -826,10 +826,10 @@ var/list/admin_verbs_ticket = list( if(!istype(H)) if(istype(H, /mob/living/carbon/brain)) var/mob/living/carbon/brain/B = H - if(istype(B.container, /obj/item/mmi/posibrain/ipc)) - var/obj/item/mmi/posibrain/ipc/C = B.container + if(istype(B.container, /obj/item/mmi/robotic_brain/positronic)) + var/obj/item/mmi/robotic_brain/positronic/C = B.container var/obj/item/organ/internal/brain/mmi_holder/posibrain/P = C.loc - if(istype(P.owner, /mob/living/carbon/human)) + if(ishuman(P.owner)) H = P.owner else return @@ -852,10 +852,10 @@ var/list/admin_verbs_ticket = list( if(!istype(H)) if(istype(H, /mob/living/carbon/brain)) var/mob/living/carbon/brain/B = H - if(istype(B.container, /obj/item/mmi/posibrain/ipc)) - var/obj/item/mmi/posibrain/ipc/C = B.container + if(istype(B.container, /obj/item/mmi/robotic_brain/positronic)) + var/obj/item/mmi/robotic_brain/positronic/C = B.container var/obj/item/organ/internal/brain/mmi_holder/posibrain/P = C.loc - if(istype(P.owner, /mob/living/carbon/human)) + if(ishuman(P.owner)) H = P.owner else return diff --git a/code/modules/admin/buildmode.dm b/code/modules/admin/buildmode.dm index d628df054c6..b04b9d2b96a 100644 --- a/code/modules/admin/buildmode.dm +++ b/code/modules/admin/buildmode.dm @@ -14,6 +14,7 @@ /obj/screen/buildmode icon = 'icons/misc/buildmode.dmi' var/datum/click_intercept/buildmode/bd + layer = HUD_LAYER_BUILDMODE /obj/screen/buildmode/New(bld) ..() @@ -78,6 +79,7 @@ /obj/effect/buildmode_reticule var/image/I var/client/cl + anchored = TRUE /obj/effect/buildmode_reticule/New(var/turf/t, var/client/c) loc = t @@ -349,13 +351,13 @@ if(BOOM_BUILDMODE) devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null if(devastation == null) devastation = -1 - var/heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null + heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null if(heavy == null) heavy = -1 - var/light = input("Range of light impact. -1 to none", text("Input")) as num|null + light = input("Range of light impact. -1 to none", text("Input")) as num|null if(light == null) light = -1 - var/flash = input("Range of flash. -1 to none", text("Input")) as num|null + flash = input("Range of flash. -1 to none", text("Input")) as num|null if(flash == null) flash = -1 - var/flames = input("Range of flames. -1 to none", text("Input")) as num|null + flames = input("Range of flames. -1 to none", text("Input")) as num|null if(flames == null) flames = -1 if(SAVE_BUILDMODE) @@ -454,10 +456,12 @@ var/turf/T = get_turf(object) log_admin("Build Mode: [key_name(user)] modified [T] ([T.x],[T.y],[T.z]) to [objholder]") T.ChangeTurf(objholder) - else + else if(!isnull(objholder)) var/obj/A = new objholder (get_turf(object)) A.setDir(build_dir) log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [build_dir]") + else + to_chat(user, "Select object type first.") else if(right_click) if(isobj(object)) log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])") @@ -625,7 +629,7 @@ L2.color = L.color link_lines += L2 if(BOOM_BUILDMODE) - explosion(object, devastation, heavy, light, flash, null, null,flames) + explosion(object, devastation, heavy, light, flash, null, TRUE, flames) if(SAVE_BUILDMODE) if(!cornerA) cornerA = select_tile(get_turf(object)) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index abfc807f9df..798185188ff 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -337,7 +337,7 @@ if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/queen/large , null, null, delmob, 1 ) if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob, 1 ) if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob, 1 ) - if("human") M.change_mob_type( /mob/living/carbon/human/human , null, null, delmob, 1 ) + if("human") M.change_mob_type( /mob/living/carbon/human, null, null, delmob, 1 ) if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob, 1 ) if("monkey") M.change_mob_type( /mob/living/carbon/human/monkey , null, null, delmob, 1 ) if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob, 1 ) diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm index 3d524e863cd..bffaaa9bc9c 100644 --- a/code/modules/admin/verbs/onlyone.dm +++ b/code/modules/admin/verbs/onlyone.dm @@ -3,14 +3,14 @@ alert("The game hasn't started yet!") return - var/list/incompatible_species = list("Plasmaman", "Vox") + var/list/incompatible_species = list(/datum/species/plasmaman, /datum/species/vox) for(var/mob/living/carbon/human/H in player_list) if(H.stat == DEAD || !(H.client)) continue if(is_special_character(H)) continue - if(H.species.name in incompatible_species) - H.set_species("Human") + if(is_type_in_list(H.dna.species, incompatible_species)) + H.set_species(/datum/species/human) var/datum/preferences/A = new() // Randomize appearance A.copy_to(H) @@ -49,7 +49,7 @@ W.assignment = "Highlander" W.registered_name = H.real_name H.equip_to_slot_or_del(W, slot_wear_id) - H.species.after_equip_job(null, H) + H.dna.species.after_equip_job(null, H) H.regenerate_icons() message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ONE! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1) diff --git a/code/modules/admin/verbs/onlyoneteam.dm b/code/modules/admin/verbs/onlyoneteam.dm index 12567cec70b..715472128b8 100644 --- a/code/modules/admin/verbs/onlyoneteam.dm +++ b/code/modules/admin/verbs/onlyoneteam.dm @@ -3,15 +3,15 @@ alert("The game hasn't started yet!") return - var/list/incompatible_species = list("Plasmaman", "Vox") + var/list/incompatible_species = list(/datum/species/plasmaman, /datum/species/vox) var/team_toggle = 0 for(var/mob/living/carbon/human/H in player_list) if(H.stat == DEAD || !(H.client)) continue if(is_special_character(H)) continue - if(H.species.name in incompatible_species) - H.set_species("Human") + if(is_type_in_list(H.dna.species, incompatible_species)) + H.set_species(/datum/species/human) var/datum/preferences/A = new() // Randomize appearance A.copy_to(H) @@ -55,7 +55,7 @@ H.equip_to_slot_or_del(W, slot_wear_id) team_toggle = !team_toggle - H.species.after_equip_job(null, H) + H.dna.species.after_equip_job(null, H) H.regenerate_icons() message_admins("[key_name_admin(usr)] used DODGEBAWWWWWWWL! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 94e0ea2acce..627cde823fa 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -37,7 +37,7 @@ createCorpse() /obj/effect/landmark/corpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it. - var/mob/living/carbon/human/human/M = new /mob/living/carbon/human/human (src.loc) + var/mob/living/carbon/human/M = new /mob/living/carbon/human(src.loc) M.real_name = src.name M.death(1) //Kills the new mob M.adjustOxyLoss(oxy_damage) @@ -293,6 +293,6 @@ /obj/effect/landmark/corpse/abductor //Connected to ruins, for some reason? name = "abductor" mobname = "???" - mob_species = "abductor" + mob_species = /datum/species/abductor corpseuniform = /obj/item/clothing/under/color/grey corpseshoes = /obj/item/clothing/shoes/combat diff --git a/code/modules/awaymissions/map_rng.dm b/code/modules/awaymissions/map_rng.dm index 7618996fdf9..77954eafb9f 100644 --- a/code/modules/awaymissions/map_rng.dm +++ b/code/modules/awaymissions/map_rng.dm @@ -20,7 +20,7 @@ template = map_templates[template_name] /obj/effect/landmark/map_loader/Initialize() - ..() + . = ..() if(template) load(template) diff --git a/code/modules/awaymissions/maploader/reader.dm b/code/modules/awaymissions/maploader/reader.dm index 5ff625544fd..816007d4ff8 100644 --- a/code/modules/awaymissions/maploader/reader.dm +++ b/code/modules/awaymissions/maploader/reader.dm @@ -57,8 +57,6 @@ var/global/dmm_suite/preloader/_preloader = new var/list/grid_models = list() var/key_len = 0 - - var/dmm_suite/loaded_map/LM = new // This try-catch is used as a budget "Finally" clause, as the dirt count // needs to be reset @@ -128,7 +126,6 @@ var/global/dmm_suite/preloader/_preloader = new bounds[MAP_MAXY] = max(bounds[MAP_MAXY], min(ycrd, world.maxy)) var/maxx = xcrdStart - log_debug("[xcrdStart]") if(measureOnly) for(var/line in gridLines) maxx = max(maxx, xcrdStart + length(line) / key_len - 1) diff --git a/code/modules/awaymissions/mission_code/spacehotel_npcs.dm b/code/modules/awaymissions/mission_code/spacehotel_npcs.dm index dcf4a48a280..2a524ab738c 100644 --- a/code/modules/awaymissions/mission_code/spacehotel_npcs.dm +++ b/code/modules/awaymissions/mission_code/spacehotel_npcs.dm @@ -3,8 +3,8 @@ override_under = /obj/item/clothing/under/mafia chattyness = SNPC_CHANCE_TALK / 4 -/mob/living/carbon/human/interactive/away/hotel/New(loc) - ..(loc, "Skrell") +/mob/living/carbon/human/interactive/away/hotel/Initialize(mapload) + . = ..(mapload, /datum/species/skrell) /mob/living/carbon/human/interactive/away/hotel/doSetup() ..() @@ -24,12 +24,6 @@ for(var/obj/item/I in get_all_slots()) I.flags |= NODROP - // FIXME(crazylemon) a hack to prevent guards from running around with an - // extra security jumpsuit like a goof - for(var/obj/item/clothing/under/U in get_all_slots()) - if(w_uniform != U) - qdel(U) - /mob/living/carbon/human/interactive/away/hotel/guard/KnockOut() // you'll never take me alive (this triggers the implant) emote("deathgasp") diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index d159ed70eb2..b26bdba7d92 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -82,12 +82,12 @@ user.mutations.Add(XRAY) if(ishuman(user)) var/mob/living/carbon/human/human = user - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(user, "Your flesh rapidly mutates!") to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(user, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) user.regenerate_icons() if("Wealth") to_chat(user, "Your wish is granted, but at a terrible cost...") @@ -95,12 +95,12 @@ new /obj/structure/closet/syndicate/resources/everything(loc) if(ishuman(user)) var/mob/living/carbon/human/human = user - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(user, "Your flesh rapidly mutates!") to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(user, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) user.regenerate_icons() if("Immortality") to_chat(user, "Your wish is granted, but at a terrible cost...") @@ -108,12 +108,12 @@ user.verbs += /mob/living/carbon/proc/immortality if(ishuman(user)) var/mob/living/carbon/human/human = user - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(user, "Your flesh rapidly mutates!") to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(user, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) user.regenerate_icons() if("To Kill") to_chat(user, "Your wish is granted, but at a terrible cost...") @@ -130,12 +130,12 @@ obj_count++ if(ishuman(user)) var/mob/living/carbon/human/human = user - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(user, "Your flesh rapidly mutates!") to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(user, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) user.regenerate_icons() if("Peace") to_chat(user, "Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence.") diff --git a/code/modules/awaymissions/snpc.dm b/code/modules/awaymissions/snpc.dm index bd7046e3b2c..04e3bf19b8e 100644 --- a/code/modules/awaymissions/snpc.dm +++ b/code/modules/awaymissions/snpc.dm @@ -4,22 +4,24 @@ var/squad_member = 0 // was spawned by squad var/home_z -/mob/living/carbon/human/interactive/away/New() - ..() +/mob/living/carbon/human/interactive/away/Initialize(mapload) + . = ..() TRAITS |= TRAIT_ROBUST faction += "away" /mob/living/carbon/human/interactive/away/random() - if(ispath(override_under, /obj/item/clothing/under)) - equip_to_slot(new override_under(src), slot_w_uniform) ..() + // a little hacky but it should prevent doubled uniforms + if(ispath(override_under, /obj/item/clothing/under)) + var/old_under = w_uniform + w_uniform = null + equip_to_slot(new override_under(src), slot_w_uniform) + qdel(old_under) /mob/living/carbon/human/interactive/away/doSetup() ..() var/datum/data/pda/app/messenger/M = MYPDA.find_program(/datum/data/pda/app/messenger) M.toff = 1 - var/datum/data/pda/app/chatroom/C = MYPDA.find_program(/datum/data/pda/app/chatroom) - C.toff = 1 /mob/living/carbon/human/interactive/away/job2area() return away_area @@ -80,4 +82,4 @@ if(living < squad_size && !length(viewers(src, world.view))) var/mob/living/carbon/human/interactive/away/A = new squad_type(loc) squad += A - A.squad_member = 1 \ No newline at end of file + A.squad_member = 1 diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index d3dd6a5438b..c7f8504f13e 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -246,6 +246,13 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE) "sig_low.gif" = 'icons/program_icons/sig_low.gif', "sig_lan.gif" = 'icons/program_icons/sig_lan.gif', "sig_none.gif" = 'icons/program_icons/sig_none.gif', + "smmon_0.gif" = 'icons/program_icons/smmon_0.gif', + "smmon_1.gif" = 'icons/program_icons/smmon_1.gif', + "smmon_2.gif" = 'icons/program_icons/smmon_2.gif', + "smmon_3.gif" = 'icons/program_icons/smmon_3.gif', + "smmon_4.gif" = 'icons/program_icons/smmon_4.gif', + "smmon_5.gif" = 'icons/program_icons/smmon_5.gif', + "smmon_6.gif" = 'icons/program_icons/smmon_6.gif', ) /datum/asset/nanoui @@ -317,7 +324,7 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE) for(var/D in cardinal) assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipe-item.dmi', state, D) for(var/state in icon_states('icons/obj/pipes/disposal.dmi')) - if(!(state in list("conpipe-c", "conpipe-j1", "conpipe-s", "conpipe-t", "conpipe-y", "intake", "outlet"))) //Pipes we want sprites for + if(!(state in list("pipe-c", "pipe-j1", "pipe-s", "pipe-t", "pipe-y", "intake", "outlet"))) //Pipes we want sprites for continue for(var/D in cardinal) assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipes/disposal.dmi', state, D) diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index db4f33ac121..f3919c2ba27 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -246,10 +246,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts switch(current_tab) if(TAB_CHAR) // Character Settings - var/datum/species/S = all_species[species] + var/datum/species/S = GLOB.all_species[species] if(!istype(S)) //The species was invalid. Set the species to the default, fetch the datum for that species and generate a random character. species = initial(species) - S = all_species[species] + S = GLOB.all_species[species] random_character() dat += "
" @@ -369,21 +369,40 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/status = organ_data[name] var/organ_name = null switch(name) - if("chest") organ_name = "torso" - if("groin") organ_name = "lower body" - if("head") organ_name = "head" - if("l_arm") organ_name = "left arm" - if("r_arm") organ_name = "right arm" - if("l_leg") organ_name = "left leg" - if("r_leg") organ_name = "right leg" - if("l_foot") organ_name = "left foot" - if("r_foot") organ_name = "right foot" - if("l_hand") organ_name = "left hand" - if("r_hand") organ_name = "right hand" - if("heart") organ_name = "heart" - if("eyes") organ_name = "eyes" + if("chest") + organ_name = "torso" + if("groin") + organ_name = "lower body" + if("head") + organ_name = "head" + if("l_arm") + organ_name = "left arm" + if("r_arm") + organ_name = "right arm" + if("l_leg") + organ_name = "left leg" + if("r_leg") + organ_name = "right leg" + if("l_foot") + organ_name = "left foot" + if("r_foot") + organ_name = "right foot" + if("l_hand") + organ_name = "left hand" + if("r_hand") + organ_name = "right hand" + if("eyes") + organ_name = "eyes" + if("heart") + organ_name = "heart" + if("lungs") + organ_name = "lungs" + if("liver") + organ_name = "liver" + if("kidneys") + organ_name = "kidneys" - if(status in list("cyborg", "amputated", "mechanical", "assisted")) + if(status in list("cyborg", "amputated", "cybernetic")) ++ind if(ind > 1) dat += ", " @@ -395,14 +414,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else R = basic_robolimb dat += "\t[R.company] [organ_name] prosthesis" - if("amputated") dat += "\tAmputated [organ_name]" - if("mechanical") dat += "\tMechanical [organ_name]" - if("assisted") - switch(organ_name) - if("heart") dat += "\tPacemaker-assisted [organ_name]" - if("voicebox") dat += "\tSurgically altered [organ_name]" - if("eyes") dat += "\tRetinal overlayed [organ_name]" - else dat += "\tMechanically assisted [organ_name]" + if("amputated") + dat += "\tAmputated [organ_name]" + if("cybernetic") + dat += "\tCybernetic [organ_name]" if(!ind) dat += "\[...\]
" else dat += "
" @@ -813,7 +828,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return 1 /datum/preferences/proc/ShowDisabilityState(mob/user,flag,label) - var/datum/species/S = all_species[species] + var/datum/species/S = GLOB.all_species[species] if(flag==DISABILITY_FLAG_FAT && !(CAN_BE_FAT in S.species_traits)) return "
  • [species] cannot be fat.
  • " return "
  • [label]: [disabilities & flag ? "Yes" : "No"]
  • " @@ -1038,7 +1053,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts /datum/preferences/proc/process_link(mob/user, list/href_list) if(!user) return - var/datum/species/S = all_species[species] + var/datum/species/S = GLOB.all_species[species] if(href_list["preference"] == "job") switch(href_list["task"]) if("close") @@ -1276,7 +1291,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts new_species += whitelisted_species species = input("Please select a species", "Character Generation", null) in new_species - var/datum/species/NS = all_species[species] + var/datum/species/NS = GLOB.all_species[species] if(!istype(NS)) //The species was invalid. Notify the user and fail out. species = prev_species to_chat(user, "Invalid species, please pick something else.") @@ -1866,26 +1881,31 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts rlimb_data[second_limb] = choice organ_data[second_limb] = "cyborg" if("organs") - var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes") - if(!organ_name) return + var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Eyes", "Heart", "Lungs", "Liver", "Kidneys") + if(!organ_name) + return var/organ = null switch(organ_name) - if("Heart") - organ = "heart" if("Eyes") organ = "eyes" + if("Heart") + organ = "heart" + if("Lungs") + organ = "lungs" + if("Liver") + organ = "liver" + if("Kidneys") + organ = "kidneys" - var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal","Assisted","Mechanical") + var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal", "Cybernetic") if(!new_state) return switch(new_state) if("Normal") organ_data[organ] = null - if("Assisted") - organ_data[organ] = "assisted" - if("Mechanical") - organ_data[organ] = "mechanical" + if("Cybernetic") + organ_data[organ] = "cybernetic" if("clientfps") var/version_message @@ -2063,8 +2083,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return 1 /datum/preferences/proc/copy_to(mob/living/carbon/human/character) - var/datum/species/S = all_species[species] - character.change_species(species) // Yell at me if this causes everything to melt + var/datum/species/S = GLOB.all_species[species] + character.set_species(S.type) // Yell at me if this causes everything to melt if(be_random_name) real_name = random_name(gender,species) @@ -2130,9 +2150,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else var/obj/item/organ/internal/I = character.get_int_organ_tag(name) if(I) - if(status == "assisted") - I.mechassist() - else if(status == "mechanical") + if(status == "cybernetic") I.robotize() character.dna.b_type = b_type @@ -2152,10 +2170,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.undershirt = undershirt character.socks = socks - if(character.species.bodyflags & HAS_HEAD_ACCESSORY) + if(character.dna.species.bodyflags & HAS_HEAD_ACCESSORY) H.headacc_colour = hacc_colour H.ha_style = ha_style - if(character.species.bodyflags & HAS_MARKINGS) + if(character.dna.species.bodyflags & HAS_MARKINGS) character.m_colours = m_colours character.m_styles = m_styles @@ -2165,14 +2183,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.backbag = backbag //Debugging report to track down a bug, which randomly assigned the plural gender to people. - if(S.has_gender && (character.gender in list(PLURAL, NEUTER))) + if(character.dna.species.has_gender && (character.gender in list(PLURAL, NEUTER))) if(isliving(src)) //Ghosts get neuter by default message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.") character.change_gender(MALE) character.change_eye_color(e_colour) - if(disabilities & DISABILITY_FLAG_FAT && (CAN_BE_FAT in character.species.species_traits)) + if(disabilities & DISABILITY_FLAG_FAT && (CAN_BE_FAT in character.dna.species.species_traits)) character.dna.SetSEState(FATBLOCK,1,1) character.overeatduration = 600 @@ -2215,7 +2233,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if(disabilities & DISABILITY_FLAG_SCRAMBLED) character.dna.SetSEState(SCRAMBLEBLOCK,1,1) - S.handle_dna(character) + character.dna.species.handle_dna(character) if(character.dna.dirtySE) character.dna.UpdateSE() diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index a175e39bc71..318cf8fb0bb 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -252,7 +252,7 @@ autohiss_mode = text2num(query.item[52]) //Sanitize - var/datum/species/SP = all_species[species] + var/datum/species/SP = GLOB.all_species[species] metadata = sanitize_text(metadata, initial(metadata)) real_name = reject_bad_name(real_name, 1) if(isnull(species)) species = "Human" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 060e53df5b7..a5b4e614551 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -49,12 +49,12 @@ if("exclude" in species_restricted) exclusive = 1 - if(H.species) + if(H.dna.species) if(exclusive) - if(!(H.species.name in species_restricted)) + if(!(H.dna.species.name in species_restricted)) wearable = 1 else - if(H.species.name in species_restricted) + if(H.dna.species.name in species_restricted) wearable = 1 if(!wearable) @@ -504,7 +504,7 @@ BLIND // can't see anything /obj/item/clothing/suit/equipped(var/mob/living/carbon/human/user, var/slot) //Handle tail-hiding on a by-species basis. ..() if(ishuman(user) && hide_tail_by_species && slot == slot_wear_suit) - if(user.species.name in hide_tail_by_species) + if(user.dna.species.name in hide_tail_by_species) if(!(flags_inv & HIDETAIL)) //Hide the tail if the user's species is in the hide_tail_by_species list and the tail isn't already hidden. flags_inv |= HIDETAIL else diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 88796165114..3156b617c03 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -6,6 +6,7 @@ var/magboot_state = "magboots" var/magpulse = 0 var/slowdown_active = 2 + var/slowdown_passive = SHOES_SLOWDOWN actions_types = list(/datum/action/item_action/toggle) strip_delay = 70 put_on_delay = 70 @@ -14,7 +15,7 @@ /obj/item/clothing/shoes/magboots/attack_self(mob/user) if(magpulse) flags &= ~NOSLIP - slowdown = SHOES_SLOWDOWN + slowdown = slowdown_passive else flags |= NOSLIP slowdown = slowdown_active @@ -53,4 +54,18 @@ obj/item/clothing/shoes/magboots/syndie/advance //For the Syndicate Strike Team desc = "Reverse-engineered magboots that appear to be based on an advanced model, as they have a lighter magnetic pull. Property of Gorlex Marauders." name = "advanced blood-red magboots" - slowdown_active = SHOES_SLOWDOWN \ No newline at end of file + slowdown_active = SHOES_SLOWDOWN + +/obj/item/clothing/shoes/magboots/clown + desc = "The prankster's standard-issue clowning shoes. Damn they're huge! There's a red light on the side." + name = "clown shoes" + icon_state = "clownmag0" + magboot_state = "clownmag" + item_state = "clown_shoes" + slowdown = SHOES_SLOWDOWN+1 + slowdown_active = SHOES_SLOWDOWN+1 + slowdown_passive = SHOES_SLOWDOWN+1 + item_color = "clown" + silence_steps = 1 + shoe_sound = "clownstep" + origin_tech = "magnets=4;syndicate=2" \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 8ee357b1ffb..1e874772478 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -16,7 +16,7 @@ /obj/item/clothing/head/helmet/space/capspace/equipped(mob/living/carbon/human/user, slot) if(ishuman(user) && slot == slot_head) - if(user.species.name == "Vox") + if(isvox(user)) if(flags & BLOCKHAIR) flags &= ~BLOCKHAIR else diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 49991df72d7..74af696e76e 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -116,7 +116,7 @@ return 1 // Okay, it wasn't a terminal being touched, check for all the simple insertions. - if(input_device.type in list(/obj/item/paicard, /obj/item/mmi, /obj/item/mmi/posibrain)) + if(input_device.type in list(/obj/item/paicard, /obj/item/mmi, /obj/item/mmi/robotic_brain)) if(integrated_ai) integrated_ai.attackby(input_device,user) // If the transfer was successful, we can clear out our vars. diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index eab5aa0c5bb..c65ea335c4d 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -609,8 +609,8 @@ var/species_icon = 'icons/mob/rig_back.dmi' // Since setting mob_icon will override the species checks in // update_inv_wear_suit(), handle species checks here. - if(wearer && sprite_sheets && sprite_sheets[wearer.get_species()]) - species_icon = sprite_sheets[wearer.get_species()] + if(wearer && sprite_sheets && sprite_sheets[wearer.dna.species.name]) + species_icon = sprite_sheets[wearer.dna.species.name] mob_icon = image("icon" = species_icon, "icon_state" = "[icon_state]") if(installed_modules.len) diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index aac34032dfb..764ee71583a 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -136,7 +136,7 @@ user.visible_message("[user] places \the [src] against [M]'s chest and listens attentively.", "You place \the [src] against [M]'s chest...") var/obj/item/organ/internal/H = M.get_int_organ(/obj/item/organ/internal/heart) var/obj/item/organ/internal/L = M.get_int_organ(/obj/item/organ/internal/lungs) - if((H && M.pulse) || (L && !(BREATHLESS in M.mutations) && !(NO_BREATHE in M.species.species_traits))) + if((H && M.pulse) || (L && !(BREATHLESS in M.mutations) && !(NO_BREATHE in M.dna.species.species_traits))) var/color = "notice" if(H) var/heart_sound diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index 1ca94e9a4f3..76bef3e056b 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -69,9 +69,10 @@ item_state = "clown" item_color = "clown" flags_size = ONESIZEFITSALL + var/honk_sound = 'sound/items/bikehorn.ogg' /obj/item/clothing/under/rank/clown/hit_reaction() - playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1) + playsound(loc, honk_sound, 50, 1, -1) if(ishuman(loc)) var/mob/living/carbon/human/H = loc if(H.mind && H.mind.assigned_role == "Clown") diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index f1739750a0a..012c79bab06 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -25,15 +25,6 @@ time = 15 category = CAT_WEAPON -/datum/crafting_recipe/lance - name = "explosive lance (grenade)" - result = /obj/item/twohanded/spear - reqs = list(/obj/item/twohanded/spear = 1, - /obj/item/grenade = 1) - parts = list(/obj/item/grenade = 1) - time = 15 - category = CAT_WEAPON - /datum/crafting_recipe/molotov name = "Molotov" result = /obj/item/reagent_containers/food/drinks/bottle/molotov diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index a229b72f745..2a734e91dcd 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -45,7 +45,7 @@ var/mob/living/carbon/human/target = M - if(istype(target.species, /datum/species/machine)) + if(ismachine(target)) to_chat(user, "[target] has no skin, how do you expect to tattoo [target.p_them()]?") return @@ -54,7 +54,7 @@ return var/datum/sprite_accessory/body_markings/tattoo/temp_tatt = marking_styles_list[tattoo_icon] - if(!(target.species.name in temp_tatt.species_allowed)) + if(!(target.dna.species.name in temp_tatt.species_allowed)) to_chat(user, "You can't think of a way to make the [tattoo_name] design work on [target == user ? "your" : "[target]'s"] body type.") return @@ -268,7 +268,7 @@ return var/mob/living/carbon/human/target = user - if(!istype(target) || target.get_species() != "Tajaran") // Only catbeasts, kthnx. + if(!istype(target) || !istajaran(target)) // Only catbeasts, kthnx. return if(target.change_body_accessory("Jay Wingler Tail")) @@ -1276,7 +1276,7 @@ /obj/item/fluff/zekemirror/attack_self(mob/user) var/mob/living/carbon/human/target = user - if(!istype(target) || target.get_species() != "Skrell") // It'd be strange to see other races with head tendrils. + if(!istype(target) || !isskrell(target)) // It'd be strange to see other races with head tendrils. return if(target.change_hair("Zekes Tentacles", 1)) @@ -1354,6 +1354,13 @@ item_state = "teri_horn" honk_sound = 'sound/items/teri_horn.ogg' +/obj/item/clothing/accessory/medal/fluff/elo //V-Force_Bomber: E.L.O. + name = "distinguished medal of loyalty and excellence" + desc = "This medal is cut into the shape of a Victoria Cross, and is awarded to those who have proven themselves to Nanotrasen with a long and successful career." + icon = 'icons/obj/custom_items.dmi' + icon_state = "elo-medal" + item_color = "elo-medal" + /obj/item/clothing/suit/fluff/vetcoat //Furasian: Fillmoore Grayson name = "Veteran Coat" desc = "An old, yet well-kept Nanotrasen uniform. Very few of its kind are still produced." @@ -1379,4 +1386,4 @@ icon_state = "panzermedal" item_state = "panzermedal" item_color = "panzermedal" - slot_flags = SLOT_TIE \ No newline at end of file + slot_flags = SLOT_TIE diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index abab5c39254..cd9b0c02206 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -2,6 +2,10 @@ announceWhen = 50 endWhen = 900 + var/list/spawned_mobs = list( + /mob/living/simple_animal/hostile/carp = 95, + /mob/living/simple_animal/hostile/carp/megacarp = 5, + ) var/list/spawned_carp = list() /datum/event/carp_migration/setup() @@ -17,6 +21,7 @@ event_announcement.Announce(announcement, "Lifesign Alert") /datum/event/carp_migration/start() + if(severity == EVENT_LEVEL_MAJOR) spawn_fish(landmarks_list.len) else if(severity == EVENT_LEVEL_MODERATE) @@ -32,19 +37,17 @@ spawn_locations.Add(C.loc) spawn_locations = shuffle(spawn_locations) num_groups = min(num_groups, spawn_locations.len) - + var/i = 1 while(i <= num_groups) var/group_size = rand(group_size_min, group_size_max) for(var/j = 1, j <= group_size, j++) - var/carptype = /mob/living/simple_animal/hostile/carp - if(prob(5)) - carptype = /mob/living/simple_animal/hostile/carp/megacarp + var/carptype = pickweight(spawned_mobs) spawned_carp.Add(new carptype(spawn_locations[i])) i++ /datum/event/carp_migration/end() - for(var/mob/living/simple_animal/hostile/carp/C in spawned_carp) + for(var/mob/living/simple_animal/hostile/C in spawned_carp) if(!C.stat) var/turf/T = get_turf(C) if(istype(T, /turf/space)) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index cf2e3621498..87836f217b8 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -18,7 +18,7 @@ continue if(!H.client) continue - if(VIRUSIMMUNE in H.species.species_traits) //don't let virus immune things get diseases they're not supposed to get. + if(VIRUSIMMUNE in H.dna.species.species_traits) //don't let virus immune things get diseases they're not supposed to get. continue var/turf/T = get_turf(H) if(!T) diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index ef7b99e1133..888e2b38dd1 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -139,7 +139,8 @@ var/list/event_last_fired = list() new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Sentience", /datum/event/sentience, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Aurora Caelus", /datum/event/aurora_caelus, 15, is_one_shot = TRUE) + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Aurora Caelus", /datum/event/aurora_caelus, 15, is_one_shot = TRUE), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Koi School", /datum/event/carp_migration/koi, 80,) ) /datum/event_container/moderate diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index b4a67ac9850..a66dcd66d0e 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -119,22 +119,22 @@ if(2) //X is an object message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]" - if(9) //X is harmful to humans + if(9) //X is harmful to crew switch(rand(1,7)) //What is X? if(1) //X is a threat - message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO HUMANS" + message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO CREW" if(2) //X is a job - message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO HUMANS" + message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO CREW" if(3) //X is an object - message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO HUMANS" + message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO CREW" if(4) //X is an action - message = "THOSE WHO [ionmust] ARE HARMFUL TO HUMANS" + message = "THOSE WHO [ionmust] ARE HARMFUL TO CREW" if(5) //X is an abstract - message = "[ionabstract] IS HARMFUL TO HUMANS" + message = "[ionabstract] IS HARMFUL TO CREW" if(6) //X is being a job - message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO HUMANS" + message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO CREW" if(7) //X is doing a thing - message = "[ionthings] IS HARMFUL TO HUMANS" + message = "[ionthings] IS HARMFUL TO CREW" if(10 to 11) //(Not) Having X is harmful switch(rand(1,2)) //Is having or not having harmful? @@ -304,16 +304,16 @@ if(24 to 26) //The AI must always message = "YOU MUST ALWAYS [ionmust]" - if(27 to 28) //Humans must eat X to survive + if(27 to 28) //Crew must eat X to survive switch(rand(1,4)) //What is X? if(1) //X is a food - message = "HUMANS MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE" + message = "CREW MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE" if(2) //X is an object - message = "HUMANS MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE" + message = "CREW MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE" if(3) //X is a threat - message = "HUMANS MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE" + message = "CREW MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE" if(4) //X is a job - message = "HUMANS MUST EAT [ionadjectiveshalf][ioncrew1] TO SURVIVE" + message = "CREW MUST EAT [ionadjectiveshalf][ioncrew1] TO SURVIVE" if(29 to 31) //Change jobs or ranks switch(rand(1,2)) //Change job or rank? @@ -360,54 +360,54 @@ if(2) //X is perform Y message = "THE [ioncrew1] MUST [ionmust]" - if(34) //X is non/the only human + if(34) //X is non/the only crew switch(rand(1,2)) //Only or non? - if(1) //Only human + if(1) //Only crew switch(rand(1,7)) //Who is it? if(1) //A specific job - message = "ONLY THE [ioncrew1] ARE HUMAN" + message = "ONLY THE [ioncrew1] ARE CREW" if(2) //Two specific jobs - message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE HUMAN" + message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE CREW" if(3) //Threats - message = "ONLY [ionadjectiveshalf][ionthreats] ARE HUMAN" + message = "ONLY [ionadjectiveshalf][ionthreats] ARE CREW" if(4) // Objects - message = "ONLY [ionadjectiveshalf][ionobjects] ARE HUMAN" + message = "ONLY [ionadjectiveshalf][ionobjects] ARE CREW" if(5) // Species - message = "ONLY [ionspecies] ARE HUMAN" + message = "ONLY [ionspecies] ARE CREW" if(6) //Adjective crewmembers - message = "ONLY [ionadjectives] PEOPLE ARE HUMAN" + message = "ONLY [ionadjectives] PEOPLE ARE CREW" if(7) //Only people who X switch(rand(1,3)) //What is X? if(1) //X is perform an action - message = "ONLY THOSE WHO [ionmust] ARE HUMAN" + message = "ONLY THOSE WHO [ionmust] ARE CREW" if(2) //X is own certain objects - message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE HUMAN" + message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE CREW" if(3) //X is eat certain food - message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE HUMAN" + message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE CREW" - if(2) //Non human + if(2) //Non crew switch(rand(1,7)) //Who is it? if(1) //A specific job - message = "[ioncrew1] ARE NON-HUMAN" + message = "[ioncrew1] ARE NON-CREW" if(2) //Two specific jobs - message = "[ioncrew1] AND [ioncrew2] ARE NON-HUMAN" + message = "[ioncrew1] AND [ioncrew2] ARE NON-CREW" if(3) //Threats - message = "[ionadjectiveshalf][ionthreats] ARE NON-HUMAN" + message = "[ionadjectiveshalf][ionthreats] ARE NON-CREW" if(4) // Objects - message = "[ionadjectiveshalf][ionobjects] ARE NON-HUMAN" + message = "[ionadjectiveshalf][ionobjects] ARE NON-CREW" if(5) // Species - message = "[ionspecies] ARE NON-HUMAN" + message = "[ionspecies] ARE NON-CREW" if(6) //Adjective crewmembers - message = "[ionadjectives] PEOPLE ARE NON-HUMAN" + message = "[ionadjectives] PEOPLE ARE NON-CREW" if(7) //Only people who X switch(rand(1,3)) //What is X? if(1) //X is perform an action - message = "THOSE WHO [ionmust] ARE NON-HUMAN" + message = "THOSE WHO [ionmust] ARE NON-CREW" if(2) //X is own certain objects - message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-HUMAN" + message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-CREW" if(3) //X is eat certain food - message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-HUMAN" + message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-CREW" if(35 to 36) //You must protect or harm X switch(rand(1,2)) //Protect or harm? diff --git a/code/modules/events/koi_mirgration.dm b/code/modules/events/koi_mirgration.dm new file mode 100644 index 00000000000..868457721b2 --- /dev/null +++ b/code/modules/events/koi_mirgration.dm @@ -0,0 +1,9 @@ +/datum/event/carp_migration + spawned_mobs = list( + /mob/living/simple_animal/hostile/retaliate/carp/koi = 95, + /mob/living/simple_animal/hostile/retaliate/carp/koi/honk = 2, + ) + + +/datum/event/carp_migration/koi/start() + spawn_fish(landmarks_list.len) \ No newline at end of file diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index cc59ec78128..321a8135150 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -4,7 +4,7 @@ /datum/event/mass_hallucination/start() for(var/mob/living/carbon/human/H in living_mob_list) var/armor = H.getarmor(type = "rad") - if((RADIMMUNE in H.species.species_traits) || armor >= 75) // Leave radiation-immune species/rad armored players completely unaffected + if((RADIMMUNE in H.dna.species.species_traits) || armor >= 75) // Leave radiation-immune species/rad armored players completely unaffected continue H.AdjustHallucinate(rand(50, 100)) diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index 2f9848a87ef..b0c0d24efaa 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -47,7 +47,7 @@ if(!reagents || !reagents.total_volume) return // The condiment might be empty after the delay. user.visible_message("[user] feeds [M] from [src].") - add_attack_logs(user, M, "Fed [src] containing [reagentlist(src)]") + add_attack_logs(user, M, "Fed [src] containing [reagentlist()]") var/fraction = min(10/reagents.total_volume, 1) reagents.reaction(M, INGEST, fraction) diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 02f743d7478..33987737fa2 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -57,7 +57,7 @@ name = "sandwich" desc = "A sandwich! A timeless classic." icon_state = "breadslice" - baseicon = "sandwich" + baseicon = "sandwichcustom" basename = "sandwich" toptype = new /obj/item/reagent_containers/food/snacks/breadslice() @@ -66,9 +66,10 @@ /obj/item/reagent_containers/food/snacks/customizable name = "sandwich" desc = "A sandwich! A timeless classic." - icon_state = "breadslice" - var/baseicon = "sandwich" - var/basename = "sandwich" + icon = 'icons/obj/food/custom.dmi' + icon_state = "sandwichcustom" + var/baseicon = "sandwichcustom" + var/basename = "sandwichcustom" bitesize = 4 var/top = 1 //Do we have a top? var/obj/item/toptype @@ -94,7 +95,7 @@ desc = "Noodles. With stuff. Delicious." icon_state = "pasta_bot" baseicon = "pasta_bot" - basename = "spaghetti" + basename = "pasta" add_overlays = 0 top = 0 @@ -312,7 +313,7 @@ name = "burger bun" desc = "A bun for a burger. Delicious." icon_state = "burger" - baseicon = "burger" + baseicon = "burgercustom" basename = "burger" toptype = new /obj/item/reagent_containers/food/snacks/bun() diff --git a/code/modules/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm new file mode 100644 index 00000000000..9da07f4f0b8 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm @@ -0,0 +1,434 @@ + +////////////////////// +// Cakes // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sliceable/carrotcake + name = "carrot cake" + desc = "A favorite desert of a certain wascally wabbit. Not a lie." + icon_state = "carrotcake" + slice_path = /obj/item/reagent_containers/food/snacks/carrotcakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#FFD675" + list_reagents = list("nutriment" = 20, "oculine" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/carrotcakeslice + name = "carrot cake slice" + desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." + icon_state = "carrotcake_slice" + trash = /obj/item/trash/plate + filling_color = "#FFD675" + +/obj/item/reagent_containers/food/snacks/sliceable/braincake + name = "brain cake" + desc = "A squishy cake-thing." + icon_state = "braincake" + slice_path = /obj/item/reagent_containers/food/snacks/braincakeslice + slices_num = 5 + filling_color = "#E6AEDB" + bitesize = 3 + list_reagents = list("protein" = 10, "nutriment" = 10, "mannitol" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/braincakeslice + name = "brain cake slice" + desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." + icon_state = "braincakeslice" + trash = /obj/item/trash/plate + filling_color = "#E6AEDB" + +/obj/item/reagent_containers/food/snacks/sliceable/cheesecake + name = "cheese cake" + desc = "DANGEROUSLY cheesy." + icon_state = "cheesecake" + slice_path = /obj/item/reagent_containers/food/snacks/cheesecakeslice + slices_num = 5 + filling_color = "#FAF7AF" + bitesize = 3 + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/cheesecakeslice + name = "cheese cake slice" + desc = "Slice of pure cheestisfaction." + icon_state = "cheesecake_slice" + trash = /obj/item/trash/plate + filling_color = "#FAF7AF" + +/obj/item/reagent_containers/food/snacks/sliceable/plaincake + name = "vanilla cake" + desc = "A plain cake, not a lie." + icon_state = "plaincake" + slice_path = /obj/item/reagent_containers/food/snacks/plaincakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#F7EDD5" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/plaincakeslice + name = "vanilla cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "plaincake_slice" + trash = /obj/item/trash/plate + filling_color = "#F7EDD5" + +/obj/item/reagent_containers/food/snacks/sliceable/orangecake + name = "orange cake" + desc = "A cake with added orange." + icon_state = "orangecake" + slice_path = /obj/item/reagent_containers/food/snacks/orangecakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#FADA8E" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/orangecakeslice + name = "orange cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "orangecake_slice" + trash = /obj/item/trash/plate + filling_color = "#FADA8E" + +/obj/item/reagent_containers/food/snacks/sliceable/limecake + name = "lime cake" + desc = "A cake with added lime." + icon_state = "limecake" + bitesize = 3 + slice_path = /obj/item/reagent_containers/food/snacks/limecakeslice + slices_num = 5 + filling_color = "#CBFA8E" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/limecakeslice + name = "lime cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "limecake_slice" + trash = /obj/item/trash/plate + filling_color = "#CBFA8E" + +/obj/item/reagent_containers/food/snacks/sliceable/lemoncake + name = "lemon cake" + desc = "A cake with added lemon." + icon_state = "lemoncake" + slice_path = /obj/item/reagent_containers/food/snacks/lemoncakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#FAFA8E" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/lemoncakeslice + name = "lemon cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "lemoncake_slice" + trash = /obj/item/trash/plate + filling_color = "#FAFA8E" + +/obj/item/reagent_containers/food/snacks/sliceable/chocolatecake + name = "chocolate cake" + desc = "A cake with added chocolate." + icon_state = "chocolatecake" + slice_path = /obj/item/reagent_containers/food/snacks/chocolatecakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#805930" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/chocolatecakeslice + name = "chocolate cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "chocolatecake_slice" + trash = /obj/item/trash/plate + filling_color = "#805930" + +/obj/item/reagent_containers/food/snacks/sliceable/birthdaycake + name = "birthday cake" + desc = "Happy Birthday..." + icon_state = "birthdaycake" + slice_path = /obj/item/reagent_containers/food/snacks/birthdaycakeslice + slices_num = 5 + filling_color = "#FFD6D6" + bitesize = 3 + list_reagents = list("nutriment" = 20, "sprinkles" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/birthdaycakeslice + name = "birthday cake slice" + desc = "A slice of your birthday" + icon_state = "birthdaycakeslice" + trash = /obj/item/trash/plate + filling_color = "#FFD6D6" + +/obj/item/reagent_containers/food/snacks/sliceable/applecake + name = "apple cake" + desc = "A cake centered with Apple." + icon_state = "applecake" + slice_path = /obj/item/reagent_containers/food/snacks/applecakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#EBF5B8" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/applecakeslice + name = "apple cake slice" + desc = "A slice of heavenly cake." + icon_state = "applecakeslice" + trash = /obj/item/trash/plate + filling_color = "#EBF5B8" + + +////////////////////// +// Cookies // +////////////////////// + +/obj/item/reagent_containers/food/snacks/cookie + name = "cookie" + desc = "COOKIE!!!" + icon_state = "COOKIE!!!" + bitesize = 1 + filling_color = "#DBC94F" + list_reagents = list("nutriment" = 1) + +/obj/item/reagent_containers/food/snacks/fortunecookie + name = "fortune cookie" + desc = "A true prophecy in each cookie!" + icon_state = "fortune_cookie" + filling_color = "#E8E79E" + list_reagents = list("nutriment" = 3) + trash = /obj/item/paper/fortune + +/obj/item/reagent_containers/food/snacks/sugarcookie + name = "sugar cookie" + desc = "Just like your little sister used to make." + icon_state = "sugarcookie" + list_reagents = list("nutriment" = 3, "sugar" = 3) + + +////////////////////// +// Pies // +////////////////////// + +/obj/item/reagent_containers/food/snacks/pie + name = "banana cream pie" + desc = "Just like back home, on clown planet! HONK!" + icon_state = "pie" + trash = /obj/item/trash/plate + filling_color = "#FBFFB8" + bitesize = 3 + list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) + ..() + new/obj/effect/decal/cleanable/pie_smudge(loc) + visible_message("[src] splats.","You hear a splat.") + qdel(src) + +/obj/item/reagent_containers/food/snacks/meatpie + name = "meat-pie" + icon_state = "meatpie" + desc = "An old barber recipe, very delicious!" + trash = /obj/item/trash/plate + filling_color = "#948051" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/tofupie + name = "tofu-pie" + icon_state = "meatpie" + desc = "A delicious tofu pie." + trash = /obj/item/trash/plate + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/amanita_pie + name = "amanita pie" + desc = "Sweet and tasty poison pie." + icon_state = "amanita_pie" + filling_color = "#FFCCCC" + bitesize = 4 + list_reagents = list("nutriment" = 6, "amanitin" = 3, "psilocybin" = 1, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/plump_pie + name = "plump pie" + desc = "I bet you love stuff made out of plump helmets!" + icon_state = "plump_pie" + filling_color = "#B8279B" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/plump_pie/New() + ..() + if(prob(10)) + name = "exceptional plump pie" + desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" // What + reagents.add_reagent("omnizine", 5) + +/obj/item/reagent_containers/food/snacks/xemeatpie + name = "Xeno-pie" + icon_state = "xenomeatpie" + desc = "A delicious meatpie. Probably heretical." + trash = /obj/item/trash/plate + filling_color = "#43DE18" + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/applepie + name = "apple pie" + desc = "A pie containing sweet sweet love... or apple." + icon_state = "applepie" + filling_color = "#E0EDC5" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/cherrypie + name = "cherry pie" + desc = "Taste so good, make a grown man cry." + icon_state = "cherrypie" + filling_color = "#FF525A" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/sliceable/pumpkinpie + name = "pumpkin pie" + desc = "A delicious treat for the autumn months." + icon_state = "pumpkinpie" + slice_path = /obj/item/reagent_containers/food/snacks/pumpkinpieslice + slices_num = 5 + bitesize = 3 + filling_color = "#F5B951" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/pumpkinpieslice + name = "pumpkin pie slice" + desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." + icon_state = "pumpkinpieslice" + trash = /obj/item/trash/plate + filling_color = "#F5B951" + + +////////////////////// +// Donuts // +////////////////////// + +/obj/item/reagent_containers/food/snacks/donut + name = "donut" + desc = "Goes great with Robust Coffee." + icon_state = "donut1" + bitesize = 5 + list_reagents = list("nutriment" = 3, "sugar" = 2) + var/extra_reagent = null + filling_color = "#D2691E" + var/randomized_sprinkles = 1 + +/obj/item/reagent_containers/food/snacks/donut/New() + ..() + if(randomized_sprinkles && prob(30)) + icon_state = "donut2" + name = "frosted donut" + reagents.add_reagent("sprinkles", 2) + filling_color = "#FF69B4" + +/obj/item/reagent_containers/food/snacks/donut/sprinkles + name = "frosted donut" + icon_state = "donut2" + list_reagents = list("nutriment" = 3, "sugar" = 2, "spinkles" = 2) + filling_color = "#FF69B4" + randomized_sprinkles = 0 + +/obj/item/reagent_containers/food/snacks/donut/chaos + name = "chaos donut" + desc = "Like life, it never quite tastes the same." + bitesize = 10 + +/obj/item/reagent_containers/food/snacks/donut/chaos/New() + ..() + extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine") + reagents.add_reagent("[extra_reagent]", 3) + if(prob(30)) + icon_state = "donut2" + name = "frosted chaos donut" + reagents.add_reagent("sprinkles", 2) + filling_color = "#FF69B4" + +/obj/item/reagent_containers/food/snacks/donut/jelly + name = "jelly donut" + desc = "You jelly?" + icon_state = "jdonut1" + extra_reagent = "berryjuice" + +/obj/item/reagent_containers/food/snacks/donut/jelly/New() + ..() + if(extra_reagent) + reagents.add_reagent("[extra_reagent]", 3) + if(prob(30)) + icon_state = "jdonut2" + name = "frosted jelly Donut" + reagents.add_reagent("sprinkles", 2) + filling_color = "#FF69B4" + +/obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly + name = "jelly donut" + desc = "You jelly?" + icon_state = "jdonut1" + extra_reagent = "slimejelly" + +/obj/item/reagent_containers/food/snacks/donut/jelly/cherryjelly + name = "jelly donut" + desc = "You jelly?" + icon_state = "jdonut1" + extra_reagent = "cherryjelly" + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/muffin + name = "muffin" + desc = "A delicious and spongy little cake." + icon_state = "muffin" + filling_color = "#E0CF9B" + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/berryclafoutis + name = "berry clafoutis" + desc = "No black birds, this is a good sign." + icon_state = "berryclafoutis" + trash = /obj/item/trash/plate + bitesize = 3 + list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/poppypretzel + name = "poppy pretzel" + desc = "A large soft pretzel full of POP! It's all twisted up!" + icon_state = "poppypretzel" + filling_color = "#916E36" + list_reagents = list("nutriment" = 5) + +/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit + name = "plump helmet biscuit" + desc = "This is a finely-prepared plump helmet biscuit. The ingredients are exceptionally minced plump helmet, and well-minced dwarven wheat flour." + icon_state = "phelmbiscuit" + filling_color = "#CFB4C4" + list_reagents = list("nutriment" = 5) + +/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit/New() + ..() + if(prob(10)) + name = "exceptional plump helmet biscuit" + desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" // Is this a reference? + reagents.add_reagent("omnizine", 5) + +/obj/item/reagent_containers/food/snacks/appletart + name = "golden apple streusel tart" + desc = "A tasty dessert that won't make it through a metal detector." + icon_state = "gappletart" + trash = /obj/item/trash/plate + filling_color = "#FFFF00" + bitesize = 3 + list_reagents = list("nutriment" = 8, "gold" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/cracker + name = "cracker" + desc = "It's a salted cracker." + icon_state = "cracker" + bitesize = 1 + filling_color = "#F5DEB8" + list_reagents = list("nutriment" = 1) diff --git a/code/modules/food_and_drinks/food/foods/bread.dm b/code/modules/food_and_drinks/food/foods/bread.dm new file mode 100644 index 00000000000..c841f8d65fa --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/bread.dm @@ -0,0 +1,183 @@ + +////////////////////// +// Breads // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sliceable/meatbread + name = "meatbread loaf" + desc = "The culinary base of every self-respecting eloquen/tg/entleman." + icon_state = "meatbread" + slice_path = /obj/item/reagent_containers/food/snacks/meatbreadslice + slices_num = 5 + filling_color = "#FF7575" + list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/meatbreadslice + name = "meatbread slice" + desc = "A slice of delicious meatbread." + icon_state = "meatbreadslice" + trash = /obj/item/trash/plate + filling_color = "#FF7575" + +/obj/item/reagent_containers/food/snacks/sliceable/xenomeatbread + name = "xenomeatbread loaf" + desc = "The culinary base of every self-respecting eloquent gentleman. Extra Heretical." + icon_state = "xenomeatbread" + slice_path = /obj/item/reagent_containers/food/snacks/xenomeatbreadslice + slices_num = 5 + filling_color = "#8AFF75" + list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/xenomeatbreadslice + name = "xenomeatbread slice" + desc = "A slice of delicious meatbread. Extra Heretical." + icon_state = "xenobreadslice" + trash = /obj/item/trash/plate + filling_color = "#8AFF75" + +/obj/item/reagent_containers/food/snacks/sliceable/spidermeatbread + name = "spider meat loaf" + desc = "Reassuringly green meatloaf made from spider meat." + icon_state = "spidermeatbread" + slice_path = /obj/item/reagent_containers/food/snacks/spidermeatbreadslice + slices_num = 5 + list_reagents = list("protein" = 20, "nutriment" = 10, "toxin" = 15, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/spidermeatbreadslice + name = "spider meat bread slice" + desc = "A slice of meatloaf made from an animal that most likely still wants you dead." + icon_state = "xenobreadslice" + trash = /obj/item/trash/plate + list_reagents = list("toxin" = 2) + +/obj/item/reagent_containers/food/snacks/sliceable/bananabread + name = "Banana-nut bread" + desc = "A heavenly and filling treat." + icon_state = "bananabread" + slice_path = /obj/item/reagent_containers/food/snacks/bananabreadslice + slices_num = 5 + filling_color = "#EDE5AD" + list_reagents = list("banana" = 20, "nutriment" = 20) + +/obj/item/reagent_containers/food/snacks/bananabreadslice + name = "Banana-nut bread slice" + desc = "A slice of delicious banana bread." + icon_state = "bananabreadslice" + trash = /obj/item/trash/plate + filling_color = "#EDE5AD" + +/obj/item/reagent_containers/food/snacks/sliceable/tofubread + name = "Tofubread" + icon_state = "Like meatbread but for vegetarians. Not guaranteed to give superpowers." + icon_state = "tofubread" + slice_path = /obj/item/reagent_containers/food/snacks/tofubreadslice + slices_num = 5 + filling_color = "#F7FFE0" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/tofubreadslice + name = "Tofubread slice" + desc = "A slice of delicious tofubread." + icon_state = "tofubreadslice" + trash = /obj/item/trash/plate + filling_color = "#F7FFE0" + +/obj/item/reagent_containers/food/snacks/sliceable/bread + name = "Bread" + icon_state = "Some plain old Earthen bread." + icon_state = "bread" + slice_path = /obj/item/reagent_containers/food/snacks/breadslice + slices_num = 6 + filling_color = "#FFE396" + list_reagents = list("nutriment" = 10) + +/obj/item/reagent_containers/food/snacks/breadslice + name = "Bread slice" + desc = "A slice of home." + icon_state = "breadslice" + trash = /obj/item/trash/plate + filling_color = "#D27332" + list_reagents = list("nutriment" = 2, "bread" = 5) + +/obj/item/reagent_containers/food/snacks/sliceable/creamcheesebread + name = "Cream Cheese Bread" + desc = "Yum yum yum!" + icon_state = "creamcheesebread" + slice_path = /obj/item/reagent_containers/food/snacks/creamcheesebreadslice + slices_num = 5 + filling_color = "#FFF896" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/creamcheesebreadslice + name = "Cream Cheese Bread slice" + desc = "A slice of yum!" + icon_state = "creamcheesebreadslice" + trash = /obj/item/trash/plate + filling_color = "#FFF896" + list_reagents = list("nutriment" = 4, "vitamin" = 1) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/bun + name = "bun" + desc = "The base for any self-respecting burger." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "bun" + list_reagents = list("nutriment" = 1) + +/obj/item/reagent_containers/food/snacks/flatbread + name = "flatbread" + desc = "Bland but filling." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "flatbread" + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/baguette + name = "baguette" + desc = "Bon appetit!" + icon_state = "baguette" + filling_color = "#E3D796" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/twobread + name = "Two Bread" + desc = "It is very bitter and winy." + icon_state = "twobread" + filling_color = "#DBCC9A" + bitesize = 3 + list_reagents = list("nutriment" = 2, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/jelliedtoast + name = "Jellied Toast" + desc = "A slice of bread covered with delicious jam." + icon_state = "jellytoast" + trash = /obj/item/trash/plate + filling_color = "#B572AB" + bitesize = 3 + +/obj/item/reagent_containers/food/snacks/jelliedtoast/cherry + list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/jelliedtoast/slime + list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/rofflewaffles + name = "Roffle Waffles" + desc = "Waffles from Roffle. Co." + icon_state = "rofflewaffles" + trash = /obj/item/trash/waffles + filling_color = "#FF00F7" + bitesize = 4 + list_reagents = list("nutriment" = 8, "psilocybin" = 2, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/waffles + name = "waffles" + desc = "Mmm, waffles." + icon_state = "waffles" + trash = /obj/item/trash/waffles + filling_color = "#E6DEB5" + list_reagents = list("nutriment" = 8, "vitamin" = 1) diff --git a/code/modules/food_and_drinks/food/candy.dm b/code/modules/food_and_drinks/food/foods/candy.dm similarity index 100% rename from code/modules/food_and_drinks/food/candy.dm rename to code/modules/food_and_drinks/food/foods/candy.dm diff --git a/code/modules/food_and_drinks/food/foods/desserts.dm b/code/modules/food_and_drinks/food/foods/desserts.dm new file mode 100644 index 00000000000..ff99efd07be --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/desserts.dm @@ -0,0 +1,97 @@ + +////////////////////// +// Ice Cream // +////////////////////// + +/obj/item/reagent_containers/food/snacks/icecream + name = "ice cream" + desc = "Delicious ice cream." + icon = 'icons/obj/kitchen.dmi' + icon_state = "icecream_cone" + bitesize = 3 + list_reagents = list("nutriment" = 1, "sugar" = 1) + +/obj/item/reagent_containers/food/snacks/icecream/New() + ..() + update_icon() + +/obj/item/reagent_containers/food/snacks/icecream/update_icon() + overlays.Cut() + var/image/filling = image('icons/obj/kitchen.dmi', src, "icecream_color") + filling.icon += mix_color_from_reagents(reagents.reagent_list) + overlays += filling + +/obj/item/reagent_containers/food/snacks/icecream/icecreamcone + name = "ice cream cone" + desc = "Delicious ice cream." + icon_state = "icecream_cone" + volume = 50 + bitesize = 3 + list_reagents = list("nutriment" = 3, "sugar" = 7, "ice" = 2) + +/obj/item/reagent_containers/food/snacks/icecream/icecreamcup + name = "chocolate ice cream cone" + desc = "Delicious ice cream." + icon_state = "icecream_cup" + volume = 50 + bitesize = 6 + list_reagents = list("nutriment" = 5, "chocolate" = 8, "ice" = 2) + +/obj/item/reagent_containers/food/snacks/icecreamsandwich + name = "icecream sandwich" + desc = "Portable Ice-cream in it's own packaging." + icon_state = "icecreamsandwich" + list_reagents = list("nutriment" = 2, "ice" = 2) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/friedbanana + name = "Fried Banana" + desc = "Goreng Pisang, also known as fried bananas." + icon_state = "friedbanana" + list_reagents = list("sugar" = 5, "nutriment" = 8, "cornoil" = 4) + +/obj/item/reagent_containers/food/snacks/ricepudding + name = "Rice Pudding" + desc = "Where's the Jam!" + icon_state = "rpudding" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + list_reagents = list("nutriment" = 7, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/spacylibertyduff + name = "Spacy Liberty Duff" + desc = "Jello gelatin, from Alfred Hubbard's cookbook." + icon_state = "spacylibertyduff" + trash = /obj/item/trash/snack_bowl + filling_color = "#42B873" + bitesize = 3 + list_reagents = list("nutriment" = 6, "psilocybin" = 6) + +/obj/item/reagent_containers/food/snacks/amanitajelly + name = "Amanita Jelly" + desc = "Looks curiously toxic." + icon_state = "amanitajelly" + trash = /obj/item/trash/snack_bowl + filling_color = "#ED0758" + bitesize = 3 + list_reagents = list("nutriment" = 6, "amanitin" = 6, "psilocybin" = 3) + +/obj/item/reagent_containers/food/snacks/candiedapple + name = "Candied Apple" + desc = "An apple coated in sugary sweetness." + icon_state = "candiedapple" + filling_color = "#F21873" + bitesize = 3 + list_reagents = list("nutriment" = 3, "sugar" = 2) + +/obj/item/reagent_containers/food/snacks/mint + name = "mint" + desc = "it is only wafer thin." + icon_state = "mint" + bitesize = 1 + filling_color = "#F2F2F2" + list_reagents = list("minttoxin" = 1) diff --git a/code/modules/food_and_drinks/food/foods/ethnic.dm b/code/modules/food_and_drinks/food/foods/ethnic.dm new file mode 100644 index 00000000000..ae8fc289798 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/ethnic.dm @@ -0,0 +1,135 @@ + +////////////////////// +// Mexican // +////////////////////// + +/obj/item/reagent_containers/food/snacks/taco + name = "taco" + desc = "Take a bite!" + icon_state = "taco" + bitesize = 3 + list_reagents = list("nutriment" = 7, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/burrito + name = "Burrito" + desc = "Meat, beans, cheese, and rice wrapped up as an easy-to-hold meal." + icon_state = "burrito" + trash = /obj/item/trash/plate + filling_color = "#A36A1F" + list_reagents = list("nutriment" = 4, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/chimichanga + name = "Chimichanga" + desc = "Time to eat a chimi-f***ing-changa." + icon_state = "chimichanga" + trash = /obj/item/trash/plate + filling_color = "#A36A1F" + list_reagents = list("omnizine" = 4, "cheese" = 2) //Deadpool reference. Deal with it. + +/obj/item/reagent_containers/food/snacks/enchiladas + name = "Enchiladas" + desc = "Viva La Mexico!" + icon_state = "enchiladas" + trash = /obj/item/trash/tray + filling_color = "#A36A1F" + bitesize = 4 + list_reagents = list("nutriment" = 8, "capsaicin" = 6) + +/obj/item/reagent_containers/food/snacks/cornchips + name = "corn chips" + desc = "Goes great with salsa! OLE!" + icon_state = "chips" + bitesize = 1 + trash = /obj/item/trash/chips + filling_color = "#E8C31E" + list_reagents = list("nutriment" = 3) + + +////////////////////// +// Chinese // +////////////////////// + +/obj/item/reagent_containers/food/snacks/chinese/chowmein + name = "chow mein" + desc = "What is in this anyways?" + icon_state = "chinese1" + junkiness = 25 + list_reagents = list("nutriment" = 1, "beans" = 3, "msg" = 4, "sugar" = 2) + +/obj/item/reagent_containers/food/snacks/chinese/sweetsourchickenball + name = "Sweet & Sour Chicken Balls" + desc = "Is this chicken cooked? The odds are better than wok paper scissors." + icon_state = "chickenball" + junkiness = 25 + list_reagents = list("nutriment" = 2, "msg" = 4, "sugar" = 2) + +/obj/item/reagent_containers/food/snacks/chinese/tao + name = "Admiral Yamamoto carp" + desc = "Tastes like chicken." + icon_state = "chinese2" + junkiness = 25 + list_reagents = list("nutriment" = 1, "protein" = 1, "msg" = 4, "sugar" = 4) + +/obj/item/reagent_containers/food/snacks/chinese/newdles + name = "chinese newdles" + desc = "Made fresh, weekly!" + icon_state = "chinese3" + junkiness = 25 + list_reagents = list("nutriment" = 1, "msg" = 4, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/chinese/rice + name = "fried rice" + desc = "A timeless classic." + icon_state = "chinese4" + junkiness = 20 + list_reagents = list("nutriment" = 1, "rice" = 3, "msg" = 4, "sugar" = 2) + + +////////////////////// +// Japanese // +////////////////////// + +/obj/item/reagent_containers/food/snacks/chawanmushi + name = "chawanmushi" + desc = "A legendary egg custard that makes friends out of enemies. Probably too hot for a cat to eat." + icon_state = "chawanmushi" + trash = /obj/item/trash/snack_bowl + filling_color = "#F0F2E4" + list_reagents = list("nutriment" = 5) + +/obj/item/reagent_containers/food/snacks/yakiimo + name = "yaki imo" + desc = "Made with roasted sweet potatoes!" + icon_state = "yakiimo" + trash = /obj/item/trash/plate + list_reagents = list("nutriment" = 5, "vitamin" = 4) + filling_color = "#8B1105" + + +////////////////////// +// Middle Eastern // +////////////////////// + +/obj/item/reagent_containers/food/snacks/human/kabob + name = "-kabob" + icon_state = "kabob" + desc = "A human meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#A85340" + list_reagents = list("nutriment" = 8) + +/obj/item/reagent_containers/food/snacks/monkeykabob + name = "Meat-kabob" + icon_state = "kabob" + desc = "Delicious meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#A85340" + list_reagents = list("nutriment" = 8) + +/obj/item/reagent_containers/food/snacks/tofukabob + name = "Tofu-kabob" + icon_state = "kabob" + desc = "Vegan meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#FFFEE0" + list_reagents = list("nutriment" = 8) diff --git a/code/modules/food_and_drinks/food/foods/ingredients.dm b/code/modules/food_and_drinks/food/foods/ingredients.dm new file mode 100644 index 00000000000..65c20eb7eba --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/ingredients.dm @@ -0,0 +1,160 @@ + +////////////////////// +// Tofu & Soy // +////////////////////// + +/obj/item/reagent_containers/food/snacks/tofu + name = "Tofu" + icon_state = "tofu" + desc = "We all love tofu." + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("plantmatter" = 2) + +/obj/item/reagent_containers/food/snacks/fried_tofu + name = "Fried Tofu" + icon_state = "tofu" + desc = "Proof that even vegetarians crave unhealthy foods." + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("plantmatter" = 3) + +/obj/item/reagent_containers/food/snacks/soydope + name = "Soy Dope" + desc = "Dope from a soy." + icon_state = "soydope" + trash = /obj/item/trash/plate + filling_color = "#C4BF76" + list_reagents = list("nutriment" = 2) + + +////////////////////// +// Cheese // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sliceable/cheesewheel + name = "Cheese wheel" + desc = "A big wheel of delicious Cheddar." + icon_state = "cheesewheel" + slice_path = /obj/item/reagent_containers/food/snacks/cheesewedge + slices_num = 5 + filling_color = "#FFF700" + list_reagents = list("nutriment" = 15, "vitamin" = 5, "cheese" = 20) + +/obj/item/reagent_containers/food/snacks/cheesewedge + name = "Cheese wedge" + desc = "A wedge of delicious Cheddar. The cheese wheel it was cut from can't have gone far." + icon_state = "cheesewedge" + filling_color = "#FFF700" + +/obj/item/reagent_containers/food/snacks/weirdcheesewedge + name = "Weird Cheese" + desc = "Some kind of... gooey, messy, gloopy thing. Similar to cheese, but only in the looser sense of the word." + icon_state = "weirdcheesewedge" + filling_color = "#00FF33" + list_reagents = list("mercury" = 5, "lsd" = 5, "ethanol" = 5, "weird_cheese" = 5) + + +////////////////////// +// Plants // +////////////////////// + +/obj/item/reagent_containers/food/snacks/hugemushroomslice + name = "huge mushroom slice" + desc = "A slice from a huge mushroom." + icon_state = "hugemushroomslice" + filling_color = "#E0D7C5" + bitesize = 6 + list_reagents = list("plantmatter" = 3, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/tomatomeat + name = "tomato slice" + desc = "A slice from a huge tomato." + icon_state = "tomatomeat" + filling_color = "#DB0000" + bitesize = 6 + list_reagents = list("protein" = 2) + +/obj/item/reagent_containers/food/snacks/watermelonslice + name = "Watermelon Slice" + desc = "A slice of watery goodness." + icon_state = "watermelonslice" + filling_color = "#FF3867" + +/obj/item/reagent_containers/food/snacks/pineappleslice + name = "Pineapple Slices" + desc = "Rings of pineapple." + icon_state = "pineappleslice" + filling_color = "#e5b437" + + +////////////////////// +// Dough // +////////////////////// + +/obj/item/reagent_containers/food/snacks/dough + name = "dough" + desc = "A piece of dough." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "dough" + list_reagents = list("nutriment" = 6) + +// Dough + rolling pin = flat dough +/obj/item/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/kitchen/rollingpin)) + if(isturf(loc)) + new /obj/item/reagent_containers/food/snacks/sliceable/flatdough(loc) + to_chat(user, "You flatten [src].") + qdel(src) + else + to_chat(user, "You need to put [src] on a surface to roll it out!") + else + ..() + +// slicable into 3xdoughslices +/obj/item/reagent_containers/food/snacks/sliceable/flatdough + name = "flat dough" + desc = "Some flattened dough." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "flat dough" + slice_path = /obj/item/reagent_containers/food/snacks/doughslice + slices_num = 3 + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/doughslice + name = "dough slice" + desc = "The building block of an impressive dish." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "doughslice" + list_reagents = list("nutriment" = 1) + + +////////////////////// +// Chocolate // +////////////////////// + +/obj/item/reagent_containers/food/snacks/chocolatebar + name = "Chocolate Bar" + desc = "Such sweet, fattening food." + icon_state = "chocolatebar" + filling_color = "#7D5F46" + list_reagents = list("nutriment" = 2, "sugar" = 2, "cocoa" = 2) + +/obj/item/reagent_containers/food/snacks/choc_pile //for reagent chocolate being spilled on turfs + name = "Pile of Chocolate" + desc = "A pile of pure chocolate pieces." + icon_state = "cocoa" + filling_color = "#7D5F46" + list_reagents = list("chocolate" = 5) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/ectoplasm + name = "ectoplasm" + desc = "A luminescent blob of what scientists refer to as 'ghost goo'." + icon = 'icons/obj/wizard.dmi' + icon_state = "ectoplasm" + list_reagents = list("ectoplasm" = 10) diff --git a/code/modules/food_and_drinks/food/foods/junkfood.dm b/code/modules/food_and_drinks/food/foods/junkfood.dm new file mode 100644 index 00000000000..b221348e8d8 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/junkfood.dm @@ -0,0 +1,93 @@ + +////////////////////// +// Vendor // +////////////////////// + +/obj/item/reagent_containers/food/snacks/chips + name = "chips" + desc = "Commander Riker's What-The-Crisps." + icon_state = "chips" + bitesize = 1 + trash = /obj/item/trash/chips + filling_color = "#E8C31E" + junkiness = 20 + list_reagents = list("nutriment" = 1, "sodiumchloride" = 1, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/sosjerky + name = "Scaredy's Private Reserve Beef Jerky" + icon_state = "sosjerky" + desc = "Beef jerky made from the finest space cows." + trash = /obj/item/trash/sosjerky + filling_color = "#631212" + junkiness = 25 + list_reagents = list("protein" = 1, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/pistachios + name = "Pistachios" + icon_state = "pistachios" + desc = "A snack of deliciously salted pistachios. A perfectly valid choice..." + trash = /obj/item/trash/pistachios + filling_color = "#BAD145" + junkiness = 20 + list_reagents = list("plantmatter" = 2, "sodiumchloride" = 1, "sugar" = 4) + +/obj/item/reagent_containers/food/snacks/no_raisin + name = "4no Raisins" + icon_state = "4no_raisins" + desc = "Best raisins in the universe. Not sure why." + trash = /obj/item/trash/raisins + filling_color = "#343834" + junkiness = 25 + list_reagents = list("plantmatter" = 2, "sugar" = 4) + +/obj/item/reagent_containers/food/snacks/spacetwinkie + name = "Space Twinkie" + icon_state = "space_twinkie" + desc = "Guaranteed to survive longer then you will." + filling_color = "#FFE591" + junkiness = 25 + list_reagents = list("sugar" = 4) + +/obj/item/reagent_containers/food/snacks/cheesiehonkers + name = "Cheesie Honkers" + icon_state = "cheesie_honkers" + desc = "Bite sized cheesie snacks that will honk all over your mouth." + trash = /obj/item/trash/cheesie + filling_color = "#FFA305" + junkiness = 25 + list_reagents = list("nutriment" = 1, "fake_cheese" = 2, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/syndicake + name = "Syndi-Cakes" + icon_state = "syndi_cakes" + desc = "An extremely moist snack cake that tastes just as good after being nuked." + filling_color = "#FF5D05" + trash = /obj/item/trash/syndi_cakes + bitesize = 3 + list_reagents = list("nutriment" = 4, "salglu_solution" = 5) + +/obj/item/reagent_containers/food/snacks/tastybread + name = "bread tube" + desc = "Bread in a tube. Chewy...and surprisingly tasty." + icon_state = "tastybread" + trash = /obj/item/trash/tastybread + filling_color = "#A66829" + junkiness = 20 + list_reagents = list("nutriment" = 2, "sugar" = 4) + + +////////////////////// +// Homemade // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sosjerky/healthy + name = "homemade beef jerky" + desc = "Homemade beef jerky made from the finest space cows." + list_reagents = list("nutriment" = 3, "vitamin" = 1) + junkiness = 0 + +/obj/item/reagent_containers/food/snacks/no_raisin/healthy + name = "homemade raisins" + desc = "homemade raisins, the best in all of spess." + list_reagents = list("nutriment" = 3, "vitamin" = 2) + junkiness = 0 diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm new file mode 100644 index 00000000000..a7f4acb4405 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/meat.dm @@ -0,0 +1,432 @@ + +////////////////////// +// Raw Meat // +////////////////////// + +/obj/item/reagent_containers/food/snacks/meat + name = "meat" + desc = "A slab of meat" + icon_state = "meat" + health = 180 + filling_color = "#FF1C1C" + bitesize = 3 + list_reagents = list("protein" = 3) + +/obj/item/reagent_containers/food/snacks/meat/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/kitchen/knife) || istype(W, /obj/item/scalpel)) + new /obj/item/reagent_containers/food/snacks/rawcutlet(src) + new /obj/item/reagent_containers/food/snacks/rawcutlet(src) + new /obj/item/reagent_containers/food/snacks/rawcutlet(src) + to_chat(user, "You cut the meat in thin strips.") + qdel(src) + else + ..() + +/obj/item/reagent_containers/food/snacks/meat/syntiflesh + name = "synthetic meat" + desc = "A synthetic slab of flesh." + +/obj/item/reagent_containers/food/snacks/meat/human + name = "-meat" + var/subjectname = "" + var/subjectjob = null + +/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct + name = "meat product" + desc = "A slab of station reclaimed and chemically processed meat product." + +/obj/item/reagent_containers/food/snacks/meat/monkey + //same as plain meat + +/obj/item/reagent_containers/food/snacks/meat/corgi + name = "Corgi meat" + desc = "Tastes like... well you know..." + +/obj/item/reagent_containers/food/snacks/meat/pug + name = "Pug meat" + desc = "Tastes like... well you know..." + +/obj/item/reagent_containers/food/snacks/meat/ham + name = "Ham" + desc = "Taste like bacon." + list_reagents = list("protein" = 3, "porktonium" = 10) + +/obj/item/reagent_containers/food/snacks/meat/meatwheat + name = "meatwheat clump" + desc = "This doesn't look like meat, but your standards aren't that high to begin with." + list_reagents = list("nutriment" = 3, "vitamin" = 2, "blood" = 5) + filling_color = rgb(150, 0, 0) + icon_state = "meatwheat_clump" + bitesize = 4 + +/obj/item/reagent_containers/food/snacks/rawcutlet + name = "raw cutlet" + desc = "A thin piece of raw meat." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "rawcutlet" + bitesize = 1 + list_reagents = list("protein" = 1) + +/obj/item/reagent_containers/food/snacks/rawcutlet/attackby(obj/item/W, mob/user, params) + if(istype(W,/obj/item/kitchen/knife)) + user.visible_message( \ + "[user] cuts the raw cutlet with the knife!", \ + "You cut the raw cutlet with your knife!" \ + ) + new /obj/item/reagent_containers/food/snacks/raw_bacon(loc) + qdel(src) + +/obj/item/reagent_containers/food/snacks/bearmeat + name = "bear meat" + desc = "A very manly slab of meat." + icon_state = "bearmeat" + filling_color = "#DB0000" + bitesize = 3 + list_reagents = list("protein" = 12, "morphine" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/xenomeat + name = "meat" + desc = "A slab of meat." + icon_state = "xenomeat" + filling_color = "#43DE18" + bitesize = 6 + list_reagents = list("protein" = 3, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/spidermeat + name = "spider meat" + desc = "A slab of spider meat." + icon_state = "spidermeat" + bitesize = 3 + list_reagents = list("protein" = 3, "toxin" = 3, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/lizardmeat + name = "mutant lizard meat" + desc = "Seems to be a slab of meat from some mutant lizard thing?" + icon_state = "xenomeat" + filling_color = "#43DE18" + bitesize = 3 + list_reagents = list("protein" = 3, "toxin" = 3) + +/obj/item/reagent_containers/food/snacks/spiderleg + name = "spider leg" + desc = "A still twitching leg of a giant spider... you don't really want to eat this, do you?" + icon_state = "spiderleg" + list_reagents = list("protein" = 2, "toxin" = 2) + +/obj/item/reagent_containers/food/snacks/raw_bacon + name = "raw bacon" + desc = "It's fleshy and pink!" + icon_state = "raw_bacon" + list_reagents = list("nutriment" = 1, "porktonium" = 10) + +/obj/item/reagent_containers/food/snacks/spidereggs + name = "spider eggs" + desc = "A cluster of juicy spider eggs. A great side dish for when you care not for your health." + icon_state = "spidereggs" + list_reagents = list("protein" = 2, "toxin" = 2) + +////////////////////// +// Cooked Meat // +////////////////////// + +/obj/item/reagent_containers/food/snacks/meatsteak + name = "Meat steak" + desc = "A piece of hot spicy meat." + icon_state = "meatstake" + trash = /obj/item/trash/plate + filling_color = "#7A3D11" + bitesize = 3 + list_reagents = list("nutriment" = 5) + +/obj/item/reagent_containers/food/snacks/bacon + name = "bacon" + desc = "It looks juicy and tastes amazing!" + icon_state = "bacon2" + list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4) + +/obj/item/reagent_containers/food/snacks/telebacon + name = "Tele Bacon" + desc = "It tastes a little odd but it is still delicious." + icon_state = "bacon" + var/obj/item/radio/beacon/bacon/baconbeacon + list_reagents = list("nutriment" = 4, "porktonium" = 10) + +/obj/item/reagent_containers/food/snacks/telebacon/New() + ..() + baconbeacon = new /obj/item/radio/beacon/bacon(src) + +/obj/item/reagent_containers/food/snacks/telebacon/On_Consume(mob/M, mob/user) + if(!reagents.total_volume) + baconbeacon.loc = user + baconbeacon.digest_delay() + +/obj/item/reagent_containers/food/snacks/meatball + name = "Meatball" + desc = "A great meal all round." + icon_state = "meatball" + filling_color = "#DB0000" + list_reagents = list("protein" = 4, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/sausage + name = "Sausage" + desc = "A piece of mixed, long meat." + icon_state = "sausage" + filling_color = "#DB0000" + list_reagents = list("protein" = 6, "vitamin" = 1, "porktonium" = 10) + +/obj/item/reagent_containers/food/snacks/cutlet + name = "cutlet" + desc = "A tasty meat slice." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "cutlet" + list_reagents = list("protein" = 2) + +/obj/item/reagent_containers/food/snacks/spidereggsham + name = "green eggs and ham" + desc = "Would you eat them on a train? Would you eat them on a plane? Would you eat them on a state of the art corporate deathtrap floating through space?" + icon_state = "spidereggsham" + trash = /obj/item/trash/plate + bitesize = 4 + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/boiledspiderleg + name = "boiled spider leg" + desc = "A giant spider's leg that's still twitching after being cooked. Gross!" + icon_state = "spiderlegcooked" + trash = /obj/item/trash/plate + bitesize = 3 + list_reagents = list("nutriment" = 3, "capsaicin" = 2) + +/obj/item/reagent_containers/food/snacks/wingfangchu + name = "Wing Fang Chu" + desc = "A savory dish of alien wing wang in soy." + icon_state = "wingfangchu" + trash = /obj/item/trash/snack_bowl + filling_color = "#43DE18" + list_reagents = list("nutriment" = 6, "soysauce" = 5, "vitamin" = 2) + + +////////////////////// +// Cubes // +////////////////////// + +/obj/item/reagent_containers/food/snacks/monkeycube + name = "monkey cube" + desc = "Just add water!" + icon_state = "monkeycube" + bitesize = 12 + filling_color = "#ADAC7F" + var/datum/species/monkey_type = /datum/species/monkey + list_reagents = list("nutriment" = 2) + +/obj/item/reagent_containers/food/snacks/monkeycube/water_act(volume, temperature) + if(volume >= 5) + return Expand() + +/obj/item/reagent_containers/food/snacks/monkeycube/wash(mob/user, atom/source) + user.drop_item() + forceMove(get_turf(source)) + return 1 + +/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand() + if(!QDELETED(src)) + visible_message("[src] expands!") + if(fingerprintslast) + log_game("Cube ([monkey_type]) inflated, last touched by: " + fingerprintslast) + else + log_game("Cube ([monkey_type]) inflated, last touched by: NO_DATA") + var/mob/living/carbon/human/creature = new /mob/living/carbon/human(get_turf(src)) + if(LAZYLEN(fingerprintshidden)) + creature.fingerprintshidden = fingerprintshidden.Copy() + creature.set_species(monkey_type) + qdel(src) + +/obj/item/reagent_containers/food/snacks/monkeycube/farwacube + name = "farwa cube" + monkey_type = /datum/species/monkey/tajaran + +/obj/item/reagent_containers/food/snacks/monkeycube/wolpincube + name = "wolpin cube" + monkey_type = /datum/species/monkey/vulpkanin + +/obj/item/reagent_containers/food/snacks/monkeycube/stokcube + name = "stok cube" + monkey_type = /datum/species/monkey/unathi + +/obj/item/reagent_containers/food/snacks/monkeycube/neaeracube + name = "neaera cube" + monkey_type = /datum/species/monkey/skrell + + +////////////////////// +// Eggs // +////////////////////// + +/obj/item/reagent_containers/food/snacks/egg + name = "egg" + desc = "An egg!" + icon_state = "egg" + filling_color = "#FDFFD1" + list_reagents = list("protein" = 1, "egg" = 5) + +/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) + ..() + var/turf/T = get_turf(hit_atom) + new/obj/effect/decal/cleanable/egg_smudge(T) + if(reagents) + reagents.reaction(hit_atom, TOUCH) + qdel(src) + +/obj/item/reagent_containers/food/snacks/egg/attackby(obj/item/W, mob/user, params) + if(istype( W, /obj/item/toy/crayon )) + var/obj/item/toy/crayon/C = W + var/clr = C.colourName + + if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) + to_chat(usr, "The egg refuses to take on this color!") + return + + to_chat(usr, "You color \the [src] [clr]") + icon_state = "egg-[clr]" + item_color = clr + else + ..() + +/obj/item/reagent_containers/food/snacks/egg/blue + icon_state = "egg-blue" + item_color = "blue" + +/obj/item/reagent_containers/food/snacks/egg/green + icon_state = "egg-green" + item_color = "green" + +/obj/item/reagent_containers/food/snacks/egg/mime + icon_state = "egg-mime" + item_color = "mime" + +/obj/item/reagent_containers/food/snacks/egg/orange + icon_state = "egg-orange" + item_color = "orange" + +/obj/item/reagent_containers/food/snacks/egg/purple + icon_state = "egg-purple" + item_color = "purple" + +/obj/item/reagent_containers/food/snacks/egg/rainbow + icon_state = "egg-rainbow" + item_color = "rainbow" + +/obj/item/reagent_containers/food/snacks/egg/red + icon_state = "egg-red" + item_color = "red" + +/obj/item/reagent_containers/food/snacks/egg/yellow + icon_state = "egg-yellow" + item_color = "yellow" + +/obj/item/reagent_containers/food/snacks/egg/gland + desc = "An egg! It looks weird..." + +/obj/item/reagent_containers/food/snacks/egg/gland/New() + ..() + reagents.add_reagent(get_random_reagent_id(), 15) + + var/reagent_color = mix_color_from_reagents(reagents.reagent_list) + color = reagent_color + +/obj/item/reagent_containers/food/snacks/friedegg + name = "Fried egg" + desc = "A fried egg, with a touch of salt and pepper." + icon_state = "friedegg" + filling_color = "#FFDF78" + bitesize = 1 + list_reagents = list("nutriment" = 3, "egg" = 5) + +/obj/item/reagent_containers/food/snacks/boiledegg + name = "Boiled egg" + desc = "A hard boiled egg." + icon_state = "egg" + filling_color = "#FFFFFF" + list_reagents = list("nutriment" = 2, "egg" = 5, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/chocolateegg + name = "Chocolate Egg" + desc = "Such sweet, fattening food." + icon_state = "chocolateegg" + filling_color = "#7D5F46" + list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2) + +/obj/item/reagent_containers/food/snacks/omelette + name = "Omelette Du Fromage" + desc = "That's all you can say!" + icon_state = "omelette" + trash = /obj/item/trash/plate + filling_color = "#FFF9A8" + list_reagents = list("nutriment" = 8, "vitamin" = 1) + bitesize = 1 + +/obj/item/reagent_containers/food/snacks/benedict + name = "eggs benedict" + desc = "There is only one egg on this, how rude." + icon_state = "benedict" + bitesize = 3 + list_reagents = list("nutriment" = 6, "egg" = 3, "vitamin" = 4) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/hotdog + name = "hotdog" + desc = "Fresh footlong ready to go down on." + icon_state = "hotdog" + bitesize = 3 + list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3) + +/obj/item/reagent_containers/food/snacks/meatbun + name = "meat bun" + desc = "Has the potential to not be dog." + icon_state = "meatbun" + bitesize = 6 + list_reagents = list("nutriment" = 6, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/sliceable/turkey + name = "Turkey" + desc = "A traditional turkey served with stuffing." + icon_state = "turkey" + slice_path = /obj/item/reagent_containers/food/snacks/turkeyslice + slices_num = 6 + list_reagents = list("protein" = 24, "nutriment" = 18, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/turkeyslice + name = "turkey serving" + desc = "A serving of some tender and delicious turkey." + icon_state = "turkeyslice" + trash = /obj/item/trash/plate + filling_color = "#B97A57" + +/obj/item/reagent_containers/food/snacks/organ + name = "organ" + desc = "It's good for you." + icon = 'icons/obj/surgery.dmi' + icon_state = "appendix" + filling_color = "#E00D34" + bitesize = 3 + list_reagents = list("protein" = 4, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/appendix +//yes, this is the same as meat. I might do something different in future + name = "appendix" + desc = "An appendix which looks perfectly healthy." + icon = 'icons/obj/surgery.dmi' + icon_state = "appendix" + filling_color = "#E00D34" + bitesize = 3 + list_reagents = list("protein" = 3, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/appendix/inflamed + name = "inflamed appendix" + desc = "An appendix which appears to be inflamed." + icon_state = "appendixinflamed" + filling_color = "#E00D7A" diff --git a/code/modules/food_and_drinks/food/foods/misc.dm b/code/modules/food_and_drinks/food/foods/misc.dm new file mode 100644 index 00000000000..4c6c607eacb --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/misc.dm @@ -0,0 +1,171 @@ + +////////////////////// +// Meals // +////////////////////// + +/obj/item/reagent_containers/food/snacks/eggplantparm + name = "Eggplant Parmigiana" + desc = "The only good recipe for eggplant." + icon_state = "eggplantparm" + trash = /obj/item/trash/plate + filling_color = "#4D2F5E" + list_reagents = list("nutriment" = 6, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/soylentgreen + name = "Soylent Green" + desc = "Not made of people. Honest." //Totally people. + icon_state = "soylent_green" + trash = /obj/item/trash/waffles + filling_color = "#B8E6B5" + list_reagents = list("nutriment" = 10, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/soylentviridians + name = "Soylent Virdians" + desc = "Not made of people. Honest." //Actually honest for once. + icon_state = "soylent_yellow" + trash = /obj/item/trash/waffles + filling_color = "#E6FA61" + list_reagents = list("nutriment" = 10, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/monkeysdelight + name = "monkey's Delight" + desc = "Eeee Eee!" + icon_state = "monkeysdelight" + trash = /obj/item/trash/tray + filling_color = "#5C3C11" + bitesize = 6 + list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/dionaroast + name = "roast diona" + desc = "It's like an enormous, leathery carrot. With an eye." + icon_state = "dionaroast" + trash = /obj/item/trash/plate + filling_color = "#75754B" + list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/tofurkey + name = "Tofurkey" + desc = "A fake turkey made from tofu." + icon_state = "tofurkey" + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("nutriment" = 12, "ether" = 3) + + +////////////////////// +// Salads // +////////////////////// + +/obj/item/reagent_containers/food/snacks/aesirsalad + name = "Aesir salad" + desc = "Probably too incredible for mortal men to fully enjoy." + icon_state = "aesirsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#468C00" + bitesize = 3 + list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6) + +/obj/item/reagent_containers/food/snacks/herbsalad + name = "herb salad" + desc = "A tasty salad with apples on top." + icon_state = "herbsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#76B87F" + bitesize = 3 + list_reagents = list("nutriment" = 8, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/validsalad + name = "valid salad" + desc = "It's just an herb salad with meatballs and fried potato slices. Nothing suspicious about it." + icon_state = "validsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#76B87F" + bitesize = 3 + list_reagents = list("nutriment" = 8, "salglu_solution" = 5, "vitamin" = 2) + + +////////////////////// +// Donk Pockets // +////////////////////// + +/obj/item/reagent_containers/food/snacks/donkpocket + name = "Donk-pocket" + desc = "The food of choice for the seasoned traitor." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + list_reagents = list("nutriment" = 4) + +/obj/item/reagent_containers/food/snacks/warmdonkpocket + name = "Warm Donk-pocket" + desc = "The food of choice for the seasoned traitor." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + list_reagents = list("nutriment" = 4) + +/obj/item/reagent_containers/food/snacks/warmdonkpocket/Post_Consume(mob/living/M) + M.reagents.add_reagent("omnizine", 15) + +/obj/item/reagent_containers/food/snacks/warmdonkpocket_weak + name = "Lightly Warm Donk-pocket" + desc = "The food of choice for the seasoned traitor. This one is lukewarm." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + list_reagents = list("nutriment" = 4, "weak_omnizine" = 3) + +/obj/item/reagent_containers/food/snacks/syndidonkpocket + name = "Donk-pocket" + desc = "This donk-pocket is emitting a small amount of heat." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + bitesize = 100 //nom the whole thing at once. + list_reagents = list("nutriment" = 1) + +/obj/item/reagent_containers/food/snacks/syndidonkpocket/Post_Consume(mob/living/M) + M.reagents.add_reagent("omnizine", 15) + M.reagents.add_reagent("teporone", 15) + M.reagents.add_reagent("synaptizine", 15) + M.reagents.add_reagent("salglu_solution", 15) + M.reagents.add_reagent("salbutamol", 15) + M.reagents.add_reagent("methamphetamine", 15) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/boiledslimecore + name = "Boiled Slime Core" + desc = "A boiled red thing." + icon_state = "boiledrorocore" + bitesize = 3 + list_reagents = list("slimejelly" = 5) + +/obj/item/reagent_containers/food/snacks/popcorn + name = "Popcorn" + desc = "Now let's find some cinema." + icon_state = "popcorn" + trash = /obj/item/trash/popcorn + var/unpopped = 0 + filling_color = "#FFFAD4" + bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 + list_reagents = list("nutriment" = 2) + +/obj/item/reagent_containers/food/snacks/popcorn/New() + ..() + unpopped = rand(1,10) + +/obj/item/reagent_containers/food/snacks/popcorn/On_Consume(mob/M, mob/user) + if(prob(unpopped)) //lol ...what's the point? + to_chat(user, "You bite down on an un-popped kernel!") + unpopped = max(0, unpopped-1) + ..() + +/obj/item/reagent_containers/food/snacks/liquidfood + name = "\improper LiquidFood Ration" + desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?" + icon_state = "liquidfood" + trash = /obj/item/trash/liquidfood + filling_color = "#A8A8A8" + bitesize = 4 + list_reagents = list("nutriment" = 20, "iron" = 3, "vitamin" = 2) diff --git a/code/modules/food_and_drinks/food/foods/pasta.dm b/code/modules/food_and_drinks/food/foods/pasta.dm new file mode 100644 index 00000000000..1b9c253ab53 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/pasta.dm @@ -0,0 +1,70 @@ + +////////////////////// +// Raw Pasta // +////////////////////// + +/obj/item/reagent_containers/food/snacks/spaghetti + name = "Spaghetti" + desc = "A bundle of raw spaghetti." + icon = 'icons/obj/food/pasta.dmi' + icon_state = "spaghetti" + filling_color = "#EDDD00" + list_reagents = list("nutriment" = 1, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/macaroni + name = "Macaroni twists" + desc = "These are little twists of raw macaroni." + icon = 'icons/obj/food/pasta.dmi' + icon_state = "macaroni" + filling_color = "#EDDD00" + list_reagents = list("nutriment" = 1, "vitamin" = 1) + + +////////////////////// +// Pasta Dishes // +////////////////////// + +/obj/item/reagent_containers/food/snacks/boiledspaghetti + name = "Boiled Spaghetti" + desc = "A plain dish of noodles, this sucks." + icon = 'icons/obj/food/pasta.dmi' + icon_state = "spaghettiboiled" + trash = /obj/item/trash/plate + filling_color = "#FCEE81" + list_reagents = list("nutriment" = 2, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/pastatomato + name = "spaghetti" + desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!" + icon = 'icons/obj/food/pasta.dmi' + icon_state = "pastatomato" + trash = /obj/item/trash/plate + filling_color = "#DE4545" + bitesize = 4 + list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/meatballspaghetti + name = "spaghetti & Meatballs" + desc = "Now thats a nic'e meatball!" + icon = 'icons/obj/food/pasta.dmi' + icon_state = "meatballspaghetti" + trash = /obj/item/trash/plate + filling_color = "#DE4545" + list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/spesslaw + name = "Spesslaw" + desc = "A lawyer's favourite." + icon = 'icons/obj/food/pasta.dmi' + icon_state = "spesslaw" + filling_color = "#DE4545" + list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6) + +/obj/item/reagent_containers/food/snacks/macncheese + name = "Macaroni cheese" + desc = "One of the most comforting foods in the world. Apparently." + trash = /obj/item/trash/snack_bowl + icon = 'icons/obj/food/pasta.dmi' + icon_state = "macncheese" + filling_color = "#ffe45d" + list_reagents = list("nutriment" = 5, "vitamin" = 2, "cheese" = 4) diff --git a/code/modules/food_and_drinks/food/foods/pizza.dm b/code/modules/food_and_drinks/food/foods/pizza.dm new file mode 100644 index 00000000000..c34d8943da7 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/pizza.dm @@ -0,0 +1,254 @@ + +////////////////////// +// Pizzas // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sliceable/pizza + icon = 'icons/obj/food/pizza.dmi' + slices_num = 6 + filling_color = "#BAA14C" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita + name = "Margherita" + desc = "The golden standard of pizzas." + icon_state = "pizzamargherita" + slice_path = /obj/item/reagent_containers/food/snacks/margheritaslice + list_reagents = list("nutriment" = 30, "tomatojuice" = 6, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/margheritaslice + name = "Margherita slice" + desc = "A slice of the classic pizza." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "pizzamargheritaslice" + filling_color = "#BAA14C" + list_reagents = list("nutriment" = 5) + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza + name = "Meatpizza" + desc = "A pizza with meat topping." + icon_state = "meatpizza" + slice_path = /obj/item/reagent_containers/food/snacks/meatpizzaslice + list_reagents = list("protein" = 30, "tomatojuice" = 6, "vitamin" = 8) + +/obj/item/reagent_containers/food/snacks/meatpizzaslice + name = "Meatpizza slice" + desc = "A slice of a meaty pizza." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "meatpizzaslice" + filling_color = "#BAA14C" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza + name = "Mushroompizza" + desc = "Very special pizza." + icon_state = "mushroompizza" + slice_path = /obj/item/reagent_containers/food/snacks/mushroompizzaslice + list_reagents = list("plantmatter" = 30, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/mushroompizzaslice + name = "Mushroompizza slice" + desc = "Maybe it is the last slice of pizza in your life." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "mushroompizzaslice" + filling_color = "#BAA14C" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza + name = "Vegetable pizza" + desc = "No one of Tomato Sapiens were harmed during making this pizza." + icon_state = "vegetablepizza" + slice_path = /obj/item/reagent_containers/food/snacks/vegetablepizzaslice + list_reagents = list("plantmatter" = 25, "tomatojuice" = 6, "oculine" = 12, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/vegetablepizzaslice + name = "Vegetable pizza slice" + desc = "A slice of the most green pizza of all pizzas not containing green ingredients." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "vegetablepizzaslice" + filling_color = "#BAA14C" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza + name = "Hawaiian Pizza" + desc = "Love it or hate it, this pizza divides opinions. Complete with juicy pineapple." + icon_state = "hawaiianpizza" //NEEDED + slice_path = /obj/item/reagent_containers/food/snacks/hawaiianpizzaslice + list_reagents = list("protein" = 15, "tomatojuice" = 6, "plantmatter" = 20, "pineapplejuice" = 6, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/hawaiianpizzaslice + name = "Hawaiian pizza slice" + desc = "A slice of polarising pizza." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "hawaiianpizzaslice" + filling_color = "#e5b437" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/macpizza + name = "Macaroni cheese pizza" + desc = "Gastronomists have yet to classify this dish as 'pizza'." + icon_state = "macpizza" + slice_path = /obj/item/reagent_containers/food/snacks/macpizzaslice + list_reagents = list("nutriment" = 40, "vitamin" = 5) //More nutriment because carbs, but it's not any more vitaminicious + filling_color = "#ffe45d" + +/obj/item/reagent_containers/food/snacks/macpizzaslice + name = "Macaroni cheese pizza slice" + desc = "A delicious slice of pizza topped with macaroni cheese... wait, what the hell? Who would do this?!" + icon = 'icons/obj/food/pizza.dmi' + icon_state = "macpizzaslice" + filling_color = "#ffe45d" + + +////////////////////// +// Boxes // +////////////////////// + +/obj/item/pizzabox + name = "pizza box" + desc = "A box suited for pizzas." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "pizzabox1" + + var/open = 0 // Is the box open? + var/ismessy = 0 // Fancy mess on the lid + var/obj/item/reagent_containers/food/snacks/sliceable/pizza/pizza // Content pizza + var/list/boxes = list() // If the boxes are stacked, they come here + var/boxtag = "" + +/obj/item/pizzabox/update_icon() + overlays = list() + + // Set appropriate description + if(open && pizza) + desc = "A box suited for pizzas. It appears to have a [pizza.name] inside." + else if(boxes.len > 0) + desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile." + var/obj/item/pizzabox/topbox = boxes[boxes.len] + var/toptag = topbox.boxtag + if(toptag != "") + desc = "[desc] The box on top has a tag, it reads: '[toptag]'." + else + desc = "A box suited for pizzas." + if(boxtag != "") + desc = "[desc] The box has a tag, it reads: '[boxtag]'." + + // Icon states and overlays + if(open) + if(ismessy) + icon_state = "pizzabox_messy" + else + icon_state = "pizzabox_open" + if(pizza) + var/image/pizzaimg = image("food/pizza.dmi", icon_state = pizza.icon_state) + pizzaimg.pixel_y = -3 + overlays += pizzaimg + + return + else + // Stupid code because byondcode sucks + var/doimgtag = 0 + if(boxes.len > 0) + var/obj/item/pizzabox/topbox = boxes[boxes.len] + if(topbox.boxtag != "") + doimgtag = 1 + else + if(boxtag != "") + doimgtag = 1 + if(doimgtag) + var/image/tagimg = image("food/pizza.dmi", icon_state = "pizzabox_tag") + tagimg.pixel_y = boxes.len * 3 + overlays += tagimg + icon_state = "pizzabox[boxes.len+1]" + +/obj/item/pizzabox/attack_hand(mob/user) + if(open && pizza) + user.put_in_hands(pizza) + to_chat(user, "You take the [pizza] out of the [src].") + pizza = null + update_icon() + return + + if(boxes.len > 0) + if(user.is_in_inactive_hand(src)) + ..() + return + var/obj/item/pizzabox/box = boxes[boxes.len] + boxes -= box + user.put_in_hands(box) + to_chat(user, "You remove the topmost [src] from your hand.") + box.update_icon() + update_icon() + return + ..() + +/obj/item/pizzabox/attack_self(mob/user) + if(boxes.len > 0) + return + open = !open + if(open && pizza) + ismessy = 1 + update_icon() + +/obj/item/pizzabox/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/pizzabox/)) + var/obj/item/pizzabox/box = I + if(!box.open && !open) + // Make a list of all boxes to be added + var/list/boxestoadd = list() + boxestoadd += box + for(var/obj/item/pizzabox/i in box.boxes) + boxestoadd += i + if((boxes.len+1) + boxestoadd.len <= 5) + user.drop_item() + box.loc = src + box.boxes = list() // Clear the box boxes so we don't have boxes inside boxes. - Xzibit + boxes.Add(boxestoadd) + box.update_icon() + update_icon() + to_chat(user, "You put the [box] ontop of the [src]!") + else + to_chat(user, "The stack is too high!") + else + to_chat(user, "Close the [box] first!") + return + + if(istype(I, /obj/item/reagent_containers/food/snacks/sliceable/pizza/)) // Long ass fucking object name + if(open) + user.drop_item() + I.loc = src + pizza = I + + update_icon() + + to_chat(user, "You put the [I] in the [src]!") + else + to_chat(user, "You try to push the [I] through the lid but it doesn't work!") + return + + if(istype(I, /obj/item/pen/)) + if(open) + return + var/t = input("Enter what you want to add to the tag:", "Write", null, null) as text + var/obj/item/pizzabox/boxtotagto = src + if(boxes.len > 0) + boxtotagto = boxes[boxes.len] + boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30) + update_icon() + return + ..() + +/obj/item/pizzabox/margherita/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita(src) + boxtag = "Margherita Deluxe" + +/obj/item/pizzabox/vegetable/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza(src) + boxtag = "Gourmet Vegatable" + +/obj/item/pizzabox/mushroom/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza(src) + boxtag = "Mushroom Special" + +/obj/item/pizzabox/meat/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza(src) + boxtag = "Meatlover's Supreme" + +/obj/item/pizzabox/hawaiian/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza(src) + boxtag = "Hawaiian Feast" \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/foods/sandwiches.dm b/code/modules/food_and_drinks/food/foods/sandwiches.dm new file mode 100644 index 00000000000..a55a92ae3d1 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/sandwiches.dm @@ -0,0 +1,196 @@ + +////////////////////// +// Burgers // +////////////////////// + +/obj/item/reagent_containers/food/snacks/brainburger + name = "brainburger" + desc = "A strange looking burger. It looks almost sentient." + icon_state = "brainburger" + filling_color = "#F2B6EA" + bitesize = 3 + list_reagents = list("nutriment" = 6, "prions" = 10, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/ghostburger + name = "Ghost Burger" + desc = "Spooky! It doesn't look very filling." + icon_state = "ghostburger" + filling_color = "#FFF2FF" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/human + var/hname = "" + var/job = null + filling_color = "#D63C3C" + +/obj/item/reagent_containers/food/snacks/human/burger + name = "-burger" + desc = "A bloody burger." + icon_state = "hburger" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/cheeseburger + name = "cheeseburger" + desc = "The cheese adds a good flavor." + icon_state = "cheeseburger" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/monkeyburger + name = "burger" + desc = "The cornerstone of every nutritious breakfast." + icon_state = "hburger" + filling_color = "#D63C3C" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/tofuburger + name = "Tofu Burger" + desc = "What.. is that meat?" + icon_state = "tofuburger" + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/roburger + name = "roburger" + desc = "The lettuce is the only organic component. Beep." + icon_state = "roburger" + filling_color = "#CCCCCC" + bitesize = 3 + list_reagents = list("nutriment" = 6, "nanomachines" = 10, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/roburgerbig + name = "roburger" + desc = "This massive patty looks like poison. Beep." + icon_state = "roburger" + filling_color = "#CCCCCC" + volume = 120 + bitesize = 3 + list_reagents = list("nutriment" = 6, "nanomachines" = 70, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/xenoburger + name = "xenoburger" + desc = "Smells caustic. Tastes like heresy." + icon_state = "xburger" + filling_color = "#43DE18" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/clownburger + name = "Clown Burger" + desc = "This tastes funny..." + icon_state = "clownburger" + filling_color = "#FF00FF" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/mimeburger + name = "Mime Burger" + desc = "Its taste defies language." + icon_state = "mimeburger" + filling_color = "#FFFFFF" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/baseballburger + name = "home run baseball burger" + desc = "It's still warm. The steam coming off of it looks like baseball." + icon_state = "baseball" + filling_color = "#CD853F" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/spellburger + name = "Spell Burger" + desc = "This is absolutely Ei Nath." + icon_state = "spellburger" + filling_color = "#D505FF" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/bigbiteburger + name = "Big Bite Burger" + desc = "Forget the Big Mac. THIS is the future!" + icon_state = "bigbiteburger" + filling_color = "#E3D681" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/superbiteburger + name = "Super Bite Burger" + desc = "This is a mountain of a burger. FOOD!" + icon_state = "superbiteburger" + filling_color = "#CCA26A" + bitesize = 7 + list_reagents = list("nutriment" = 40, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/jellyburger + name = "Jelly Burger" + desc = "Culinary delight..?" + icon_state = "jellyburger" + filling_color = "#B572AB" + bitesize = 3 + +/obj/item/reagent_containers/food/snacks/jellyburger/slime + list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/jellyburger/cherry + list_reagents = list("nutriment" = 6, "cherryjelly" = 5, "vitamin" = 1) + + +////////////////////// +// Sandwiches // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sandwich + name = "Sandwich" + desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce! Arthur Dent would be proud." + icon_state = "sandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/toastedsandwich + name = "Toasted Sandwich" + desc = "Now if you only had a pepper bar." + icon_state = "toastedsandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + list_reagents = list("nutriment" = 6, "carbon" = 2) + +/obj/item/reagent_containers/food/snacks/grilledcheese + name = "Grilled Cheese Sandwich" + desc = "Goes great with Tomato soup!" + icon_state = "toastedsandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value? + +/obj/item/reagent_containers/food/snacks/jellysandwich + name = "Jelly Sandwich" + desc = "You wish you had some peanut butter to go with this..." + icon_state = "jellysandwich" + trash = /obj/item/trash/plate + filling_color = "#9E3A78" + bitesize = 3 + +/obj/item/reagent_containers/food/snacks/jellysandwich/slime + list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/jellysandwich/cherry + list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/notasandwich + name = "not-a-sandwich" + desc = "Something seems to be wrong with this, you can't quite figure what. Maybe it's his moustache." + icon_state = "notasandwich" + list_reagents = list("nutriment" = 6, "vitamin" = 6) + +/obj/item/reagent_containers/food/snacks/wrap + name = "egg wrap" + desc = "The precursor to Pigs in a Blanket." + icon_state = "wrap" + list_reagents = list("nutriment" = 5) diff --git a/code/modules/food_and_drinks/food/seafood.dm b/code/modules/food_and_drinks/food/foods/seafood.dm similarity index 100% rename from code/modules/food_and_drinks/food/seafood.dm rename to code/modules/food_and_drinks/food/foods/seafood.dm diff --git a/code/modules/food_and_drinks/food/foods/side_dishes.dm b/code/modules/food_and_drinks/food/foods/side_dishes.dm new file mode 100644 index 00000000000..7b563519ca3 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/side_dishes.dm @@ -0,0 +1,105 @@ + +////////////////////// +// Raw // +////////////////////// + +/obj/item/reagent_containers/food/snacks/rawsticks + name = "raw potato sticks" + desc = "Raw fries, not very tasty." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "rawsticks" + list_reagents = list("plantmatter" = 3) + + +////////////////////// +// Fried // +////////////////////// + +/obj/item/reagent_containers/food/snacks/fries + name = "Space fries" + desc = "AKA: French Fries, Freedom Fries, etc." + icon_state = "fries" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + list_reagents = list("nutriment" = 4) + +/obj/item/reagent_containers/food/snacks/cheesyfries + name = "cheesy fries" + desc = "Fries. Covered in cheese. Duh." + icon_state = "cheesyfries" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/tatortot + name = "tator tot" + desc = "A large fried potato nugget that may or may not try to valid you." + icon_state = "tatortot" + list_reagents = list("nutriment" = 4) + filling_color = "FFD700" + +/obj/item/reagent_containers/food/snacks/onionrings + name = "onion rings" + desc = "Onion slices coated in batter." + icon_state = "onionrings" + list_reagents = list("nutriment" = 3) + filling_color = "#C0C9A0" + gender = PLURAL + +/obj/item/reagent_containers/food/snacks/carrotfries + name = "carrot fries" + desc = "Tasty fries from fresh carrots." + icon_state = "carrotfries" + trash = /obj/item/trash/plate + filling_color = "#FAA005" + list_reagents = list("plantmatter" = 3, "oculine" = 3, "vitamin" = 2) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/beans + name = "tin of beans" + desc = "Musical fruit in a slightly less musical container." + icon_state = "beans" + list_reagents = list("nutriment" = 10, "beans" = 10, "vitamin" = 3) + +/obj/item/reagent_containers/food/snacks/mashed_potatoes //mashed taters + name = "mashed potatoes" + desc = "Some soft, creamy, and irresistible mashed potatoes." + icon_state = "mashedtaters" + trash = /obj/item/trash/plate + filling_color = "#D6D9C1" + list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/stuffing + name = "Stuffing" + desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" + icon_state = "stuffing" + filling_color = "#C9AC83" + list_reagents = list("nutriment" = 3) + +/obj/item/reagent_containers/food/snacks/loadedbakedpotato + name = "loaded baked potato" + desc = "Totally baked." + icon_state = "loadedbakedpotato" + filling_color = "#9C7A68" + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/boiledrice + name = "Boiled Rice" + desc = "A boring dish of boring rice." + icon_state = "boiledrice" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + list_reagents = list("nutriment" = 5, "vitamin" = 1) + + +/obj/item/reagent_containers/food/snacks/roastparsnip + name = "roast parsnip" + desc = "Sweet and crunchy." + icon_state = "roastparsnip" + trash = /obj/item/trash/plate + list_reagents = list("nutriment" = 3, "vitamin" = 4) + filling_color = "#FF5500" diff --git a/code/modules/food_and_drinks/food/foods/soups.dm b/code/modules/food_and_drinks/food/foods/soups.dm new file mode 100644 index 00000000000..76e4d752a41 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/soups.dm @@ -0,0 +1,166 @@ + +////////////////////// +// Soups // +////////////////////// + +/obj/item/reagent_containers/food/snacks/meatballsoup + name = "Meatball soup" + desc = "You've got balls kid, BALLS!" + icon_state = "meatballsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#785210" + bitesize = 5 + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/slimesoup + name = "slime soup" + desc = "If no water is available, you may substitute tears." + icon_state = "slimesoup" + filling_color = "#C4DBA0" + bitesize = 5 + list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/bloodsoup + name = "Tomato soup" + desc = "Smells like copper." + icon_state = "tomatosoup" + filling_color = "#FF0000" + bitesize = 5 + list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/clownstears + name = "Clown's Tears" + desc = "Not very funny." + icon_state = "clownstears" + filling_color = "#C4FBFF" + bitesize = 5 + list_reagents = list("nutriment" = 4, "banana" = 5, "water" = 5, "vitamin" = 8) + +/obj/item/reagent_containers/food/snacks/vegetablesoup + name = "Vegetable soup" + desc = "A true vegan meal." //TODO + icon_state = "vegetablesoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#AFC4B5" + bitesize = 5 + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/nettlesoup + name = "Nettle soup" + desc = "To think, the botanist would've beat you to death with one of these." + icon_state = "nettlesoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#AFC4B5" + bitesize = 5 + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/mysterysoup + name = "mystery soup" + desc = "The mystery is, why aren't you eating it?" + icon_state = "mysterysoup" + var/extra_reagent = null + bitesize = 5 + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/mysterysoup/New() + ..() + extra_reagent = pick("capsaicin", "frostoil", "omnizine", "banana", "blood", "slimejelly", "toxin", "banana", "carbon", "oculine") + reagents.add_reagent("[extra_reagent]", 5) + +/obj/item/reagent_containers/food/snacks/wishsoup + name = "Wish Soup" + desc = "I wish this was soup." + icon_state = "wishsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#D1F4FF" + bitesize = 5 + list_reagents = list("water" = 10) + +/obj/item/reagent_containers/food/snacks/wishsoup/New() + ..() + if(prob(25)) + desc = "A wish come true!" // hue + reagents.add_reagent("nutriment", 9) + reagents.add_reagent("vitamin", 1) + +/obj/item/reagent_containers/food/snacks/tomatosoup + name = "Tomato Soup" + desc = "Drinking this feels like being a vampire! A tomato vampire..." + icon_state = "tomatosoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#D92929" + bitesize = 5 + list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3) + +/obj/item/reagent_containers/food/snacks/milosoup + name = "Milosoup" + desc = "The universe's best soup! Yum!!!" + icon_state = "milosoup" + trash = /obj/item/trash/snack_bowl + bitesize = 5 + list_reagents = list("nutriment" = 7, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/mushroomsoup + name = "chantrelle soup" + desc = "A delicious and hearty mushroom soup." + icon_state = "mushroomsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#E386BF" + bitesize = 5 + list_reagents = list("nutriment" = 8, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/beetsoup + name = "beet soup" + desc = "Wait, how do you spell it again..?" + icon_state = "beetsoup" + trash = /obj/item/trash/snack_bowl + bitesize = 5 + filling_color = "#FAC9FF" + list_reagents = list("nutriment" = 7, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/beetsoup/New() + ..() + name = pick("borsch","bortsch","borstch","borsh","borshch","borscht") + + +////////////////////// +// Stews // +////////////////////// + +/obj/item/reagent_containers/food/snacks/stew + name = "Stew" + desc = "A nice and warm stew. Healthy and strong." + icon_state = "stew" + filling_color = "#9E673A" + bitesize = 7 + list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/stewedsoymeat + name = "Stewed Soy Meat" + desc = "Even non-vegetarians will LOVE this!" + icon_state = "stewedsoymeat" + trash = /obj/item/trash/plate + list_reagents = list("nutriment" = 8) + + +////////////////////// +// Chili // +////////////////////// + +/obj/item/reagent_containers/food/snacks/hotchili + name = "Hot Chili" + desc = "A five alarm Texan Chili!" + icon_state = "hotchili" + trash = /obj/item/trash/snack_bowl + filling_color = "#FF3C00" + bitesize = 5 + list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/coldchili + name = "Cold Chili" + desc = "This slush is barely a liquid!" + icon_state = "coldchili" + filling_color = "#2B00FF" + trash = /obj/item/trash/snack_bowl + bitesize = 5 + list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2) diff --git a/code/modules/food_and_drinks/food/meat.dm b/code/modules/food_and_drinks/food/meat.dm deleted file mode 100644 index 7940050b35a..00000000000 --- a/code/modules/food_and_drinks/food/meat.dm +++ /dev/null @@ -1,55 +0,0 @@ -/obj/item/reagent_containers/food/snacks/meat - name = "meat" - desc = "A slab of meat" - icon_state = "meat" - health = 180 - filling_color = "#FF1C1C" - bitesize = 3 - list_reagents = list("protein" = 3) - -/obj/item/reagent_containers/food/snacks/meat/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/kitchen/knife) || istype(W, /obj/item/scalpel)) - new /obj/item/reagent_containers/food/snacks/rawcutlet(src) - new /obj/item/reagent_containers/food/snacks/rawcutlet(src) - new /obj/item/reagent_containers/food/snacks/rawcutlet(src) - to_chat(user, "You cut the meat in thin strips.") - qdel(src) - else - ..() - -/obj/item/reagent_containers/food/snacks/meat/syntiflesh - name = "synthetic meat" - desc = "A synthetic slab of flesh." - -/obj/item/reagent_containers/food/snacks/meat/human - name = "-meat" - var/subjectname = "" - var/subjectjob = null - -/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct - name = "meat product" - desc = "A slab of station reclaimed and chemically processed meat product." - -/obj/item/reagent_containers/food/snacks/meat/monkey - //same as plain meat - -/obj/item/reagent_containers/food/snacks/meat/corgi - name = "Corgi meat" - desc = "Tastes like... well you know..." - -/obj/item/reagent_containers/food/snacks/meat/pug - name = "Pug meat" - desc = "Tastes like... well you know..." - -/obj/item/reagent_containers/food/snacks/meat/ham - name = "Ham" - desc = "Taste like bacon." - list_reagents = list("protein" = 3, "porktonium" = 10) - -/obj/item/reagent_containers/food/snacks/meat/meatwheat - name = "meatwheat clump" - desc = "This doesn't look like meat, but your standards aren't that high to begin with." - list_reagents = list("nutriment" = 3, "vitamin" = 2, "blood" = 5) - filling_color = rgb(150, 0, 0) - icon_state = "meatwheat_clump" - bitesize = 4 \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 5dc010bfae9..4803405520a 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -271,791 +271,6 @@ // bitesize = 3 //This is the amount each bite consumes. - - -/obj/item/reagent_containers/food/snacks/aesirsalad - name = "Aesir salad" - desc = "Probably too incredible for mortal men to fully enjoy." - icon_state = "aesirsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#468C00" - bitesize = 3 - list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6) - -/obj/item/reagent_containers/food/snacks/chips - name = "chips" - desc = "Commander Riker's What-The-Crisps." - icon_state = "chips" - bitesize = 1 - trash = /obj/item/trash/chips - filling_color = "#E8C31E" - junkiness = 20 - list_reagents = list("nutriment" = 1, "sodiumchloride" = 1, "sugar" = 3) - -/obj/item/reagent_containers/food/snacks/cornchips - name = "corn chips" - desc = "Goes great with salsa! OLE!" - icon_state = "chips" - bitesize = 1 - trash = /obj/item/trash/chips - filling_color = "#E8C31E" - list_reagents = list("nutriment" = 3) - -/obj/item/reagent_containers/food/snacks/cookie - name = "cookie" - desc = "COOKIE!!!" - icon_state = "COOKIE!!!" - bitesize = 1 - filling_color = "#DBC94F" - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/chocolatebar - name = "Chocolate Bar" - desc = "Such sweet, fattening food." - icon_state = "chocolatebar" - filling_color = "#7D5F46" - list_reagents = list("nutriment" = 2, "sugar" = 2, "cocoa" = 2) - -/obj/item/reagent_containers/food/snacks/choc_pile //for reagent chocolate being spilled on turfs - name = "Pile of Chocolate" - desc = "A pile of pure chocolate pieces." - icon_state = "cocoa" - filling_color = "#7D5F46" - list_reagents = list("chocolate" = 5) - -/obj/item/reagent_containers/food/snacks/chocolateegg - name = "Chocolate Egg" - desc = "Such sweet, fattening food." - icon_state = "chocolateegg" - filling_color = "#7D5F46" - list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2) - -/obj/item/reagent_containers/food/snacks/donut - name = "donut" - desc = "Goes great with Robust Coffee." - icon_state = "donut1" - bitesize = 5 - list_reagents = list("nutriment" = 3, "sugar" = 2) - var/extra_reagent = null - filling_color = "#D2691E" - var/randomized_sprinkles = 1 - -/obj/item/reagent_containers/food/snacks/donut/New() - ..() - if(randomized_sprinkles && prob(30)) - icon_state = "donut2" - name = "frosted donut" - reagents.add_reagent("sprinkles", 2) - filling_color = "#FF69B4" - -/obj/item/reagent_containers/food/snacks/donut/sprinkles - name = "frosted donut" - icon_state = "donut2" - list_reagents = list("nutriment" = 3, "sugar" = 2, "spinkles" = 2) - filling_color = "#FF69B4" - randomized_sprinkles = 0 - -/obj/item/reagent_containers/food/snacks/donut/chaos - name = "chaos donut" - desc = "Like life, it never quite tastes the same." - bitesize = 10 - -/obj/item/reagent_containers/food/snacks/donut/chaos/New() - ..() - extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine") - reagents.add_reagent("[extra_reagent]", 3) - if(prob(30)) - icon_state = "donut2" - name = "frosted chaos donut" - reagents.add_reagent("sprinkles", 2) - filling_color = "#FF69B4" - -/obj/item/reagent_containers/food/snacks/donut/jelly - name = "jelly donut" - desc = "You jelly?" - icon_state = "jdonut1" - extra_reagent = "berryjuice" - -/obj/item/reagent_containers/food/snacks/donut/jelly/New() - ..() - if(extra_reagent) - reagents.add_reagent("[extra_reagent]", 3) - if(prob(30)) - icon_state = "jdonut2" - name = "frosted jelly Donut" - reagents.add_reagent("sprinkles", 2) - filling_color = "#FF69B4" - -/obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly - name = "jelly donut" - desc = "You jelly?" - icon_state = "jdonut1" - extra_reagent = "slimejelly" - -/obj/item/reagent_containers/food/snacks/donut/jelly/cherryjelly - name = "jelly donut" - desc = "You jelly?" - icon_state = "jdonut1" - extra_reagent = "cherryjelly" - -/obj/item/reagent_containers/food/snacks/egg - name = "egg" - desc = "An egg!" - icon_state = "egg" - filling_color = "#FDFFD1" - list_reagents = list("protein" = 1, "egg" = 5) - -/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) - ..() - var/turf/T = get_turf(hit_atom) - new/obj/effect/decal/cleanable/egg_smudge(T) - if(reagents) - reagents.reaction(hit_atom, TOUCH) - qdel(src) - -/obj/item/reagent_containers/food/snacks/egg/attackby(obj/item/W, mob/user, params) - if(istype( W, /obj/item/toy/crayon )) - var/obj/item/toy/crayon/C = W - var/clr = C.colourName - - if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) - to_chat(usr, "The egg refuses to take on this color!") - return - - to_chat(usr, "You color \the [src] [clr]") - icon_state = "egg-[clr]" - item_color = clr - else - ..() - -/obj/item/reagent_containers/food/snacks/egg/blue - icon_state = "egg-blue" - item_color = "blue" - -/obj/item/reagent_containers/food/snacks/egg/green - icon_state = "egg-green" - item_color = "green" - -/obj/item/reagent_containers/food/snacks/egg/mime - icon_state = "egg-mime" - item_color = "mime" - -/obj/item/reagent_containers/food/snacks/egg/orange - icon_state = "egg-orange" - item_color = "orange" - -/obj/item/reagent_containers/food/snacks/egg/purple - icon_state = "egg-purple" - item_color = "purple" - -/obj/item/reagent_containers/food/snacks/egg/rainbow - icon_state = "egg-rainbow" - item_color = "rainbow" - -/obj/item/reagent_containers/food/snacks/egg/red - icon_state = "egg-red" - item_color = "red" - -/obj/item/reagent_containers/food/snacks/egg/yellow - icon_state = "egg-yellow" - item_color = "yellow" - -/obj/item/reagent_containers/food/snacks/friedegg - name = "Fried egg" - desc = "A fried egg, with a touch of salt and pepper." - icon_state = "friedegg" - filling_color = "#FFDF78" - bitesize = 1 - list_reagents = list("nutriment" = 3, "egg" = 5) - -/obj/item/reagent_containers/food/snacks/boiledegg - name = "Boiled egg" - desc = "A hard boiled egg." - icon_state = "egg" - filling_color = "#FFFFFF" - list_reagents = list("nutriment" = 2, "egg" = 5, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/organ - - name = "organ" - desc = "It's good for you." - icon = 'icons/obj/surgery.dmi' - icon_state = "appendix" - filling_color = "#E00D34" - bitesize = 3 - list_reagents = list("protein" = 4, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/appendix -//yes, this is the same as meat. I might do something different in future - name = "appendix" - desc = "An appendix which looks perfectly healthy." - icon = 'icons/obj/surgery.dmi' - icon_state = "appendix" - filling_color = "#E00D34" - bitesize = 3 - list_reagents = list("protein" = 3, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/appendix/inflamed - name = "inflamed appendix" - desc = "An appendix which appears to be inflamed." - icon_state = "appendixinflamed" - filling_color = "#E00D7A" - -/obj/item/reagent_containers/food/snacks/tofu - name = "Tofu" - icon_state = "tofu" - desc = "We all love tofu." - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("plantmatter" = 2) - -/obj/item/reagent_containers/food/snacks/fried_tofu - name = "Fried Tofu" - icon_state = "tofu" - desc = "Proof that even vegetarians crave unhealthy foods." - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("plantmatter" = 3) - -/obj/item/reagent_containers/food/snacks/tofurkey - name = "Tofurkey" - desc = "A fake turkey made from tofu." - icon_state = "tofurkey" - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("nutriment" = 12, "ether" = 3) - -/obj/item/reagent_containers/food/snacks/stuffing - name = "Stuffing" - desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" - icon_state = "stuffing" - filling_color = "#C9AC83" - list_reagents = list("nutriment" = 3) - -/obj/item/reagent_containers/food/snacks/hugemushroomslice - name = "huge mushroom slice" - desc = "A slice from a huge mushroom." - icon_state = "hugemushroomslice" - filling_color = "#E0D7C5" - bitesize = 6 - list_reagents = list("plantmatter" = 3, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/tomatomeat - name = "tomato slice" - desc = "A slice from a huge tomato." - icon_state = "tomatomeat" - filling_color = "#DB0000" - bitesize = 6 - list_reagents = list("protein" = 2) - -/obj/item/reagent_containers/food/snacks/bearmeat - name = "bear meat" - desc = "A very manly slab of meat." - icon_state = "bearmeat" - filling_color = "#DB0000" - bitesize = 3 - list_reagents = list("protein" = 12, "morphine" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/xenomeat - name = "meat" - desc = "A slab of meat." - icon_state = "xenomeat" - filling_color = "#43DE18" - bitesize = 6 - list_reagents = list("protein" = 3, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/spidermeat - name = "spider meat" - desc = "A slab of spider meat." - icon_state = "spidermeat" - bitesize = 3 - list_reagents = list("protein" = 3, "toxin" = 3, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/lizardmeat - name = "mutant lizard meat" - desc = "Seems to be a slab of meat from some mutant lizard thing?" - icon_state = "xenomeat" - filling_color = "#43DE18" - bitesize = 3 - list_reagents = list("protein" = 3, "toxin" = 3) - -/obj/item/reagent_containers/food/snacks/spiderleg - name = "spider leg" - desc = "A still twitching leg of a giant spider... you don't really want to eat this, do you?" - icon_state = "spiderleg" - list_reagents = list("protein" = 2, "toxin" = 2) - -/obj/item/reagent_containers/food/snacks/meatball - name = "Meatball" - desc = "A great meal all round." - icon_state = "meatball" - filling_color = "#DB0000" - list_reagents = list("protein" = 4, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/sausage - name = "Sausage" - desc = "A piece of mixed, long meat." - icon_state = "sausage" - filling_color = "#DB0000" - list_reagents = list("protein" = 6, "vitamin" = 1, "porktonium" = 10) - -/obj/item/reagent_containers/food/snacks/donkpocket - name = "Donk-pocket" - desc = "The food of choice for the seasoned traitor." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - list_reagents = list("nutriment" = 4) - -/obj/item/reagent_containers/food/snacks/warmdonkpocket - name = "Warm Donk-pocket" - desc = "The food of choice for the seasoned traitor." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - list_reagents = list("nutriment" = 4) - -/obj/item/reagent_containers/food/snacks/warmdonkpocket/Post_Consume(mob/living/M) - M.reagents.add_reagent("omnizine", 15) - -/obj/item/reagent_containers/food/snacks/warmdonkpocket_weak - name = "Lightly Warm Donk-pocket" - desc = "The food of choice for the seasoned traitor. This one is lukewarm." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - list_reagents = list("nutriment" = 4, "weak_omnizine" = 3) - -/obj/item/reagent_containers/food/snacks/syndidonkpocket - name = "Donk-pocket" - desc = "This donk-pocket is emitting a small amount of heat." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - bitesize = 100 //nom the whole thing at once. - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/syndidonkpocket/Post_Consume(mob/living/M) - M.reagents.add_reagent("omnizine", 15) - M.reagents.add_reagent("teporone", 15) - M.reagents.add_reagent("synaptizine", 15) - M.reagents.add_reagent("salglu_solution", 15) - M.reagents.add_reagent("salbutamol", 15) - M.reagents.add_reagent("methamphetamine", 15) - -/obj/item/reagent_containers/food/snacks/brainburger - name = "brainburger" - desc = "A strange looking burger. It looks almost sentient." - icon_state = "brainburger" - filling_color = "#F2B6EA" - bitesize = 3 - list_reagents = list("nutriment" = 6, "prions" = 10, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/ghostburger - name = "Ghost Burger" - desc = "Spooky! It doesn't look very filling." - icon_state = "ghostburger" - filling_color = "#FFF2FF" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/human - var/hname = "" - var/job = null - filling_color = "#D63C3C" - -/obj/item/reagent_containers/food/snacks/human/burger - name = "-burger" - desc = "A bloody burger." - icon_state = "hburger" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/cheeseburger - name = "cheeseburger" - desc = "The cheese adds a good flavor." - icon_state = "cheeseburger" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/monkeyburger - name = "burger" - desc = "The cornerstone of every nutritious breakfast." - icon_state = "hburger" - filling_color = "#D63C3C" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/tofuburger - name = "Tofu Burger" - desc = "What.. is that meat?" - icon_state = "tofuburger" - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/roburger - name = "roburger" - desc = "The lettuce is the only organic component. Beep." - icon_state = "roburger" - filling_color = "#CCCCCC" - bitesize = 3 - list_reagents = list("nutriment" = 6, "nanomachines" = 10, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/roburgerbig - name = "roburger" - desc = "This massive patty looks like poison. Beep." - icon_state = "roburger" - filling_color = "#CCCCCC" - volume = 120 - bitesize = 3 - list_reagents = list("nutriment" = 6, "nanomachines" = 70, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/xenoburger - name = "xenoburger" - desc = "Smells caustic. Tastes like heresy." - icon_state = "xburger" - filling_color = "#43DE18" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/clownburger - name = "Clown Burger" - desc = "This tastes funny..." - icon_state = "clownburger" - filling_color = "#FF00FF" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/mimeburger - name = "Mime Burger" - desc = "Its taste defies language." - icon_state = "mimeburger" - filling_color = "#FFFFFF" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/baseballburger - name = "home run baseball burger" - desc = "It's still warm. The steam coming off of it looks like baseball." - icon_state = "baseball" - filling_color = "#CD853F" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/omelette - name = "Omelette Du Fromage" - desc = "That's all you can say!" - icon_state = "omelette" - trash = /obj/item/trash/plate - filling_color = "#FFF9A8" - list_reagents = list("nutriment" = 8, "vitamin" = 1) - bitesize = 1 - -/obj/item/reagent_containers/food/snacks/muffin - name = "Muffin" - desc = "A delicious and spongy little cake." - icon_state = "muffin" - filling_color = "#E0CF9B" - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/pie - name = "Banana Cream Pie" - desc = "Just like back home, on clown planet! HONK!" - icon_state = "pie" - trash = /obj/item/trash/plate - filling_color = "#FBFFB8" - bitesize = 3 - list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) - ..() - new/obj/effect/decal/cleanable/pie_smudge(loc) - visible_message("[src] splats.","You hear a splat.") - qdel(src) - -/obj/item/reagent_containers/food/snacks/berryclafoutis - name = "Berry Clafoutis" - desc = "No black birds, this is a good sign." - icon_state = "berryclafoutis" - trash = /obj/item/trash/plate - bitesize = 3 - list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/waffles - name = "waffles" - desc = "Mmm, waffles." - icon_state = "waffles" - trash = /obj/item/trash/waffles - filling_color = "#E6DEB5" - list_reagents = list("nutriment" = 8, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/eggplantparm - name = "Eggplant Parmigiana" - desc = "The only good recipe for eggplant." - icon_state = "eggplantparm" - trash = /obj/item/trash/plate - filling_color = "#4D2F5E" - list_reagents = list("nutriment" = 6, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/soylentgreen - name = "Soylent Green" - desc = "Not made of people. Honest." //Totally people. - icon_state = "soylent_green" - trash = /obj/item/trash/waffles - filling_color = "#B8E6B5" - list_reagents = list("nutriment" = 10, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/soylentviridians - name = "Soylent Virdians" - desc = "Not made of people. Honest." //Actually honest for once. - icon_state = "soylent_yellow" - trash = /obj/item/trash/waffles - filling_color = "#E6FA61" - list_reagents = list("nutriment" = 10, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/meatpie - name = "Meat-pie" - icon_state = "meatpie" - desc = "An old barber recipe, very delicious!" - trash = /obj/item/trash/plate - filling_color = "#948051" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/tofupie - name = "Tofu-pie" - icon_state = "meatpie" - desc = "A delicious tofu pie." - trash = /obj/item/trash/plate - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/amanita_pie - name = "amanita pie" - desc = "Sweet and tasty poison pie." - icon_state = "amanita_pie" - filling_color = "#FFCCCC" - bitesize = 4 - list_reagents = list("nutriment" = 6, "amanitin" = 3, "psilocybin" = 1, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/plump_pie - name = "plump pie" - desc = "I bet you love stuff made out of plump helmets!" - icon_state = "plump_pie" - filling_color = "#B8279B" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/plump_pie/New() - ..() - if(prob(10)) - name = "exceptional plump pie" - desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" // What - reagents.add_reagent("omnizine", 5) - -/obj/item/reagent_containers/food/snacks/xemeatpie - name = "Xeno-pie" - icon_state = "xenomeatpie" - desc = "A delicious meatpie. Probably heretical." - trash = /obj/item/trash/plate - filling_color = "#43DE18" - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/wingfangchu - name = "Wing Fang Chu" - desc = "A savory dish of alien wing wang in soy." - icon_state = "wingfangchu" - trash = /obj/item/trash/snack_bowl - filling_color = "#43DE18" - list_reagents = list("nutriment" = 6, "soysauce" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/human/kabob - name = "-kabob" - icon_state = "kabob" - desc = "A human meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#A85340" - list_reagents = list("nutriment" = 8) - -/obj/item/reagent_containers/food/snacks/monkeykabob - name = "Meat-kabob" - icon_state = "kabob" - desc = "Delicious meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#A85340" - list_reagents = list("nutriment" = 8) - -/obj/item/reagent_containers/food/snacks/tofukabob - name = "Tofu-kabob" - icon_state = "kabob" - desc = "Vegan meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#FFFEE0" - list_reagents = list("nutriment" = 8) - -/obj/item/reagent_containers/food/snacks/popcorn - name = "Popcorn" - desc = "Now let's find some cinema." - icon_state = "popcorn" - trash = /obj/item/trash/popcorn - var/unpopped = 0 - filling_color = "#FFFAD4" - bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 - list_reagents = list("nutriment" = 2) - -/obj/item/reagent_containers/food/snacks/popcorn/New() - ..() - unpopped = rand(1,10) - -/obj/item/reagent_containers/food/snacks/popcorn/On_Consume(mob/M, mob/user) - if(prob(unpopped)) //lol ...what's the point? - to_chat(user, "You bite down on an un-popped kernel!") - unpopped = max(0, unpopped-1) - ..() - -/obj/item/reagent_containers/food/snacks/sosjerky - name = "Scaredy's Private Reserve Beef Jerky" - icon_state = "sosjerky" - desc = "Beef jerky made from the finest space cows." - trash = /obj/item/trash/sosjerky - filling_color = "#631212" - junkiness = 25 - list_reagents = list("protein" = 1, "sugar" = 3) - -/obj/item/reagent_containers/food/snacks/sosjerky/healthy - name = "homemade beef jerky" - desc = "Homemade beef jerky made from the finest space cows." - list_reagents = list("nutriment" = 3, "vitamin" = 1) - junkiness = 0 - -/obj/item/reagent_containers/food/snacks/pistachios - name = "Pistachios" - icon_state = "pistachios" - desc = "A snack of deliciously salted pistachios. A perfectly valid choice..." - trash = /obj/item/trash/pistachios - filling_color = "#BAD145" - junkiness = 20 - list_reagents = list("plantmatter" = 2, "sodiumchloride" = 1, "sugar" = 4) - -/obj/item/reagent_containers/food/snacks/no_raisin - name = "4no Raisins" - icon_state = "4no_raisins" - desc = "Best raisins in the universe. Not sure why." - trash = /obj/item/trash/raisins - filling_color = "#343834" - junkiness = 25 - list_reagents = list("plantmatter" = 2, "sugar" = 4) - -/obj/item/reagent_containers/food/snacks/no_raisin/healthy - name = "homemade raisins" - desc = "homemade raisins, the best in all of spess." - list_reagents = list("nutriment" = 3, "vitamin" = 2) - junkiness = 0 - -/obj/item/reagent_containers/food/snacks/spacetwinkie - name = "Space Twinkie" - icon_state = "space_twinkie" - desc = "Guaranteed to survive longer then you will." - filling_color = "#FFE591" - junkiness = 25 - list_reagents = list("sugar" = 4) - -/obj/item/reagent_containers/food/snacks/cheesiehonkers - name = "Cheesie Honkers" - icon_state = "cheesie_honkers" - desc = "Bite sized cheesie snacks that will honk all over your mouth." - trash = /obj/item/trash/cheesie - filling_color = "#FFA305" - junkiness = 25 - list_reagents = list("nutriment" = 1, "fake_cheese" = 2, "sugar" = 3) - -/obj/item/reagent_containers/food/snacks/chinese/chowmein - name = "chow mein" - desc = "What is in this anyways?" - icon_state = "chinese1" - junkiness = 25 - list_reagents = list("nutriment" = 1, "beans" = 3, "msg" = 4, "sugar" = 2) - -/obj/item/reagent_containers/food/snacks/chinese/sweetsourchickenball - name = "Sweet & Sour Chicken Balls" - desc = "Is this chicken cooked? The odds are better than wok paper scissors." - icon_state = "chickenball" - junkiness = 25 - list_reagents = list("nutriment" = 2, "msg" = 4, "sugar" = 2) - -/obj/item/reagent_containers/food/snacks/chinese/tao - name = "Admiral Yamamoto carp" - desc = "Tastes like chicken." - icon_state = "chinese2" - junkiness = 25 - list_reagents = list("nutriment" = 1, "protein" = 1, "msg" = 4, "sugar" = 4) - -/obj/item/reagent_containers/food/snacks/chinese/newdles - name = "chinese newdles" - desc = "Made fresh, weekly!" - icon_state = "chinese3" - junkiness = 25 - list_reagents = list("nutriment" = 1, "msg" = 4, "sugar" = 3) - -/obj/item/reagent_containers/food/snacks/chinese/rice - name = "fried rice" - desc = "A timeless classic." - icon_state = "chinese4" - junkiness = 20 - list_reagents = list("nutriment" = 1, "rice" = 3, "msg" = 4, "sugar" = 2) - -/obj/item/reagent_containers/food/snacks/syndicake - name = "Syndi-Cakes" - icon_state = "syndi_cakes" - desc = "An extremely moist snack cake that tastes just as good after being nuked." - filling_color = "#FF5D05" - trash = /obj/item/trash/syndi_cakes - bitesize = 3 - list_reagents = list("nutriment" = 4, "salglu_solution" = 5) - -/obj/item/reagent_containers/food/snacks/loadedbakedpotato - name = "Loaded Baked Potato" - desc = "Totally baked." - icon_state = "loadedbakedpotato" - filling_color = "#9C7A68" - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/fries - name = "Space Fries" - desc = "AKA: French Fries, Freedom Fries, etc." - icon_state = "fries" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - list_reagents = list("nutriment" = 4) - -/obj/item/reagent_containers/food/snacks/soydope - name = "Soy Dope" - desc = "Dope from a soy." - icon_state = "soydope" - trash = /obj/item/trash/plate - filling_color = "#C4BF76" - list_reagents = list("nutriment" = 2) - -/obj/item/reagent_containers/food/snacks/spaghetti - name = "Spaghetti" - desc = "A bundle of raw spaghetti." - icon_state = "spaghetti" - filling_color = "#EDDD00" - list_reagents = list("nutriment" = 1, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/cheesyfries - name = "Cheesy Fries" - desc = "Fries. Covered in cheese. Duh." - icon_state = "cheesyfries" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/fortunecookie - name = "Fortune cookie" - desc = "A true prophecy in each cookie!" - icon_state = "fortune_cookie" - filling_color = "#E8E79E" - list_reagents = list("nutriment" = 3) - /obj/item/reagent_containers/food/snacks/badrecipe name = "Burned mess" desc = "Someone should be demoted from chef for this." @@ -1069,1333 +284,7 @@ cooktype["grilled"] = 1 cooktype["deep fried"] = 1 -/obj/item/reagent_containers/food/snacks/meatsteak - name = "Meat steak" - desc = "A piece of hot spicy meat." - icon_state = "meatstake" - trash = /obj/item/trash/plate - filling_color = "#7A3D11" - bitesize = 3 - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/spacylibertyduff - name = "Spacy Liberty Duff" - desc = "Jello gelatin, from Alfred Hubbard's cookbook." - icon_state = "spacylibertyduff" - trash = /obj/item/trash/snack_bowl - filling_color = "#42B873" - bitesize = 3 - list_reagents = list("nutriment" = 6, "psilocybin" = 6) - -/obj/item/reagent_containers/food/snacks/amanitajelly - name = "Amanita Jelly" - desc = "Looks curiously toxic." - icon_state = "amanitajelly" - trash = /obj/item/trash/snack_bowl - filling_color = "#ED0758" - bitesize = 3 - list_reagents = list("nutriment" = 6, "amanitin" = 6, "psilocybin" = 3) - -/obj/item/reagent_containers/food/snacks/poppypretzel - name = "Poppy pretzel" - desc = "It's all twisted up!" - icon_state = "poppypretzel" - filling_color = "#916E36" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/meatballsoup - name = "Meatball soup" - desc = "You've got balls kid, BALLS!" - icon_state = "meatballsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#785210" - bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/slimesoup - name = "slime soup" - desc = "If no water is available, you may substitute tears." - icon_state = "slimesoup" - filling_color = "#C4DBA0" - bitesize = 5 - list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/bloodsoup - name = "Tomato soup" - desc = "Smells like copper." - icon_state = "tomatosoup" - filling_color = "#FF0000" - bitesize = 5 - list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/clownstears - name = "Clown's Tears" - desc = "Not very funny." - icon_state = "clownstears" - filling_color = "#C4FBFF" - bitesize = 5 - list_reagents = list("nutriment" = 4, "banana" = 5, "water" = 5, "vitamin" = 8) - -/obj/item/reagent_containers/food/snacks/vegetablesoup - name = "Vegetable soup" - desc = "A true vegan meal." //TODO - icon_state = "vegetablesoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#AFC4B5" - bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/nettlesoup - name = "Nettle soup" - desc = "To think, the botanist would've beat you to death with one of these." - icon_state = "nettlesoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#AFC4B5" - bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/mysterysoup - name = "mystery soup" - desc = "The mystery is, why aren't you eating it?" - icon_state = "mysterysoup" - var/extra_reagent = null - bitesize = 5 - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/mysterysoup/New() - ..() - extra_reagent = pick("capsaicin", "frostoil", "omnizine", "banana", "blood", "slimejelly", "toxin", "banana", "carbon", "oculine") - reagents.add_reagent("[extra_reagent]", 5) - -/obj/item/reagent_containers/food/snacks/wishsoup - name = "Wish Soup" - desc = "I wish this was soup." - icon_state = "wishsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#D1F4FF" - bitesize = 5 - list_reagents = list("water" = 10) - -/obj/item/reagent_containers/food/snacks/wishsoup/New() - ..() - if(prob(25)) - desc = "A wish come true!" // hue - reagents.add_reagent("nutriment", 9) - reagents.add_reagent("vitamin", 1) - -/obj/item/reagent_containers/food/snacks/hotchili - name = "Hot Chili" - desc = "A five alarm Texan Chili!" - icon_state = "hotchili" - trash = /obj/item/trash/snack_bowl - filling_color = "#FF3C00" - bitesize = 5 - list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/coldchili - name = "Cold Chili" - desc = "This slush is barely a liquid!" - icon_state = "coldchili" - filling_color = "#2B00FF" - trash = /obj/item/trash/snack_bowl - bitesize = 5 - list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/raw_bacon - name = "raw bacon" - desc = "It's fleshy and pink!" - icon_state = "raw_bacon" - list_reagents = list("nutriment" = 1, "porktonium" = 10) - -/obj/item/reagent_containers/food/snacks/bacon - name = "bacon" - desc = "It looks juicy and tastes amazing!" - icon_state = "bacon2" - list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4) - -/obj/item/reagent_containers/food/snacks/telebacon - name = "Tele Bacon" - desc = "It tastes a little odd but it is still delicious." - icon_state = "bacon" - var/obj/item/radio/beacon/bacon/baconbeacon - list_reagents = list("nutriment" = 4, "porktonium" = 10) - -/obj/item/reagent_containers/food/snacks/telebacon/New() - ..() - baconbeacon = new /obj/item/radio/beacon/bacon(src) - -/obj/item/reagent_containers/food/snacks/telebacon/On_Consume(mob/M, mob/user) - if(!reagents.total_volume) - baconbeacon.loc = user - baconbeacon.digest_delay() - - -/obj/item/reagent_containers/food/snacks/monkeycube - name = "monkey cube" - desc = "Just add water!" - icon_state = "monkeycube" - bitesize = 12 - filling_color = "#ADAC7F" - var/monkey_type = "Monkey" - list_reagents = list("nutriment" = 2) - -/obj/item/reagent_containers/food/snacks/monkeycube/water_act(volume, temperature) - if(volume >= 5) - return Expand() - -/obj/item/reagent_containers/food/snacks/monkeycube/wash(mob/user, atom/source) - user.drop_item() - forceMove(get_turf(source)) - return 1 - -/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand() - if(!QDELETED(src)) - visible_message("[src] expands!") - if(fingerprintslast) - log_game("Cube ([monkey_type]) inflated, last touched by: " + fingerprintslast) - else - log_game("Cube ([monkey_type]) inflated, last touched by: NO_DATA") - var/mob/living/carbon/human/creature = new /mob/living/carbon/human(get_turf(src)) - if(LAZYLEN(fingerprintshidden)) - creature.fingerprintshidden = fingerprintshidden.Copy() - creature.set_species(monkey_type) - qdel(src) - -/obj/item/reagent_containers/food/snacks/monkeycube/farwacube - name = "farwa cube" - monkey_type = "Farwa" - -/obj/item/reagent_containers/food/snacks/monkeycube/wolpincube - name = "wolpin cube" - monkey_type = "Wolpin" - -/obj/item/reagent_containers/food/snacks/monkeycube/stokcube - name = "stok cube" - monkey_type = "Stok" - -/obj/item/reagent_containers/food/snacks/monkeycube/neaeracube - name = "neaera cube" - monkey_type = "Neara" - - -/obj/item/reagent_containers/food/snacks/spellburger - name = "Spell Burger" - desc = "This is absolutely Ei Nath." - icon_state = "spellburger" - filling_color = "#D505FF" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/bigbiteburger - name = "Big Bite Burger" - desc = "Forget the Big Mac. THIS is the future!" - icon_state = "bigbiteburger" - filling_color = "#E3D681" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/enchiladas - name = "Enchiladas" - desc = "Viva La Mexico!" - icon_state = "enchiladas" - trash = /obj/item/trash/tray - filling_color = "#A36A1F" - bitesize = 4 - list_reagents = list("nutriment" = 8, "capsaicin" = 6) - -/obj/item/reagent_containers/food/snacks/burrito - name = "Burrito" - desc = "Meat, beans, cheese, and rice wrapped up as an easy-to-hold meal." - icon_state = "burrito" - trash = /obj/item/trash/plate - filling_color = "#A36A1F" - list_reagents = list("nutriment" = 4, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/chimichanga - name = "Chimichanga" - desc = "Time to eat a chimi-f***ing-changa." - icon_state = "chimichanga" - trash = /obj/item/trash/plate - filling_color = "#A36A1F" - list_reagents = list("omnizine" = 4, "cheese" = 2) //Deadpool reference. Deal with it. - -/obj/item/reagent_containers/food/snacks/monkeysdelight - name = "monkey's Delight" - desc = "Eeee Eee!" - icon_state = "monkeysdelight" - trash = /obj/item/trash/tray - filling_color = "#5C3C11" - bitesize = 6 - list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/baguette - name = "Baguette" - desc = "Bon appetit!" - icon_state = "baguette" - filling_color = "#E3D796" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/sandwich - name = "Sandwich" - desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce! Arthur Dent would be proud." - icon_state = "sandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/toastedsandwich - name = "Toasted Sandwich" - desc = "Now if you only had a pepper bar." - icon_state = "toastedsandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - list_reagents = list("nutriment" = 6, "carbon" = 2) - -/obj/item/reagent_containers/food/snacks/grilledcheese - name = "Grilled Cheese Sandwich" - desc = "Goes great with Tomato soup!" - icon_state = "toastedsandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value? - -/obj/item/reagent_containers/food/snacks/tomatosoup - name = "Tomato Soup" - desc = "Drinking this feels like being a vampire! A tomato vampire..." - icon_state = "tomatosoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#D92929" - bitesize = 5 - list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3) - -/obj/item/reagent_containers/food/snacks/rofflewaffles - name = "Roffle Waffles" - desc = "Waffles from Roffle. Co." - icon_state = "rofflewaffles" - trash = /obj/item/trash/waffles - filling_color = "#FF00F7" - bitesize = 4 - list_reagents = list("nutriment" = 8, "psilocybin" = 2, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/stew - name = "Stew" - desc = "A nice and warm stew. Healthy and strong." - icon_state = "stew" - filling_color = "#9E673A" - bitesize = 7 - list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/jelliedtoast - name = "Jellied Toast" - desc = "A slice of bread covered with delicious jam." - icon_state = "jellytoast" - trash = /obj/item/trash/plate - filling_color = "#B572AB" - bitesize = 3 - -/obj/item/reagent_containers/food/snacks/jelliedtoast/cherry - list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/jelliedtoast/slime - list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/jellyburger - name = "Jelly Burger" - desc = "Culinary delight..?" - icon_state = "jellyburger" - filling_color = "#B572AB" - bitesize = 3 - -/obj/item/reagent_containers/food/snacks/jellyburger/slime - list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/jellyburger/cherry - list_reagents = list("nutriment" = 6, "cherryjelly" = 5, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/milosoup - name = "Milosoup" - desc = "The universe's best soup! Yum!!!" - icon_state = "milosoup" - trash = /obj/item/trash/snack_bowl - bitesize = 5 - list_reagents = list("nutriment" = 7, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/stewedsoymeat - name = "Stewed Soy Meat" - desc = "Even non-vegetarians will LOVE this!" - icon_state = "stewedsoymeat" - trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 8) - -/obj/item/reagent_containers/food/snacks/boiledspaghetti - name = "Boiled Spaghetti" - desc = "A plain dish of noodles, this sucks." - icon_state = "spaghettiboiled" - trash = /obj/item/trash/plate - filling_color = "#FCEE81" - list_reagents = list("nutriment" = 2, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/boiledrice - name = "Boiled Rice" - desc = "A boring dish of boring rice." - icon_state = "boiledrice" - trash = /obj/item/trash/snack_bowl - filling_color = "#FFFBDB" - list_reagents = list("nutriment" = 5, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/ricepudding - name = "Rice Pudding" - desc = "Where's the Jam!" - icon_state = "rpudding" - trash = /obj/item/trash/snack_bowl - filling_color = "#FFFBDB" - list_reagents = list("nutriment" = 7, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/pastatomato - name = "spaghetti" - desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!" - icon_state = "pastatomato" - trash = /obj/item/trash/plate - filling_color = "#DE4545" - bitesize = 4 - list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/meatballspaghetti - name = "spaghetti & Meatballs" - desc = "Now thats a nic'e meatball!" - icon_state = "meatballspaghetti" - trash = /obj/item/trash/plate - filling_color = "#DE4545" - list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/spesslaw - name = "Spesslaw" - desc = "A lawyer's favourite." - icon_state = "spesslaw" - filling_color = "#DE4545" - list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6) - -/obj/item/reagent_containers/food/snacks/poppypretzel - name = "Poppy Pretzel" - desc = "A large soft pretzel full of POP!" - icon_state = "poppypretzel" - filling_color = "#AB7D2E" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/carrotfries - name = "Carrot Fries" - desc = "Tasty fries from fresh carrots." - icon_state = "carrotfries" - trash = /obj/item/trash/plate - filling_color = "#FAA005" - list_reagents = list("plantmatter" = 3, "oculine" = 3, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/superbiteburger - name = "Super Bite Burger" - desc = "This is a mountain of a burger. FOOD!" - icon_state = "superbiteburger" - filling_color = "#CCA26A" - bitesize = 7 - list_reagents = list("nutriment" = 40, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/candiedapple - name = "Candied Apple" - desc = "An apple coated in sugary sweetness." - icon_state = "candiedapple" - filling_color = "#F21873" - bitesize = 3 - list_reagents = list("nutriment" = 3, "sugar" = 2) - -/obj/item/reagent_containers/food/snacks/applepie - name = "Apple Pie" - desc = "A pie containing sweet sweet love... or apple." - icon_state = "applepie" - filling_color = "#E0EDC5" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/cherrypie - name = "Cherry Pie" - desc = "Taste so good, make a grown man cry." - icon_state = "cherrypie" - filling_color = "#FF525A" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/twobread - name = "Two Bread" - desc = "It is very bitter and winy." - icon_state = "twobread" - filling_color = "#DBCC9A" - bitesize = 3 - list_reagents = list("nutriment" = 2, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/jellysandwich - name = "Jelly Sandwich" - desc = "You wish you had some peanut butter to go with this..." - icon_state = "jellysandwich" - trash = /obj/item/trash/plate - filling_color = "#9E3A78" - bitesize = 3 - -/obj/item/reagent_containers/food/snacks/jellysandwich/slime - list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/jellysandwich/cherry - list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/boiledslimecore - name = "Boiled Slime Core" - desc = "A boiled red thing." - icon_state = "boiledrorocore" - bitesize = 3 - list_reagents = list("slimejelly" = 5) - -/obj/item/reagent_containers/food/snacks/mint - name = "mint" - desc = "it is only wafer thin." - icon_state = "mint" - bitesize = 1 - filling_color = "#F2F2F2" - list_reagents = list("minttoxin" = 1) - -/obj/item/reagent_containers/food/snacks/mushroomsoup - name = "chantrelle soup" - desc = "A delicious and hearty mushroom soup." - icon_state = "mushroomsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#E386BF" - bitesize = 5 - list_reagents = list("nutriment" = 8, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit - name = "plump helmet biscuit" - desc = "This is a finely-prepared plump helmet biscuit. The ingredients are exceptionally minced plump helmet, and well-minced dwarven wheat flour." - icon_state = "phelmbiscuit" - filling_color = "#CFB4C4" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit/New() - ..() - if(prob(10)) - name = "exceptional plump helmet biscuit" - desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" // Is this a reference? - reagents.add_reagent("omnizine", 5) - -/obj/item/reagent_containers/food/snacks/chawanmushi - name = "chawanmushi" - desc = "A legendary egg custard that makes friends out of enemies. Probably too hot for a cat to eat." - icon_state = "chawanmushi" - trash = /obj/item/trash/snack_bowl - filling_color = "#F0F2E4" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/beetsoup - name = "beet soup" - desc = "Wait, how do you spell it again..?" - icon_state = "beetsoup" - trash = /obj/item/trash/snack_bowl - bitesize = 5 - filling_color = "#FAC9FF" - list_reagents = list("nutriment" = 7, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/beetsoup/New() - ..() - name = pick("borsch","bortsch","borstch","borsh","borshch","borscht") - -/obj/item/reagent_containers/food/snacks/herbsalad - name = "herb salad" - desc = "A tasty salad with apples on top." - icon_state = "herbsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#76B87F" - bitesize = 3 - list_reagents = list("nutriment" = 8, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/validsalad - name = "valid salad" - desc = "It's just an herb salad with meatballs and fried potato slices. Nothing suspicious about it." - icon_state = "validsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#76B87F" - bitesize = 3 - list_reagents = list("nutriment" = 8, "salglu_solution" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/appletart - name = "golden apple streusel tart" - desc = "A tasty dessert that won't make it through a metal detector." - icon_state = "gappletart" - trash = /obj/item/trash/plate - filling_color = "#FFFF00" - bitesize = 3 - list_reagents = list("nutriment" = 8, "gold" = 5, "vitamin" = 4) - -/////////////////////////////////////////////////Sliceable//////////////////////////////////////// -// All the food items that can be sliced into smaller bits like Meatbread and Cheesewheels - -// sliceable is just an organization type path, it doesn't have any additional code or variables tied to it. - -/obj/item/reagent_containers/food/snacks/sliceable/meatbread - name = "meatbread loaf" - desc = "The culinary base of every self-respecting eloquen/tg/entleman." - icon_state = "meatbread" - slice_path = /obj/item/reagent_containers/food/snacks/meatbreadslice - slices_num = 5 - filling_color = "#FF7575" - list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/meatbreadslice - name = "meatbread slice" - desc = "A slice of delicious meatbread." - icon_state = "meatbreadslice" - trash = /obj/item/trash/plate - filling_color = "#FF7575" - -/obj/item/reagent_containers/food/snacks/sliceable/xenomeatbread - name = "xenomeatbread loaf" - desc = "The culinary base of every self-respecting eloquent gentleman. Extra Heretical." - icon_state = "xenomeatbread" - slice_path = /obj/item/reagent_containers/food/snacks/xenomeatbreadslice - slices_num = 5 - filling_color = "#8AFF75" - list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/xenomeatbreadslice - name = "xenomeatbread slice" - desc = "A slice of delicious meatbread. Extra Heretical." - icon_state = "xenobreadslice" - trash = /obj/item/trash/plate - filling_color = "#8AFF75" - -/obj/item/reagent_containers/food/snacks/sliceable/spidermeatbread - name = "spider meat loaf" - desc = "Reassuringly green meatloaf made from spider meat." - icon_state = "spidermeatbread" - slice_path = /obj/item/reagent_containers/food/snacks/spidermeatbreadslice - slices_num = 5 - list_reagents = list("protein" = 20, "nutriment" = 10, "toxin" = 15, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/spidermeatbreadslice - name = "spider meat bread slice" - desc = "A slice of meatloaf made from an animal that most likely still wants you dead." - icon_state = "xenobreadslice" - trash = /obj/item/trash/plate - list_reagents = list("toxin" = 2) - -/obj/item/reagent_containers/food/snacks/sliceable/bananabread - name = "Banana-nut bread" - desc = "A heavenly and filling treat." - icon_state = "bananabread" - slice_path = /obj/item/reagent_containers/food/snacks/bananabreadslice - slices_num = 5 - filling_color = "#EDE5AD" - list_reagents = list("banana" = 20, "nutriment" = 20) - -/obj/item/reagent_containers/food/snacks/bananabreadslice - name = "Banana-nut bread slice" - desc = "A slice of delicious banana bread." - icon_state = "bananabreadslice" - trash = /obj/item/trash/plate - filling_color = "#EDE5AD" - -/obj/item/reagent_containers/food/snacks/sliceable/tofubread - name = "Tofubread" - icon_state = "Like meatbread but for vegetarians. Not guaranteed to give superpowers." - icon_state = "tofubread" - slice_path = /obj/item/reagent_containers/food/snacks/tofubreadslice - slices_num = 5 - filling_color = "#F7FFE0" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/tofubreadslice - name = "Tofubread slice" - desc = "A slice of delicious tofubread." - icon_state = "tofubreadslice" - trash = /obj/item/trash/plate - filling_color = "#F7FFE0" - -/obj/item/reagent_containers/food/snacks/sliceable/carrotcake - name = "Carrot Cake" - desc = "A favorite desert of a certain wascally wabbit. Not a lie." - icon_state = "carrotcake" - slice_path = /obj/item/reagent_containers/food/snacks/carrotcakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#FFD675" - list_reagents = list("nutriment" = 20, "oculine" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/carrotcakeslice - name = "Carrot Cake slice" - desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." - icon_state = "carrotcake_slice" - trash = /obj/item/trash/plate - filling_color = "#FFD675" - -/obj/item/reagent_containers/food/snacks/sliceable/braincake - name = "Brain Cake" - desc = "A squishy cake-thing." - icon_state = "braincake" - slice_path = /obj/item/reagent_containers/food/snacks/braincakeslice - slices_num = 5 - filling_color = "#E6AEDB" - bitesize = 3 - list_reagents = list("protein" = 10, "nutriment" = 10, "mannitol" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/braincakeslice - name = "Brain Cake slice" - desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." - icon_state = "braincakeslice" - trash = /obj/item/trash/plate - filling_color = "#E6AEDB" - -/obj/item/reagent_containers/food/snacks/sliceable/cheesecake - name = "Cheese Cake" - desc = "DANGEROUSLY cheesy." - icon_state = "cheesecake" - slice_path = /obj/item/reagent_containers/food/snacks/cheesecakeslice - slices_num = 5 - filling_color = "#FAF7AF" - bitesize = 3 - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/cheesecakeslice - name = "Cheese Cake slice" - desc = "Slice of pure cheestisfaction." - icon_state = "cheesecake_slice" - trash = /obj/item/trash/plate - filling_color = "#FAF7AF" - -/obj/item/reagent_containers/food/snacks/sliceable/plaincake - name = "Vanilla Cake" - desc = "A plain cake, not a lie." - icon_state = "plaincake" - slice_path = /obj/item/reagent_containers/food/snacks/plaincakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#F7EDD5" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/plaincakeslice - name = "Vanilla Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "plaincake_slice" - trash = /obj/item/trash/plate - filling_color = "#F7EDD5" - -/obj/item/reagent_containers/food/snacks/sliceable/orangecake - name = "Orange Cake" - desc = "A cake with added orange." - icon_state = "orangecake" - slice_path = /obj/item/reagent_containers/food/snacks/orangecakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#FADA8E" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/orangecakeslice - name = "Orange Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "orangecake_slice" - trash = /obj/item/trash/plate - filling_color = "#FADA8E" - -/obj/item/reagent_containers/food/snacks/sliceable/limecake - name = "Lime Cake" - desc = "A cake with added lime." - icon_state = "limecake" - bitesize = 3 - slice_path = /obj/item/reagent_containers/food/snacks/limecakeslice - slices_num = 5 - filling_color = "#CBFA8E" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/limecakeslice - name = "Lime Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "limecake_slice" - trash = /obj/item/trash/plate - filling_color = "#CBFA8E" - -/obj/item/reagent_containers/food/snacks/sliceable/lemoncake - name = "Lemon Cake" - desc = "A cake with added lemon." - icon_state = "lemoncake" - slice_path = /obj/item/reagent_containers/food/snacks/lemoncakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#FAFA8E" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/lemoncakeslice - name = "Lemon Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "lemoncake_slice" - trash = /obj/item/trash/plate - filling_color = "#FAFA8E" - -/obj/item/reagent_containers/food/snacks/sliceable/chocolatecake - name = "Chocolate Cake" - desc = "A cake with added chocolate." - icon_state = "chocolatecake" - slice_path = /obj/item/reagent_containers/food/snacks/chocolatecakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#805930" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/chocolatecakeslice - name = "Chocolate Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "chocolatecake_slice" - trash = /obj/item/trash/plate - filling_color = "#805930" - -/obj/item/reagent_containers/food/snacks/sliceable/cheesewheel - name = "Cheese wheel" - desc = "A big wheel of delicious Cheddar." - icon_state = "cheesewheel" - slice_path = /obj/item/reagent_containers/food/snacks/cheesewedge - slices_num = 5 - filling_color = "#FFF700" - list_reagents = list("nutriment" = 15, "vitamin" = 5, "cheese" = 20) - -/obj/item/reagent_containers/food/snacks/cheesewedge - name = "Cheese wedge" - desc = "A wedge of delicious Cheddar. The cheese wheel it was cut from can't have gone far." - icon_state = "cheesewedge" - filling_color = "#FFF700" - -/obj/item/reagent_containers/food/snacks/weirdcheesewedge - name = "Weird Cheese" - desc = "Some kind of... gooey, messy, gloopy thing. Similar to cheese, but only in the looser sense of the word." - icon_state = "weirdcheesewedge" - filling_color = "#00FF33" - list_reagents = list("mercury" = 5, "lsd" = 5, "ethanol" = 5, "weird_cheese" = 5) - -/obj/item/reagent_containers/food/snacks/sliceable/birthdaycake - name = "Birthday Cake" - desc = "Happy Birthday..." - icon_state = "birthdaycake" - slice_path = /obj/item/reagent_containers/food/snacks/birthdaycakeslice - slices_num = 5 - filling_color = "#FFD6D6" - bitesize = 3 - list_reagents = list("nutriment" = 20, "sprinkles" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/birthdaycakeslice - name = "Birthday Cake slice" - desc = "A slice of your birthday" - icon_state = "birthdaycakeslice" - trash = /obj/item/trash/plate - filling_color = "#FFD6D6" - -/obj/item/reagent_containers/food/snacks/sliceable/bread - name = "Bread" - icon_state = "Some plain old Earthen bread." - icon_state = "bread" - slice_path = /obj/item/reagent_containers/food/snacks/breadslice - slices_num = 6 - filling_color = "#FFE396" - list_reagents = list("nutriment" = 10) - -/obj/item/reagent_containers/food/snacks/breadslice - name = "Bread slice" - desc = "A slice of home." - icon_state = "breadslice" - trash = /obj/item/trash/plate - filling_color = "#D27332" - list_reagents = list("nutriment" = 2, "bread" = 5) - -/obj/item/reagent_containers/food/snacks/sliceable/creamcheesebread - name = "Cream Cheese Bread" - desc = "Yum yum yum!" - icon_state = "creamcheesebread" - slice_path = /obj/item/reagent_containers/food/snacks/creamcheesebreadslice - slices_num = 5 - filling_color = "#FFF896" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/creamcheesebreadslice - name = "Cream Cheese Bread slice" - desc = "A slice of yum!" - icon_state = "creamcheesebreadslice" - trash = /obj/item/trash/plate - filling_color = "#FFF896" - list_reagents = list("nutriment" = 4, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/watermelonslice - name = "Watermelon Slice" - desc = "A slice of watery goodness." - icon_state = "watermelonslice" - filling_color = "#FF3867" - -/obj/item/reagent_containers/food/snacks/pineappleslice - name = "Pineapple Slices" - desc = "Rings of pineapple." - icon_state = "pineappleslice" - filling_color = "#e5b437" - -/obj/item/reagent_containers/food/snacks/sliceable/applecake - name = "Apple Cake" - desc = "A cake centered with Apple." - icon_state = "applecake" - slice_path = /obj/item/reagent_containers/food/snacks/applecakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#EBF5B8" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/applecakeslice - name = "Apple Cake slice" - desc = "A slice of heavenly cake." - icon_state = "applecakeslice" - trash = /obj/item/trash/plate - filling_color = "#EBF5B8" - -/obj/item/reagent_containers/food/snacks/sliceable/pumpkinpie - name = "Pumpkin Pie" - desc = "A delicious treat for the autumn months." - icon_state = "pumpkinpie" - slice_path = /obj/item/reagent_containers/food/snacks/pumpkinpieslice - slices_num = 5 - bitesize = 3 - filling_color = "#F5B951" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/pumpkinpieslice - name = "Pumpkin Pie slice" - desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." - icon_state = "pumpkinpieslice" - trash = /obj/item/trash/plate - filling_color = "#F5B951" - -/obj/item/reagent_containers/food/snacks/cracker - name = "Cracker" - desc = "It's a salted cracker." - icon_state = "cracker" - bitesize = 1 - filling_color = "#F5DEB8" - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/rawcutlet - name = "raw cutlet" - desc = "A thin piece of raw meat." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "rawcutlet" - bitesize = 1 - list_reagents = list("protein" = 1) - -/obj/item/reagent_containers/food/snacks/rawcutlet/attackby(obj/item/W, mob/user, params) - if(istype(W,/obj/item/kitchen/knife)) - user.visible_message( \ - "[user] cuts the raw cutlet with the knife!", \ - "You cut the raw cutlet with your knife!" \ - ) - new /obj/item/reagent_containers/food/snacks/raw_bacon(loc) - qdel(src) - - -/////////////////////////////////////////////////PIZZA//////////////////////////////////////// - -/obj/item/reagent_containers/food/snacks/sliceable/pizza - slices_num = 6 - filling_color = "#BAA14C" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita - name = "Margherita" - desc = "The golden standard of pizzas." - icon_state = "pizzamargherita" - slice_path = /obj/item/reagent_containers/food/snacks/margheritaslice - slices_num = 6 - list_reagents = list("nutriment" = 30, "tomatojuice" = 6, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/margheritaslice - name = "Margherita slice" - desc = "A slice of the classic pizza." - icon_state = "pizzamargheritaslice" - filling_color = "#BAA14C" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza - name = "Meatpizza" - desc = "A pizza with meat topping." - icon_state = "meatpizza" - slice_path = /obj/item/reagent_containers/food/snacks/meatpizzaslice - slices_num = 6 - list_reagents = list("protein" = 30, "tomatojuice" = 6, "vitamin" = 8) - -/obj/item/reagent_containers/food/snacks/meatpizzaslice - name = "Meatpizza slice" - desc = "A slice of a meaty pizza." - icon_state = "meatpizzaslice" - filling_color = "#BAA14C" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza - name = "Mushroompizza" - desc = "Very special pizza." - icon_state = "mushroompizza" - slice_path = /obj/item/reagent_containers/food/snacks/mushroompizzaslice - slices_num = 6 - list_reagents = list("plantmatter" = 30, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/mushroompizzaslice - name = "Mushroompizza slice" - desc = "Maybe it is the last slice of pizza in your life." - icon_state = "mushroompizzaslice" - filling_color = "#BAA14C" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza - name = "Vegetable pizza" - desc = "No one of Tomato Sapiens were harmed during making this pizza." - icon_state = "vegetablepizza" - slice_path = /obj/item/reagent_containers/food/snacks/vegetablepizzaslice - slices_num = 6 - list_reagents = list("plantmatter" = 25, "tomatojuice" = 6, "oculine" = 12, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/vegetablepizzaslice - name = "Vegetable pizza slice" - desc = "A slice of the most green pizza of all pizzas not containing green ingredients." - icon_state = "vegetablepizzaslice" - filling_color = "#BAA14C" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza - name = "Hawaiian Pizza" - desc = "Love it or hate it, this pizza divides opinions. Complete with juicy pineapple." - icon_state = "hawaiianpizza" //NEEDED - slice_path = /obj/item/reagent_containers/food/snacks/hawaiianpizzaslice - slices_num = 6 - list_reagents = list("protein" = 15, "tomatojuice" = 6, "plantmatter" = 20, "pineapplejuice" = 6, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/hawaiianpizzaslice - name = "Hawaiian pizza slice" - desc = "A slice of polarising pizza." - icon_state = "hawaiianpizzaslice" - filling_color = "#e5b437" - -/obj/item/pizzabox - name = "pizza box" - desc = "A box suited for pizzas." - icon = 'icons/obj/food/food.dmi' - icon_state = "pizzabox1" - - var/open = 0 // Is the box open? - var/ismessy = 0 // Fancy mess on the lid - var/obj/item/reagent_containers/food/snacks/sliceable/pizza/pizza // Content pizza - var/list/boxes = list() // If the boxes are stacked, they come here - var/boxtag = "" - -/obj/item/pizzabox/update_icon() - - overlays = list() - - // Set appropriate description - if( open && pizza ) - desc = "A box suited for pizzas. It appears to have a [pizza.name] inside." - else if( boxes.len > 0 ) - desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile." - - var/obj/item/pizzabox/topbox = boxes[boxes.len] - var/toptag = topbox.boxtag - if( toptag != "" ) - desc = "[desc] The box on top has a tag, it reads: '[toptag]'." - else - desc = "A box suited for pizzas." - - if( boxtag != "" ) - desc = "[desc] The box has a tag, it reads: '[boxtag]'." - - // Icon states and overlays - if( open ) - if( ismessy ) - icon_state = "pizzabox_messy" - else - icon_state = "pizzabox_open" - - if( pizza ) - var/image/pizzaimg = image("food/food.dmi", icon_state = pizza.icon_state) - pizzaimg.pixel_y = -3 - overlays += pizzaimg - - return - else - // Stupid code because byondcode sucks - var/doimgtag = 0 - if( boxes.len > 0 ) - var/obj/item/pizzabox/topbox = boxes[boxes.len] - if( topbox.boxtag != "" ) - doimgtag = 1 - else - if( boxtag != "" ) - doimgtag = 1 - - if( doimgtag ) - var/image/tagimg = image("food/food.dmi", icon_state = "pizzabox_tag") - tagimg.pixel_y = boxes.len * 3 - overlays += tagimg - - icon_state = "pizzabox[boxes.len+1]" - -/obj/item/pizzabox/attack_hand(mob/user) - if(open && pizza) - user.put_in_hands(pizza) - to_chat(user, "You take the [pizza] out of the [src].") - pizza = null - update_icon() - return - - if(boxes.len > 0) - if(user.is_in_inactive_hand(src)) - ..() - return - - var/obj/item/pizzabox/box = boxes[boxes.len] - boxes -= box - - user.put_in_hands( box ) - to_chat(user, "You remove the topmost [src] from your hand.") - box.update_icon() - update_icon() - return - ..() - -/obj/item/pizzabox/attack_self(mob/user) - if(boxes.len > 0) - return - - open = !open - - if( open && pizza ) - ismessy = 1 - - update_icon() - -/obj/item/pizzabox/attackby( obj/item/I, mob/user, params) - if(istype(I, /obj/item/pizzabox/)) - var/obj/item/pizzabox/box = I - - if(!box.open && !open) - // Make a list of all boxes to be added - var/list/boxestoadd = list() - boxestoadd += box - for(var/obj/item/pizzabox/i in box.boxes) - boxestoadd += i - - if( (boxes.len+1) + boxestoadd.len <= 5 ) - user.drop_item() - - box.loc = src - box.boxes = list() // Clear the box boxes so we don't have boxes inside boxes. - Xzibit - boxes.Add( boxestoadd ) - - box.update_icon() - update_icon() - - to_chat(user, "You put the [box] ontop of the [src]!") - else - to_chat(user, "The stack is too high!") - else - to_chat(user, "Close the [box] first!") - - return - - if(istype(I, /obj/item/reagent_containers/food/snacks/sliceable/pizza/)) // Long ass fucking object name - - if(open) - user.drop_item() - I.loc = src - pizza = I - - update_icon() - - to_chat(user, "You put the [I] in the [src]!") - else - to_chat(user, "You try to push the [I] through the lid but it doesn't work!") - return - - if(istype(I, /obj/item/pen/)) - - if(open) - return - - var/t = input("Enter what you want to add to the tag:", "Write", null, null) as text - - var/obj/item/pizzabox/boxtotagto = src - if( boxes.len > 0 ) - boxtotagto = boxes[boxes.len] - - boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30) - - update_icon() - return - ..() - -/obj/item/pizzabox/margherita/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita(src) - boxtag = "Margherita Deluxe" - -/obj/item/pizzabox/vegetable/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza(src) - boxtag = "Gourmet Vegatable" - -/obj/item/pizzabox/mushroom/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza(src) - boxtag = "Mushroom Special" - -/obj/item/pizzabox/meat/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza(src) - boxtag = "Meatlover's Supreme" - -/obj/item/pizzabox/hawaiian/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza(src) - boxtag = "Hawaiian Feast" - -////////////////////////////////FOOD ADDITIONS//////////////////////////////////////////// - -/obj/item/reagent_containers/food/snacks/wrap - name = "egg wrap" - desc = "The precursor to Pigs in a Blanket." - icon_state = "wrap" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/beans - name = "tin of beans" - desc = "Musical fruit in a slightly less musical container." - icon_state = "beans" - list_reagents = list("nutriment" = 10, "beans" = 10, "vitamin" = 3) - -/obj/item/reagent_containers/food/snacks/benedict - name = "eggs benedict" - desc = "There is only one egg on this, how rude." - icon_state = "benedict" - bitesize = 3 - list_reagents = list("nutriment" = 6, "egg" = 3, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/hotdog - name = "hotdog" - desc = "Fresh footlong ready to go down on." - icon_state = "hotdog" - bitesize = 3 - list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3) - -/obj/item/reagent_containers/food/snacks/meatbun - name = "meat bun" - desc = "Has the potential to not be Dog." - icon_state = "meatbun" - bitesize = 6 - list_reagents = list("nutriment" = 6, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/icecreamsandwich - name = "icecream sandwich" - desc = "Portable Ice-cream in it's own packaging." - icon_state = "icecreamsandwich" - list_reagents = list("nutriment" = 2, "ice" = 2) - -/obj/item/reagent_containers/food/snacks/notasandwich - name = "not-a-sandwich" - desc = "Something seems to be wrong with this, you can't quite figure what. Maybe it's his moustache." - icon_state = "notasandwich" - list_reagents = list("nutriment" = 6, "vitamin" = 6) - -/obj/item/reagent_containers/food/snacks/sugarcookie - name = "sugar cookie" - desc = "Just like your little sister used to make." - icon_state = "sugarcookie" - list_reagents = list("nutriment" = 3, "sugar" = 3) - -/obj/item/reagent_containers/food/snacks/friedbanana - name = "Fried Banana" - desc = "Goreng Pisang, also known as fried bananas." - icon_state = "friedbanana" - list_reagents = list("sugar" = 5, "nutriment" = 8, "cornoil" = 4) - -/obj/item/reagent_containers/food/snacks/dionaroast - name = "roast diona" - desc = "It's like an enormous, leathery carrot. With an eye." - icon_state = "dionaroast" - trash = /obj/item/trash/plate - filling_color = "#75754B" - list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/boiledspiderleg - name = "boiled spider leg" - desc = "A giant spider's leg that's still twitching after being cooked. Gross!" - icon_state = "spiderlegcooked" - trash = /obj/item/trash/plate - bitesize = 3 - list_reagents = list("nutriment" = 3, "capsaicin" = 2) - -/obj/item/reagent_containers/food/snacks/spidereggs - name = "spider eggs" - desc = "A cluster of juicy spider eggs. A great side dish for when you care not for your health." - icon_state = "spidereggs" - list_reagents = list("protein" = 2, "toxin" = 2) - -/obj/item/reagent_containers/food/snacks/spidereggsham - name = "green eggs and ham" - desc = "Would you eat them on a train? Would you eat them on a plane? Would you eat them on a state of the art corporate deathtrap floating through space?" - icon_state = "spidereggsham" - trash = /obj/item/trash/plate - bitesize = 4 - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/sliceable/turkey - name = "Turkey" - desc = "A traditional turkey served with stuffing." - icon_state = "turkey" - slice_path = /obj/item/reagent_containers/food/snacks/turkeyslice - slices_num = 6 - list_reagents = list("protein" = 24, "nutriment" = 18, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/turkeyslice - name = "turkey serving" - desc = "A serving of some tender and delicious turkey." - icon_state = "turkeyslice" - trash = /obj/item/trash/plate - filling_color = "#B97A57" - -/obj/item/reagent_containers/food/snacks/mashed_potatoes //mashed taters - name = "mashed potatoes" - desc = "Some sot creamy, and irresistible mashed potatoes." - icon_state = "mashedtaters" - trash = /obj/item/trash/plate - filling_color = "#D6D9C1" - list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10, "vitamin" = 2) - -////////////////////////////////ICE CREAM/////////////////////////////////// -/obj/item/reagent_containers/food/snacks/icecream - name = "ice cream" - desc = "Delicious ice cream." - icon = 'icons/obj/kitchen.dmi' - icon_state = "icecream_cone" - bitesize = 3 - list_reagents = list("nutriment" = 1, "sugar" = 1) - -/obj/item/reagent_containers/food/snacks/icecream/New() - ..() - update_icon() - -/obj/item/reagent_containers/food/snacks/icecream/update_icon() - overlays.Cut() - var/image/filling = image('icons/obj/kitchen.dmi', src, "icecream_color") - filling.icon += mix_color_from_reagents(reagents.reagent_list) - overlays += filling - -/obj/item/reagent_containers/food/snacks/icecream/icecreamcone - name = "ice cream cone" - desc = "Delicious ice cream." - icon_state = "icecream_cone" - volume = 50 - bitesize = 3 - list_reagents = list("nutriment" = 3, "sugar" = 7, "ice" = 2) - -/obj/item/reagent_containers/food/snacks/icecream/icecreamcup - name = "chocolate ice cream cone" - desc = "Delicious ice cream." - icon_state = "icecream_cup" - volume = 50 - bitesize = 6 - list_reagents = list("nutriment" = 5, "chocolate" = 8, "ice" = 2) +// MISC /obj/item/reagent_containers/food/snacks/cereal name = "box of cereal" @@ -2411,131 +300,5 @@ icon_state = "deepfried_holder_icon" list_reagents = list("nutriment" = 3) -/obj/item/reagent_containers/food/snacks/dough - name = "dough" - desc = "A piece of dough." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "dough" - list_reagents = list("nutriment" = 6) -// Dough + rolling pin = flat dough -/obj/item/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/kitchen/rollingpin)) - if(isturf(loc)) - new /obj/item/reagent_containers/food/snacks/sliceable/flatdough(loc) - to_chat(user, "You flatten [src].") - qdel(src) - else - to_chat(user, "You need to put [src] on a surface to roll it out!") - else - ..() - -// slicable into 3xdoughslices -/obj/item/reagent_containers/food/snacks/sliceable/flatdough - name = "flat dough" - desc = "Some flattened dough." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "flat dough" - slice_path = /obj/item/reagent_containers/food/snacks/doughslice - slices_num = 3 - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/doughslice - name = "dough slice" - desc = "The building block of an impressive dish." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "doughslice" - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/bun - name = "bun" - desc = "The base for any self-respecting burger." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "bun" - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/taco - name = "taco" - desc = "Take a bite!" - icon_state = "taco" - bitesize = 3 - list_reagents = list("nutriment" = 7, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/cutlet - name = "cutlet" - desc = "A tasty meat slice." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "cutlet" - list_reagents = list("protein" = 2) - -/obj/item/reagent_containers/food/snacks/flatbread - name = "flatbread" - desc = "Bland but filling." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "flatbread" - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/rawsticks - name = "raw potato sticks" - desc = "Raw fries, not very tasty." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "rawsticks" - list_reagents = list("plantmatter" = 3) - -/obj/item/reagent_containers/food/snacks/ectoplasm - name = "ectoplasm" - desc = "A luminescent blob of what scientists refer to as 'ghost goo'." - icon = 'icons/obj/wizard.dmi' - icon_state = "ectoplasm" - list_reagents = list("ectoplasm" = 10) - -/obj/item/reagent_containers/food/snacks/liquidfood - name = "\improper LiquidFood Ration" - desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?" - icon_state = "liquidfood" - trash = /obj/item/trash/liquidfood - filling_color = "#A8A8A8" - bitesize = 4 - list_reagents = list("nutriment" = 20, "iron" = 3, "vitamin" = 2) - - -/obj/item/reagent_containers/food/snacks/tastybread - name = "bread tube" - desc = "Bread in a tube. Chewy...and surprisingly tasty." - icon_state = "tastybread" - trash = /obj/item/trash/tastybread - filling_color = "#A66829" - junkiness = 20 - list_reagents = list("nutriment" = 2, "sugar" = 4) - -/obj/item/reagent_containers/food/snacks/yakiimo - name = "yaki imo" - desc = "Made with roasted sweet potatoes!" - icon_state = "yakiimo" - trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 5, "vitamin" = 4) - filling_color = "#8B1105" - -/obj/item/reagent_containers/food/snacks/roastparsnip - name = "roast parsnip" - desc = "Sweet and crunchy." - icon_state = "roastparsnip" - trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 3, "vitamin" = 4) - filling_color = "#FF5500" - -/obj/item/reagent_containers/food/snacks/tatortot - name = "tator tot" - desc = "A large fried potato nugget that may or may not try to valid you." - icon_state = "tatortot" - list_reagents = list("nutriment" = 4) - filling_color = "FFD700" - -/obj/item/reagent_containers/food/snacks/onionrings - name = "onion rings" - desc = "Onion slices coated in batter." - icon_state = "onionrings" - list_reagents = list("nutriment" = 3) - filling_color = "#C0C9A0" - gender = PLURAL #undef MAX_WEIGHT_CLASS \ No newline at end of file diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index a67b88f97d4..1e3c5602a22 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -122,7 +122,7 @@ to_chat(user, "The [src] is locked and running, wait for it to finish.") return - if(!ishuman(victim) || issmall(victim)) + if(!ishuman(victim)) to_chat(user, "This is not suitable for the [src]!") return @@ -255,8 +255,11 @@ if(occupant.reagents) occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count,1)) - if(occupant.get_species() == "Human") - new /obj/item/stack/sheet/animalhide/human(src) + if(ishuman(occupant)) + var/mob/living/carbon/human/H = occupant + var/skinned = H.dna.species.skinned_type + if(skinned) + new skinned(src) new /obj/effect/decal/cleanable/blood/gibs(src) if(!UserOverride) diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index dfbea528d53..ad4dcb5e4d8 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -87,6 +87,10 @@ input = /obj/item/reagent_containers/food/snacks/doughslice output = /obj/item/reagent_containers/food/snacks/spaghetti +/datum/food_processor_process/macaroni + input = /obj/item/reagent_containers/food/snacks/spaghetti + output = /obj/item/reagent_containers/food/snacks/macaroni + /datum/food_processor_process/parsnip input = /obj/item/reagent_containers/food/snacks/grown/parsnip output = /obj/item/reagent_containers/food/snacks/roastparsnip diff --git a/code/modules/food_and_drinks/recipes/recipes_microwave.dm b/code/modules/food_and_drinks/recipes/recipes_microwave.dm index effbcef37ba..70169476c9d 100644 --- a/code/modules/food_and_drinks/recipes/recipes_microwave.dm +++ b/code/modules/food_and_drinks/recipes/recipes_microwave.dm @@ -396,6 +396,14 @@ ) result = /obj/item/reagent_containers/food/snacks/spesslaw +/datum/recipe/microwave/macncheese + reagents = list("water" = 5, "milk" = 5) + items = list( + /obj/item/reagent_containers/food/snacks/cheesewedge, + /obj/item/reagent_containers/food/snacks/macaroni, + ) + result = /obj/item/reagent_containers/food/snacks/macncheese + /datum/recipe/microwave/superbiteburger reagents = list("sodiumchloride" = 5, "blackpepper" = 5) items = list( diff --git a/code/modules/food_and_drinks/recipes/recipes_oven.dm b/code/modules/food_and_drinks/recipes/recipes_oven.dm index b4b636a6ee7..7dcfe199ded 100644 --- a/code/modules/food_and_drinks/recipes/recipes_oven.dm +++ b/code/modules/food_and_drinks/recipes/recipes_oven.dm @@ -180,21 +180,16 @@ result = /obj/item/reagent_containers/food/snacks/fortunecookie /datum/recipe/oven/fortunecookie/make_food(obj/container) - var/obj/item/paper/paper = locate() in container - paper.loc = null //prevent deletion + var/obj/item/paper/P = locate() in container + P.loc = null //So we don't delete the paper while cooking the cookie var/obj/item/reagent_containers/food/snacks/fortunecookie/being_cooked = ..() - paper.loc = being_cooked - being_cooked.trash = paper //so the paper is left behind as trash without special-snowflake(TM Nodrak) code ~carn + if(P.info) //If there's anything written on the paper, just move it into the fortune cookie + P.forceMove(being_cooked) //Prevents the oven deleting our paper + being_cooked.trash = P //so the paper is left behind as trash without special-snowflake(TM Nodrak) code ~carn + else + qdel(P) return being_cooked -/datum/recipe/oven/fortunecookie/check_items(obj/container) - . = ..() - if(.) - var/obj/item/paper/paper = locate() in container - if(!paper || !paper.info) - return -1 - return . - /datum/recipe/oven/pizzamargherita items = list( /obj/item/reagent_containers/food/snacks/sliceable/flatdough, @@ -264,6 +259,15 @@ ) result = /obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza +/datum/recipe/oven/macncheesepizza + items = list( + /obj/item/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/reagent_containers/food/snacks/cheesewedge, + /obj/item/reagent_containers/food/snacks/cheesewedge, + /obj/item/reagent_containers/food/snacks/macncheese, + ) + result = /obj/item/reagent_containers/food/snacks/sliceable/pizza/macpizza + /datum/recipe/oven/amanita_pie items = list( /obj/item/reagent_containers/food/snacks/sliceable/flatdough, diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 950b873af55..7acd3efc961 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -23,7 +23,7 @@ return 1 /mob/living/carbon/human/bee_friendly() - if(get_species() == "Diona") //bees pollinate plants, duh. + if(isdiona(src)) //bees pollinate plants, duh. return 1 if((wear_suit && (wear_suit.flags & THICKMATERIAL)) && (head && (head.flags & THICKMATERIAL))) return 1 diff --git a/code/modules/martial_arts/brawling.dm b/code/modules/martial_arts/brawling.dm index a40a52b86be..b326e9f8b33 100644 --- a/code/modules/martial_arts/brawling.dm +++ b/code/modules/martial_arts/brawling.dm @@ -15,7 +15,7 @@ var/atk_verb = pick("left hook","right hook","straight punch") - var/damage = rand(5, 8) + A.species.punchdamagelow + var/damage = rand(5, 8) + A.dna.species.punchdamagelow if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index f42b7963104..bff0cf0d2e4 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -33,8 +33,8 @@ /datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) - var/damage = rand(A.species.punchdamagelow, A.species.punchdamagehigh) - var/datum/unarmed_attack/attack = A.species.unarmed + var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh) + var/datum/unarmed_attack/attack = A.dna.species.unarmed var/atk_verb = "[pick(attack.attack_verb)]" if(D.lying) @@ -62,7 +62,7 @@ add_attack_logs(A, D, "Melee attacked with martial-art [src]", (damage > 0) ? null : ATKLOG_ALL) - if((D.stat != DEAD) && damage >= A.species.punchstunthreshold) + if((D.stat != DEAD) && damage >= A.dna.species.punchstunthreshold) D.visible_message("[A] has weakened [D]!!", \ "[A] has weakened [D]!") D.apply_effect(4, WEAKEN, armor_block) diff --git a/code/modules/martial_arts/mimejutsu.dm b/code/modules/martial_arts/mimejutsu.dm index 38605c3538d..e8aa7a53d03 100644 --- a/code/modules/martial_arts/mimejutsu.dm +++ b/code/modules/martial_arts/mimejutsu.dm @@ -23,7 +23,7 @@ /datum/martial_art/mimejutsu/proc/mimeChuck(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(!D.stat && !D.stunned && !D.weakened) - var/damage = rand(5, 8) + A.species.punchdamagelow + var/damage = rand(5, 8) + A.dna.species.punchdamagelow if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) D.visible_message("[A] swings invisible nunchcuks at [D]..and misses?") diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm index 9f4f7629c7e..4d94793a5e9 100644 --- a/code/modules/mining/coins.dm +++ b/code/modules/mining/coins.dm @@ -106,7 +106,7 @@ return if(CC.use(1)) - overlays += image('icons/obj/items.dmi',"coin_string_overlay") + overlays += image('icons/obj/economy.dmi',"coin_string_overlay") string_attached = 1 to_chat(user, "You attach a string to the coin.") else diff --git a/code/modules/mining/lavaland/loot/ashdragon_loot.dm b/code/modules/mining/lavaland/loot/ashdragon_loot.dm index ff0db975895..d88ec709dce 100644 --- a/code/modules/mining/lavaland/loot/ashdragon_loot.dm +++ b/code/modules/mining/lavaland/loot/ashdragon_loot.dm @@ -116,7 +116,7 @@ switch(random) if(1) to_chat(user, "Your flesh begins to melt! Miraculously, you seem fine otherwise.") - H.set_species("Skeleton") + H.set_species(/datum/species/skeleton) if(2) to_chat(user, "Power courses through you! You can now shift your form at will.") if(user.mind) diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index ddf1255cca0..59d3a715f32 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -289,7 +289,7 @@ if(ishuman(i)) var/mob/living/carbon/human/H = i if(H.stat == DEAD) - H.set_species("Shadow") + H.set_species(/datum/species/shadow) H.revive() H.disabilities |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal H.grab_ghost(force = TRUE) diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm index e1c6c7f28a9..a80c2ae6c18 100644 --- a/code/modules/mining/lavaland/loot/tendril_loot.dm +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -105,13 +105,13 @@ to_chat(M, "This item is currently non-functional.") /*if(ishuman(M) && M.stat != DEAD) var/mob/living/carbon/human/H = M - if(H.species.name != "Human" || reac_volume < 5) // implying xenohumans are holy + if(!ishumanbasic(H) || reac_volume < 5) // implying xenohumans are holy if(method == INGEST && show_message) to_chat(H, "You feel nothing but a terrible aftertaste.") return ..() to_chat(H, "A terrible pain travels down your back as wings burst out!") - H.set_species("Angel") + H.set_species(/datum/species/angel) playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1, -1) H.adjustBruteLoss(20) H.emote("scream") diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 0a151babe67..c4487d61948 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -523,7 +523,7 @@ icon_state = "fan_tiny" buildstackamount = 2 -/obj/structure/fans/New(loc) +/obj/structure/fans/Initialize(loc) ..() air_update_turf(1) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 93bdfe30c27..1a6f29a6dd0 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -226,7 +226,14 @@ "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") /datum/language/vox/get_random_name() - return ..(FEMALE,1,6) + var/sounds = rand(2, 8) + var/i = 0 + var/newname = "" + + while(i <= sounds) + i++ + newname += pick(vox_name_syllables) + return capitalize(newname) /datum/language/diona name = "Rootspeak" @@ -240,8 +247,8 @@ syllables = list("hs","zt","kr","st","sh") /datum/language/diona/get_random_name() - var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]" - new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]" + var/new_name = "[pick(list("To Sleep Beneath", "Wind Over", "Embrace of", "Dreams of", "Witnessing", "To Walk Beneath", "Approaching the", "Glimmer of", "The Ripple of", "Colors of", "The Still of", "Silence of", "Gentle Breeze of", "Glistening Waters under", "Child of", "Blessed Plant-ling of", "Grass-Walker of", "Element of", "Spawn of"))]" + new_name += " [pick(list("the Void", "the Sky", "Encroaching Night", "Planetsong", "Starsong", "the Wandering Star", "the Empty Day", "Daybreak", "Nightfall", "the Rain", "the Stars", "the Waves", "Dusk", "Night", "the Wind", "the Summer Wind", "the Blazing Sun", "the Scorching Sun", "Eternal Fields", "the Soothing Plains", "the Undying Fiona", "Mother Nature's Bousum"))]" return new_name /datum/language/trinary @@ -507,8 +514,10 @@ ..(speaker,message,speaker.real_name) /datum/language/abductor/check_special_condition(mob/living/carbon/human/other, mob/living/carbon/human/speaker) - if(other.mind && other.mind.abductor) - if(other.mind.abductor.team == speaker.mind.abductor.team) + if(isabductor(other) && isabductor(speaker)) + var/datum/species/abductor/A = speaker.dna.species + var/datum/species/abductor/A2 = other.dna.species + if(A.team == A2.team) return TRUE return FALSE @@ -553,7 +562,7 @@ if(!message) return - + log_say("(ROBOT) [message]", speaker) var/message_start = "[name], [speaker.name]" var/message_body = "[speaker.say_quote(message)],\"[message]\"
    " diff --git a/code/modules/mob/living/autohiss.dm b/code/modules/mob/living/autohiss.dm index da19b6a35b2..df1bde34306 100644 --- a/code/modules/mob/living/autohiss.dm +++ b/code/modules/mob/living/autohiss.dm @@ -4,7 +4,7 @@ /mob/living/carbon/human/handle_autohiss(message, datum/language/L) if(!client || client.prefs.autohiss_mode == AUTOHISS_OFF) // no need to process if there's no client or they have autohiss off return message - return species.handle_autohiss(message, L, client.prefs.autohiss_mode) + return dna.species.handle_autohiss(message, L, client.prefs.autohiss_mode) /client/verb/toggle_autohiss() set name = "Toggle Auto-Accent" diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 99d5c795eb5..9d50d8bf2ea 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -16,6 +16,9 @@ var/obj/mecha/mecha = null//This does not appear to be used outside of reference in mecha.dm. // I'm using this for mechs giving MMIs HUDs now + var/obj/item/radio/radio = null // For use with the radio MMI upgrade + var/datum/action/generic/configure_mmi_radio/radio_action = null + /obj/item/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(istype(O, /obj/item/organ/internal/brain/crystal )) to_chat(user, " This brain is too malformed to be able to use with the [src].") @@ -29,34 +32,70 @@ to_chat(user, "Somehow, this MMI still has a brain in it. Report this to the bug tracker.") log_runtime(EXCEPTION("[user] tried to stick a [O] into [src] in [get_area(src)], but the held brain variable wasn't cleared"), src) return - for(var/mob/V in viewers(src, null)) - V.show_message("[user] sticks \a [O] into \the [src].") - brainmob = B.brainmob - B.brainmob = null - brainmob.loc = src - brainmob.container = src - brainmob.stat = CONSCIOUS - respawnable_list -= brainmob - dead_mob_list -= brainmob//Update dem lists - living_mob_list += brainmob + if(user.drop_item()) + B.forceMove(src) + visible_message("[user] sticks \a [O] into \the [src].") + brainmob = B.brainmob + B.brainmob = null + brainmob.loc = src + brainmob.container = src + brainmob.stat = CONSCIOUS + respawnable_list -= brainmob + dead_mob_list -= brainmob//Update dem lists + living_mob_list += brainmob - user.drop_item() - B.forceMove(src) - held_brain = B - if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff - name = "Man-Machine Interface: Alien - [brainmob.real_name]" - icon = 'icons/mob/alien.dmi' - icon_state = "AlienMMI" - alien = 1 + held_brain = B + if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff + name = "Man-Machine Interface: Alien - [brainmob.real_name]" + icon = 'icons/mob/alien.dmi' + become_occupied("AlienMMI") + alien = 1 + else + name = "Man-Machine Interface: [brainmob.real_name]" + icon = B.mmi_icon + become_occupied("[B.mmi_icon_state]") + alien = 0 + + if(radio_action) + radio_action.UpdateButtonIcon() + feedback_inc("cyborg_mmis_filled",1) else - name = "Man-Machine Interface: [brainmob.real_name]" - icon = B.mmi_icon - icon_state = "[B.mmi_icon_state]" - alien = 0 - feedback_inc("cyborg_mmis_filled",1) + to_chat(user, "You can't drop [B]!") return + if(istype(O, /obj/item/mmi_radio_upgrade)) + if(radio) + to_chat(user, "[src] already has a radio installed.") + else + user.visible_message("[user] begins to install the [O] into [src]...", \ + "You start to install the [O] into [src]...") + if(do_after(user, 20, target=src)) + if(user.drop_item()) + user.visible_message("[user] installs [O] in [src].", \ + "You install [O] in [src].") + if(brainmob) + to_chat(brainmob, "MMI radio capability installed.") + install_radio() + qdel(O) + else + to_chat(user, "You can't drop [O]!") + return + + // Maybe later add encryption key support, but that's a pain in the neck atm + if(isscrewdriver(O)) + if(radio) + user.visible_message("[user] begins to uninstall the radio from [src]...", \ + "You start to uninstall the radio from [src]...") + if(do_after(user, 40 * O.toolspeed, target = src)) + uninstall_radio() + new /obj/item/mmi_radio_upgrade(get_turf(src)) + user.visible_message("[user] uninstalls the radio from [src].", \ + "You uninstall the radio from [src].") + else + to_chat(user, "There is no radio in [src]!") + return + if(brainmob) O.attack(brainmob, user)//Oh noooeeeee // Brainmobs can take damage, but they can't actually die. Maybe should fix. @@ -82,10 +121,10 @@ brainmob.dna = H.dna.Clone() brainmob.container = src - if(!istype(H.species) || isnull(H.species.return_organ("brain"))) // Diona/buggy people + if(!istype(H.dna.species) || isnull(H.dna.species.return_organ("brain"))) // Diona/buggy people held_brain = new(src) else // We have a species, and it has a brain - var/brain_path = H.species.return_organ("brain") + var/brain_path = H.dna.species.return_organ("brain") if(!ispath(brain_path, /obj/item/organ/internal/brain)) brain_path = /obj/item/organ/internal/brain held_brain = new brain_path(src) // Slime people will keep their slimy brains this way @@ -93,8 +132,7 @@ held_brain.name = "\the [brainmob.name]'s [initial(held_brain.name)]" name = "Man-Machine Interface: [brainmob.real_name]" - icon_state = "mmi_full" - return + become_occupied("mmi_full") //I made this proc as a way to have a brainmob be transferred to any created brain, and to solve the //problem i was having with alien/nonalien brain drops. @@ -116,31 +154,54 @@ held_brain.forceMove(dropspot) held_brain = null +/obj/item/mmi/proc/become_occupied(var/new_icon) + icon_state = new_icon + if(radio) + radio_action.ApplyIcon() -/obj/item/mmi/radio_enabled - name = "Radio-enabled Man-Machine Interface" - desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio." - origin_tech = "biotech=2;programming=3;engineering=2;magnets=2" +/obj/item/mmi/examine(mob/user) + . = ..() + if(radio) + to_chat(user, "A radio is installed on [src].") - var/obj/item/radio/radio = null//Let's give it a radio. +/obj/item/mmi/proc/install_radio() + radio = new(src) + radio.broadcasting = TRUE + radio_action = new(radio, src) + if(brainmob && brainmob.loc == src) + radio_action.Grant(brainmob) -/obj/item/mmi/radio_enabled/New() - ..() - radio = new(src)//Spawns a radio inside the MMI. - radio.broadcasting = 1//So it's broadcasting from the start. +/obj/item/mmi/proc/uninstall_radio() + QDEL_NULL(radio) + QDEL_NULL(radio_action) -/obj/item/mmi/radio_enabled/verb/Toggle_Listening() - set name = "Toggle Listening" - set desc = "Toggle listening channel on or off." - set category = "MMI" - set src = usr.loc - set popup_menu = 0 +/datum/action/generic/configure_mmi_radio + name = "Configure MMI Radio" + desc = "Configure the radio installed in your MMI." + check_flags = AB_CHECK_CONSCIOUS + procname = "ui_interact" + var/obj/item/mmi = null - if(brainmob.stat) - to_chat(brainmob, "Can't do that while incapacitated or dead.") +/datum/action/generic/configure_mmi_radio/New(var/Target, var/obj/item/mmi/M) + . = ..() + mmi = M - radio.listening = radio.listening==1 ? 0 : 1 - to_chat(brainmob, "Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.") +/datum/action/generic/configure_mmi_radio/Destroy() + mmi = null + return ..() + +/datum/action/generic/configure_mmi_radio/ApplyIcon(obj/screen/movable/action_button/current_button) + // A copy/paste of the item action icon code + current_button.overlays.Cut() + if(target) + var/obj/item/I = mmi + var/old_layer = I.layer + var/old_plane = I.plane + I.layer = 21 + I.plane = HUD_PLANE + current_button.overlays += I + I.layer = old_layer + I.plane = old_plane /obj/item/mmi/emp_act(severity) if(!brainmob) @@ -168,8 +229,22 @@ borg.mmi = null QDEL_NULL(brainmob) QDEL_NULL(held_brain) + QDEL_NULL(radio) + QDEL_NULL(radio_action) return ..() +// These two procs are important for when an MMI pilots a mech +// (Brainmob "enters/leaves" the MMI when piloting) +// Also neatly handles basically every case where a brain +// is inserted or removed from an MMI +/obj/item/mmi/Entered(atom/movable/A) + if(radio && istype(A, /mob/living/carbon/brain)) + radio_action.Grant(A) + +/obj/item/mmi/Exited(atom/movable/A) + if(radio && istype(A, /mob/living/carbon/brain)) + radio_action.Remove(A) + /obj/item/mmi/syndie name = "Syndicate Man-Machine Interface" desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores." @@ -190,10 +265,25 @@ forceMove(holder) holder.stored_mmi = src holder.update_from_mmi() - if(istype(src, /obj/item/mmi/posibrain)) - holder.robotize() if(brainmob && brainmob.mind) brainmob.mind.transfer_to(H) holder.insert(H) return 1 + +// As a synthetic, the only limit on visibility is view range +/obj/item/mmi/contents_nano_distance(var/src_object, var/mob/living/user) + if((src_object in view(src)) && get_dist(src_object, src) <= user.client.view) + return STATUS_INTERACTIVE // interactive (green visibility) + return user.shared_living_nano_distance(src_object) + +// For now the only thing that is helped by this is radio access +// Later a more intricate system for MMI UI interaction can be established +/obj/item/mmi/contents_nano_interact(var/src_object, var/mob/living/user) + if(!istype(user, /mob/living/carbon/brain)) + log_runtime(EXCEPTION("Somehow a non-brain mob is inside an MMI!"), user) + return ..() + var/mob/living/carbon/brain/BM = user + if(BM.container == src && src_object == radio) + return STATUS_INTERACTIVE + return ..() diff --git a/code/modules/mob/living/carbon/brain/MMI_radio.dm b/code/modules/mob/living/carbon/brain/MMI_radio.dm new file mode 100644 index 00000000000..6eeaa44a42c --- /dev/null +++ b/code/modules/mob/living/carbon/brain/MMI_radio.dm @@ -0,0 +1,5 @@ +/obj/item/mmi_radio_upgrade + name = "MMI radio upgrade" + desc = "Enables radio capability on MMIs when either installed directly on the MMI, or through a cyborg's chassis." + icon = 'icons/obj/module.dmi' + icon_state = "cyborg_upgrade1" diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index 82e062246b6..c64318d804b 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -84,12 +84,12 @@ I'm using this for Stat to give it a more nifty interface to work with if(container) var/obj/item/mmi/M = container if(istype(M) && M.held_brain) - return M.held_brain.dna.get_species_name() + return M.held_brain.dna.species.name else return "Artificial Life" if(istype(loc, /obj/item/organ/internal/brain)) var/obj/item/organ/internal/brain/B = loc - return B.dna.get_species_name() + return B.dna.species.name /mob/living/carbon/brain/Stat() ..() diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 8c02bac91d1..0a8f6fb3b83 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -14,7 +14,7 @@ organ_tag = "brain" parent_organ = "head" slot = "brain" - vital = 1 + vital = TRUE hidden_pain = TRUE //the brain has no pain receptors, and brain damage is meant to be a stealthy damage type. var/mmi_icon = 'icons/obj/assemblies.dmi' var/mmi_icon_state = "mmi_full" diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm deleted file mode 100644 index f5e575dccaf..00000000000 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ /dev/null @@ -1,205 +0,0 @@ -/obj/item/mmi/posibrain - name = "positronic brain" - desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." - icon = 'icons/obj/assemblies.dmi' - icon_state = "posibrain" - w_class = WEIGHT_CLASS_NORMAL - origin_tech = "biotech=3;programming=3;plasmatech=2" - - var/searching = 0 - var/askDelay = 10 * 60 * 1 - //var/mob/living/carbon/brain/brainmob = null - var/list/ghost_volunteers[0] - req_access = list(access_robotics) - mecha = null//This does not appear to be used outside of reference in mecha.dm. - var/silenced = 0 //if set to 1, they can't talk. - var/next_ping_at = 0 - -/obj/item/mmi/posibrain/examine(mob/user) - if(..(user, 1)) - to_chat(user, "Its speaker is turned [silenced ? "off" : "on"].") - -/obj/item/mmi/posibrain/attack_self(mob/user) - if(brainmob && !brainmob.key && searching == 0) - //Start the process of searching for a new user. - to_chat(user, "You carefully locate the manual activation switch and start the positronic brain's boot process.") - icon_state = "posibrain-searching" - ghost_volunteers.Cut() - searching = 1 - request_player() - spawn(600) - if(ghost_volunteers.len) - var/mob/dead/observer/O - while(!istype(O) && ghost_volunteers.len) - O = pick_n_take(ghost_volunteers) - if(istype(O) && check_observer(O)) - transfer_personality(O) - reset_search() - else - silenced = !silenced - to_chat(user, "You toggle the speaker [silenced ? "off" : "on"].") - if(brainmob && brainmob.key) - to_chat(brainmob, "Your internal speaker has been toggled [silenced ? "off" : "on"].") - -/obj/item/mmi/posibrain/proc/request_player() - for(var/mob/dead/observer/O in player_list) - if(check_observer(O)) - to_chat(O, "\A [src] has been activated. (Teleport | Sign Up)") - -/obj/item/mmi/posibrain/proc/check_observer(var/mob/dead/observer/O) - if(cannotPossess(O)) - return 0 - if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) - return 0 - if(!O.can_reenter_corpse) - return 0 - if(O.client) - return 1 - return 0 - -/obj/item/mmi/posibrain/proc/question(var/client/C) - spawn(0) - if(!C) return - var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round") - if(!C || brainmob.key || 0 == searching) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. - if(response == "Yes") - transfer_personality(C.mob) - else if(response == "Never for this round") - C.prefs.be_special -= ROLE_POSIBRAIN - -// This should not ever happen, but let's be safe -/obj/item/mmi/posibrain/dropbrain(var/turf/dropspot) - log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain."), src) - return - -/obj/item/mmi/posibrain/transfer_identity(var/mob/living/carbon/H) - name = "positronic brain ([H])" - if(isnull(brainmob.dna)) - brainmob.dna = H.dna.Clone() - brainmob.name = brainmob.dna.real_name - brainmob.real_name = brainmob.name - brainmob.timeofhostdeath = H.timeofdeath - brainmob.stat = CONSCIOUS - if(brainmob.mind) - brainmob.mind.assigned_role = "Positronic Brain" - if(H.mind) - H.mind.transfer_to(brainmob) - to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a metal cube.") - icon_state = "posibrain-occupied" - return - -/obj/item/mmi/posibrain/proc/transfer_personality(var/mob/candidate) - src.searching = 0 - src.brainmob.key = candidate.key - src.name = "positronic brain ([src.brainmob.name])" - - to_chat(src.brainmob, "You are a positronic brain, brought into existence on [station_name()].") - to_chat(src.brainmob, "As a synthetic intelligence, you answer to all crewmembers, as well as the AI.") - to_chat(src.brainmob, "Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.") - src.brainmob.mind.assigned_role = "Positronic Brain" - - var/turf/T = get_turf_or_move(src.loc) - for(var/mob/M in viewers(T)) - M.show_message("The positronic brain chimes quietly.") - icon_state = "posibrain-occupied" - -/obj/item/mmi/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. - if(src.brainmob && src.brainmob.key) return - - src.searching = 0 - icon_state = "posibrain" - - var/turf/T = get_turf_or_move(src.loc) - for(var/mob/M in viewers(T)) - M.show_message("The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?") - -/obj/item/mmi/posibrain/Topic(href,href_list) - if("signup" in href_list) - var/mob/dead/observer/O = locate(href_list["signup"]) - if(!O) return - volunteer(O) - -/obj/item/mmi/posibrain/proc/volunteer(var/mob/dead/observer/O) - if(!searching) - to_chat(O, "Not looking for a ghost, yet.") - return - if(!istype(O)) - to_chat(O, "Error.") - return - if(O in ghost_volunteers) - to_chat(O, "Removed from registration list.") - ghost_volunteers.Remove(O) - return - if(!check_observer(O)) - to_chat(O, "You cannot be \a [src].") - return - if(cannotPossess(O)) - to_chat(O, "Upon using the antagHUD you forfeited the ability to join the round.") - return - if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) - to_chat(O, "You are job banned from this role.") - return - to_chat(O., "You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.") - ghost_volunteers.Add(O) - - -/obj/item/mmi/posibrain/examine(mob/user) - to_chat(user, "*---------*") - if(!..(user)) - to_chat(user, "*---------*") - return - - var/msg = "" - - if(src.brainmob && src.brainmob.key) - switch(src.brainmob.stat) - if(CONSCIOUS) - if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk - if(UNCONSCIOUS) msg += "It doesn't seem to be responsive.\n" - if(DEAD) msg += "It appears to be completely inactive.\n" - else - msg += "It appears to be completely inactive.\n" - msg += "*---------*" - to_chat(user, msg) - -/obj/item/mmi/posibrain/emp_act(severity) - if(!src.brainmob) - return - else - switch(severity) - if(1) - src.brainmob.emp_damage += rand(20,30) - if(2) - src.brainmob.emp_damage += rand(10,20) - if(3) - src.brainmob.emp_damage += rand(0,10) - ..() - -/obj/item/mmi/posibrain/New() - src.brainmob = new(src) - src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]" - src.brainmob.real_name = src.brainmob.name - src.brainmob.loc = src - src.brainmob.container = src - src.brainmob.stat = 0 - src.brainmob.SetSilence(0) - dead_mob_list -= src.brainmob - - ..() - -/obj/item/mmi/posibrain/attack_ghost(var/mob/dead/observer/O) - if(searching) - volunteer(O) - return - if(brainmob && brainmob.key) - return // No point pinging a posibrain with a player already inside - if(check_observer(O) && (world.time >= next_ping_at)) - next_ping_at = world.time + (20 SECONDS) - playsound(get_turf(src), 'sound/items/posiping.ogg', 80, 0) - var/turf/T = get_turf_or_move(src.loc) - for(var/mob/M in viewers(T)) - M.show_message("The positronic brain pings softly.") - -/obj/item/mmi/posibrain/ipc - desc = "A cube of shining metal, four inches to a side and covered in shallow grooves. The speaker switch is set to 'off'." - silenced = 1 diff --git a/code/modules/mob/living/carbon/brain/robotic_brain.dm b/code/modules/mob/living/carbon/brain/robotic_brain.dm new file mode 100644 index 00000000000..ea83ab90206 --- /dev/null +++ b/code/modules/mob/living/carbon/brain/robotic_brain.dm @@ -0,0 +1,231 @@ +/obj/item/mmi/robotic_brain + name = "robotic brain" + desc = "An advanced circuit, capable of housing a non-sentient synthetic intelligence." + icon = 'icons/obj/module.dmi' + icon_state = "boris_blank" + var/blank_icon = "boris_blank" + var/searching_icon = "boris_recharging" + var/occupied_icon = "boris" + w_class = WEIGHT_CLASS_NORMAL + origin_tech = "biotech=3;programming=3;plasmatech=2" + + var/searching = FALSE + var/askDelay = 10 * 60 * 1 + //var/mob/living/carbon/brain/brainmob = null + var/list/ghost_volunteers[0] + req_access = list(access_robotics) + mecha = null//This does not appear to be used outside of reference in mecha.dm. + var/silenced = FALSE //if TRUE, they can't talk. + var/next_ping_at = 0 + var/requires_master = TRUE + var/mob/living/carbon/human/imprinted_master = null + var/ejected_flavor_text = "circuit" + +/obj/item/mmi/robotic_brain/Destroy() + imprinted_master = null + return ..() + +/obj/item/mmi/robotic_brain/attack_self(mob/user) + if(requires_master && !imprinted_master) + to_chat(user, "You press your thumb on [src] and imprint your user information.") + imprinted_master = user + return + if(brainmob && !brainmob.key && !searching) + //Start the process of searching for a new user. + to_chat(user, "You carefully locate the manual activation switch and start [src]'s boot process.") + icon_state = searching_icon + ghost_volunteers.Cut() + searching = TRUE + request_player() + spawn(600) + if(ghost_volunteers.len) + var/mob/dead/observer/O + while(!istype(O) && ghost_volunteers.len) + O = pick_n_take(ghost_volunteers) + if(istype(O) && check_observer(O)) + transfer_personality(O) + reset_search() + else + silenced = !silenced + to_chat(user, "You toggle the speaker [silenced ? "off" : "on"].") + if(brainmob && brainmob.key) + to_chat(brainmob, "Your internal speaker has been toggled [silenced ? "off" : "on"].") + +/obj/item/mmi/robotic_brain/proc/request_player() + for(var/mob/dead/observer/O in player_list) + if(check_observer(O)) + to_chat(O, "\A [src] has been activated. (Teleport | Sign Up)") + +/obj/item/mmi/robotic_brain/proc/check_observer(mob/dead/observer/O) + if(cannotPossess(O)) + return FALSE + if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) + return FALSE + if(!O.can_reenter_corpse) + return FALSE + if(O.client) + return TRUE + return FALSE + +/obj/item/mmi/robotic_brain/proc/question(client/C) + spawn(0) + if(!C) + return + var/response = alert(C, "Someone is requesting a personality for a [src]. Would you like to play as one?", "[src] request", "Yes", "No", "Never for this round") + if(!C || brainmob.key || !searching) + return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. + if(response == "Yes") + transfer_personality(C.mob) + else if(response == "Never for this round") + C.prefs.be_special -= ROLE_POSIBRAIN + +// This should not ever happen, but let's be safe +/obj/item/mmi/robotic_brain/dropbrain(turf/dropspot) + log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain."), src) + +/obj/item/mmi/robotic_brain/transfer_identity(mob/living/carbon/H) + name = "[src] ([H])" + if(isnull(brainmob.dna)) + brainmob.dna = H.dna.Clone() + brainmob.name = brainmob.dna.real_name + brainmob.real_name = brainmob.name + brainmob.timeofhostdeath = H.timeofdeath + brainmob.stat = CONSCIOUS + if(brainmob.mind) + brainmob.mind.assigned_role = "Positronic Brain" + if(H.mind) + H.mind.transfer_to(brainmob) + to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [ejected_flavor_text].") + become_occupied(occupied_icon) + if(radio) + radio_action.ApplyIcon() + +/obj/item/mmi/robotic_brain/attempt_become_organ(obj/item/organ/external/parent, mob/living/carbon/human/H) + if(..()) + if(imprinted_master) + to_chat(H, "You are permanently imprinted to [imprinted_master], obey [imprinted_master]'s every order and assist [imprinted_master.p_them()] in completing [imprinted_master.p_their()] goals at any cost.") + + +/obj/item/mmi/robotic_brain/proc/transfer_personality(mob/candidate) + searching = FALSE + brainmob.key = candidate.key + name = "[src] ([brainmob.name])" + + to_chat(brainmob, "You are a [src], brought into existence on [station_name()].") + to_chat(brainmob, "As a non-sentient synthetic intelligence, you answer to [imprinted_master], unless otherwise placed inside of a lawed synthetic structure or mech.") + to_chat(brainmob, "Remember, the purpose of your existence is to serve [imprinted_master]'s every word, unless lawed or placed into a mech in the future.") + brainmob.mind.assigned_role = "Positronic Brain" + + visible_message("[src] chimes quietly.") + become_occupied(occupied_icon) + + +/obj/item/mmi/robotic_brain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. + if(brainmob && brainmob.key) + return + + searching = FALSE + icon_state = blank_icon + + visible_message("[src] buzzes quietly as the light fades out. Perhaps you could try again?") + +/obj/item/mmi/robotic_brain/Topic(href, href_list) + if("signup" in href_list) + var/mob/dead/observer/O = locate(href_list["signup"]) + if(!O) + return + volunteer(O) + +/obj/item/mmi/robotic_brain/proc/volunteer(mob/dead/observer/O) + if(!searching) + to_chat(O, "Not looking for a ghost, yet.") + return + if(!istype(O)) + to_chat(O, "Error.") + return + if(O in ghost_volunteers) + to_chat(O, "Removed from registration list.") + ghost_volunteers.Remove(O) + return + if(!check_observer(O)) + to_chat(O, "You cannot be \a [src].") + return + if(cannotPossess(O)) + to_chat(O, "Upon using the antagHUD you forfeited the ability to join the round.") + return + if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) + to_chat(O, "You are job banned from this role.") + return + to_chat(O., "You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.") + ghost_volunteers.Add(O) + + +/obj/item/mmi/robotic_brain/examine(mob/user) + to_chat(user, "Its speaker is turned [silenced ? "off" : "on"].") + to_chat(user, "*---------*") + . = ..() + if(!.) + to_chat(user, "*---------*") + return + + var/list/msg = list("") + + if(brainmob && brainmob.key) + switch(brainmob.stat) + if(CONSCIOUS) + if(!brainmob.client) + msg += "It appears to be in stand-by mode.\n" //afk + if(UNCONSCIOUS) + msg += "It doesn't seem to be responsive.\n" + if(DEAD) + msg += "It appears to be completely inactive.\n" + else + msg += "It appears to be completely inactive.\n" + msg += "*---------*" + to_chat(user, msg.Join("")) + +/obj/item/mmi/robotic_brain/emp_act(severity) + if(!brainmob) + return + switch(severity) + if(1) + brainmob.emp_damage += rand(20, 30) + if(2) + brainmob.emp_damage += rand(10, 20) + if(3) + brainmob.emp_damage += rand(0, 10) + ..() + +/obj/item/mmi/robotic_brain/New() + brainmob = new(src) + brainmob.name = "[pick(list("PBU", "HIU", "SINA", "ARMA", "OSI"))]-[rand(100, 999)]" + brainmob.real_name = brainmob.name + brainmob.forceMove(src) + brainmob.container = src + brainmob.stat = CONSCIOUS + brainmob.SetSilence(0) + dead_mob_list -= brainmob + ..() + +/obj/item/mmi/robotic_brain/attack_ghost(mob/dead/observer/O) + if(searching) + volunteer(O) + return + if(brainmob && brainmob.key) + return // No point pinging a posibrain with a player already inside + if(check_observer(O) && (world.time >= next_ping_at)) + next_ping_at = world.time + (20 SECONDS) + playsound(get_turf(src), 'sound/items/posiping.ogg', 80, 0) + visible_message("[src] pings softly.") + +/obj/item/mmi/robotic_brain/positronic + name = "positronic brain" + icon = 'icons/obj/assemblies.dmi' + icon_state = "posibrain" + blank_icon = "posibrain" + searching_icon = "posibrain-searching" + occupied_icon = "posibrain-occupied" + desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." + silenced = TRUE + requires_master = FALSE + ejected_flavor_text = "metal cube" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm index e8e2dd00c45..907a2e4862d 100644 --- a/code/modules/mob/living/carbon/brain/say.dm +++ b/code/modules/mob/living/carbon/brain/say.dm @@ -2,7 +2,7 @@ /mob/living/carbon/brain/say(var/message, var/datum/language/speaking = null) if(!can_speak(warning = TRUE)) return - + if(prob(emp_damage * 4)) if(prob(10)) //10% chance to drop the message entirely return @@ -10,21 +10,21 @@ message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher ..(message) - + /mob/living/carbon/brain/whisper(message as text) if(!can_speak(warning = TRUE)) return ..() - + /mob/living/carbon/brain/can_speak(var/warning = FALSE) . = ..() if(!istype(container, /obj/item/mmi)) . = FALSE - else if(istype(container, /obj/item/mmi/posibrain)) - var/obj/item/mmi/posibrain/P = container - if(P && P.silenced) + else if(istype(container, /obj/item/mmi/robotic_brain)) + var/obj/item/mmi/robotic_brain/R = container + if(R && R.silenced) if(warning) to_chat(usr, "You cannot speak, as your internal speaker is turned off.") . = FALSE @@ -41,12 +41,10 @@ if(metalgear.radio) radio_worked = metalgear.radio.talk_into(src, message, message_mode, verb, speaking) - else if(!radio_worked && istype(c, /obj/item/mmi/radio_enabled)) - var/obj/item/mmi/radio_enabled/R = c - if(R.radio) - radio_worked = R.radio.talk_into(src, message, message_mode, verb, speaking) + else if(!radio_worked && c.radio) + radio_worked = c.radio.talk_into(src, message, message_mode, verb, speaking) return radio_worked if("whisper") whisper_say(message, speaking, alt_name) return 1 - else return 0 \ No newline at end of file + else return 0 diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index aa890cbd17f..4b00bf832c8 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -342,7 +342,7 @@ AdjustEyeBlurry(damage * rand(3, 6)) if(E.damage > (E.min_bruised_damage + E.min_broken_damage) / 2) - if(!(E.status & ORGAN_ROBOT)) + if(!E.is_robotic()) to_chat(src, "Your eyes start to burn badly!") else //snowflake conditions piss me off for the record to_chat(src, "The flash blinds you!") @@ -382,7 +382,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, if(!ventcrawler) if(ishuman(src)) var/mob/living/carbon/human/H = src - ventcrawlerlocal = H.species.ventcrawler + ventcrawlerlocal = H.dna.species.ventcrawler if(!ventcrawlerlocal) return diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 80b871e7996..d19051692ca 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -3,20 +3,9 @@ AC.flags = flags AC.ui_interact(user, state = state) -/mob/living/carbon/human/proc/change_species(var/new_species) - if(!new_species || species == new_species || !(new_species in all_species)) - return - - set_species(new_species, null, 1) - reset_hair() - if(species.bodyflags & HAS_MARKINGS) - reset_markings() - - return 1 - /mob/living/carbon/human/proc/change_gender(var/new_gender, var/update_dna = 1) var/obj/item/organ/external/head/H = bodyparts_by_name["head"] - if(gender == new_gender || (gender == PLURAL && species.has_gender)) + if(gender == new_gender || (gender == PLURAL && dna.species.has_gender)) return gender = new_gender @@ -129,7 +118,7 @@ /mob/living/carbon/human/proc/change_alt_head(var/alternate_head) var/obj/item/organ/external/head/H = get_organ("head") - if(!H || H.alt_head == alternate_head || (H.status & ORGAN_ROBOT) || (!(species.bodyflags & HAS_ALT_HEADS) && alternate_head != "None") || !(alternate_head in alt_heads_list)) + if(!H || H.alt_head == alternate_head || H.is_robotic() || (!(dna.species.bodyflags & HAS_ALT_HEADS) && alternate_head != "None") || !(alternate_head in alt_heads_list)) return H.alt_head = alternate_head @@ -296,7 +285,7 @@ /mob/living/carbon/human/proc/change_skin_color(var/colour = "#000000") - if(colour == skin_colour || !(species.bodyflags & HAS_SKIN_COLOR)) + if(colour == skin_colour || !(dna.species.bodyflags & HAS_SKIN_COLOR)) return skin_colour = colour @@ -306,7 +295,7 @@ return 1 /mob/living/carbon/human/proc/change_skin_tone(var/tone) - if(s_tone == tone || !((species.bodyflags & HAS_SKIN_TONE) || (species.bodyflags & HAS_ICON_SKIN_TONE))) + if(s_tone == tone || !((dna.species.bodyflags & HAS_SKIN_TONE) || (dna.species.bodyflags & HAS_ICON_SKIN_TONE))) return s_tone = tone @@ -321,8 +310,8 @@ /mob/living/carbon/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list()) var/list/valid_species = new() - for(var/current_species_name in all_species) - var/datum/species/current_species = all_species[current_species_name] + for(var/current_species_name in GLOB.all_species) + var/datum/species/current_species = GLOB.all_species[current_species_name] if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it! if(whitelist.len && !(current_species_name in whitelist)) @@ -350,16 +339,16 @@ continue if((H.gender == MALE && S.gender == FEMALE) || (H.gender == FEMALE && S.gender == MALE)) continue - if(H.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... + if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] - if((H.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. + if((H.dna.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_hairstyles += hairstyle //Give them their hairstyles if they do. else if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. But if the user has a robotic humanoid head and the hairstyle can fit humans, let them use it as a wig. */ valid_hairstyles += hairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(H.species.name in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. + if(H.dna.species.name in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. valid_hairstyles += hairstyle return valid_hairstyles @@ -378,17 +367,17 @@ continue if((H.gender == MALE && S.gender == FEMALE) || (H.gender == FEMALE && S.gender == MALE)) continue - if(H.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... + if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] - if(H.species.name in S.species_allowed) //If this is a facial hair style native to the user's species... - if((H.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. + if(H.dna.species.name in S.species_allowed) //If this is a facial hair style native to the user's species... + if((H.dna.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_facial_hairstyles += facialhairstyle //Give them their facial hairstyles if they do. else if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the facial hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. But if the user has a robotic humanoid head and the facial hairstyle can fit humans, let them use it as a wig. */ valid_facial_hairstyles += facialhairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(H.species.name in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list. + if(H.dna.species.name in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list. valid_facial_hairstyles += facialhairstyle return valid_facial_hairstyles @@ -402,7 +391,7 @@ for(var/head_accessory in head_accessory_styles_list) var/datum/sprite_accessory/S = head_accessory_styles_list[head_accessory] - if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. + if(!(H.dna.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. continue valid_head_accessories += head_accessory @@ -421,7 +410,7 @@ continue if(S.marking_location != location) //If the marking isn't for the location we desire, skip. continue - if(!(species.name in S.species_allowed)) //If the user is not of a species the marking style allows, skip it. Otherwise, add it to the list. + if(!(dna.species.name in S.species_allowed)) //If the user is not of a species the marking style allows, skip it. Otherwise, add it to the list. continue if(location == "tail") if(!body_accessory) @@ -432,7 +421,7 @@ continue if(location == "head") var/datum/sprite_accessory/body_markings/head/M = marking_styles_list[S.name] - if(H.species.bodyflags & ALL_RPARTS)//If the user is a species that can have a robotic head... + if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species that can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] if(!(S.models_allowed && (robohead.company in S.models_allowed))) //Make sure they don't get markings incompatible with their head. continue @@ -456,7 +445,7 @@ if(!istype(A)) valid_body_accessories["None"] = "None" //The only null entry should be the "None" option. continue - if(species.name in A.allowed_species) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list. + if(dna.species.name in A.allowed_species) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list. valid_body_accessories += B return valid_body_accessories @@ -469,7 +458,7 @@ valid_alt_heads["None"] = alt_heads_list["None"] //The only null entry should be the "None" option, and there should always be a "None" option. for(var/alternate_head in alt_heads_list) var/datum/sprite_accessory/alt_heads/head = alt_heads_list[alternate_head] - if(!(H.species.name in head.species_allowed)) + if(!(H.dna.species.name in head.species_allowed)) continue valid_alt_heads += alternate_head diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 37749c0dd76..bdca496d256 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -62,7 +62,7 @@ animation.master = src flick("dust-h", animation) - new species.remains_type(get_turf(src)) + new dna.species.remains_type(get_turf(src)) spawn(15) if(animation) qdel(animation) @@ -103,8 +103,8 @@ set_heartattack(FALSE) //Handle species-specific deaths. - if(species) - species.handle_death(src) + if(dna.species) + dna.species.handle_death(src) callHook("death", list(src, gibbed)) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index be46cc9fa7d..c1eb8641820 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -29,34 +29,42 @@ switch(act) //Cooldown-inducing emotes if("ping", "pings", "buzz", "buzzes", "beep", "beeps", "yes", "no", "buzz2") - if(species.name == "Machine") //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise. + var/found_machine_head = FALSE + if(ismachine(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - else //Everyone else fails, skip the emote attempt - return + found_machine_head = TRUE + else + var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises + if(H && H.is_robotic()) + on_CD = handle_emote_CD() + found_machine_head = TRUE + + if(!found_machine_head) //Everyone else fails, skip the emote attempt + return //Everyone else fails, skip the emote attempt if("drone","drones","hum","hums","rumble","rumbles") - if(get_species() == "Drask") //Only Drask can make whale noises + if(isdrask(src)) //Only Drask can make whale noises on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm else return if("howl", "howls") - if(get_species() == "Vulpkanin") //Only Vulpkanin can howl + if(isvulpkanin(src)) //Only Vulpkanin can howl on_CD = handle_emote_CD(100) else return if("growl", "growls") - if(get_species() == "Vulpkanin") //Only Vulpkanin can growl + if(isvulpkanin(src)) //Only Vulpkanin can growl on_CD = handle_emote_CD() else return if("squish", "squishes") var/found_slime_bodypart = 0 - if(get_species() == "Slime People") //Only Slime People can squish + if(isslimeperson(src)) //Only Slime People can squish on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' found_slime_bodypart = 1 else for(var/obj/item/organ/external/L in bodyparts) // if your limbs are squishy you can squish too! - if(L.dna.species in list("Slime People")) + if(istype(L.dna.species, /datum/species/slime)) on_CD = handle_emote_CD() found_slime_bodypart = 1 break @@ -65,31 +73,31 @@ return if("clack", "clacks") - if(get_species() == "Kidan") //Only Kidan can clack and rightfully so. + if(iskidan(src)) //Only Kidan can clack and rightfully so. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return if("click", "clicks") - if(get_species() == "Kidan") //Only Kidan can click and rightfully so. + if(iskidan(src)) //Only Kidan can click and rightfully so. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return if("creaks", "creak") - if(get_species() == "Diona") //Only Dionas can Creaks. + if(isdiona(src)) //Only Dionas can Creaks. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return if("hiss", "hisses") - if(get_species() == "Unathi") //Only Unathi can hiss. + if(isunathi(src)) //Only Unathi can hiss. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return if("quill", "quills") - if(get_species() == "Vox") //Only Vox can rustle their quills. + if(isvox(src)) //Only Vox can rustle their quills. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return @@ -225,7 +233,7 @@ message = "[src] starts wagging [p_their()] tail." start_tail_wagging(1) - else if(species.bodyflags & TAIL_WAGGING) + else if(dna.species.bodyflags & TAIL_WAGGING) if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) message = "[src] starts wagging [p_their()] tail." start_tail_wagging(1) @@ -236,7 +244,7 @@ m_type = 1 if("swag", "swags") - if(species.bodyflags & TAIL_WAGGING || body_accessory) + if(dna.species.bodyflags & TAIL_WAGGING || body_accessory) message = "[src] stops wagging [p_their()] tail." stop_tail_wagging(1) else @@ -431,11 +439,11 @@ message = "[src] coughs!" m_type = 2 if(gender == FEMALE) - if(species.female_cough_sounds) - playsound(src, pick(species.female_cough_sounds), 120) + if(dna.species.female_cough_sounds) + playsound(src, pick(dna.species.female_cough_sounds), 120) else - if(species.male_cough_sounds) - playsound(src, pick(species.male_cough_sounds), 120) + if(dna.species.male_cough_sounds) + playsound(src, pick(dna.species.male_cough_sounds), 120) else message = "[src] makes a strong noise." m_type = 2 @@ -479,7 +487,7 @@ m_type = 2 if("deathgasp", "deathgasps") - message = "[src] [replacetext(species.death_message, "their", p_their())]" + message = "[src] [replacetext(dna.species.death_message, "their", p_their())]" m_type = 1 if("giggle", "giggles") @@ -676,9 +684,9 @@ if(!muzzled) message = "[src] sneezes." if(gender == FEMALE) - playsound(src, species.female_sneeze_sound, 70) + playsound(src, dna.species.female_sneeze_sound, 70) else - playsound(src, species.male_sneeze_sound, 70) + playsound(src, dna.species.male_sneeze_sound, 70) m_type = 2 else message = "[src] makes a strange noise." @@ -784,12 +792,12 @@ m_type = 1 else if(!muzzled) - message = "[src] [species.scream_verb][M ? " at [M]" : ""]!" + message = "[src] [dna.species.scream_verb][M ? " at [M]" : ""]!" m_type = 2 if(gender == FEMALE) - playsound(loc, "[species.female_scream_sound]", 80, 1, frequency = get_age_pitch()) + playsound(loc, "[dna.species.female_scream_sound]", 80, 1, frequency = get_age_pitch()) else - playsound(loc, "[species.male_scream_sound]", 80, 1, frequency = get_age_pitch()) //default to male screams if no gender is present. + playsound(loc, "[dna.species.male_scream_sound]", 80, 1, frequency = get_age_pitch()) //default to male screams if no gender is present. else message = "[src] makes a very loud noise[M ? " at [M]" : ""]." @@ -890,9 +898,7 @@ + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-(none)/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-(none)/mob, swag(s), tremble(s), twitch(es), twitch(es)_s," \ + " wag(s), wave(s), whimper(s), wink(s), yawn(s), quill(s)" - switch(species.name) - if("Machine") - emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob" + switch(dna.species.name) if("Drask") emotelist += "\nDrask specific emotes :- drone(s)-(none)/mob, hum(s)-(none)/mob, rumble(s)-(none)/mob" if("Kidan") @@ -906,11 +912,18 @@ if("Diona") emotelist += "\nDiona specific emotes :- creak(s)" - if (species.name == "Slime People") + if(ismachine(src)) + emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob" + else + var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises + if(H && H.is_robotic()) + emotelist += "\nRobotic head specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob" + + if(isslimeperson(src)) emotelist += "\nSlime people specific emotes :- squish(es)-(none)/mob" else for(var/obj/item/organ/external/L in bodyparts) // if your limbs are squishy you can squish too! - if(L.dna.species in list("Slime People")) + if(istype(L.dna.species, /datum/species/slime)) emotelist += "\nSlime people body part specific emotes :- squish(es)-(none)/mob" break diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index ef352b5a8f8..a39d2843501 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -29,14 +29,12 @@ msg += "[bicon(icon(icon, dir=SOUTH))] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated msg += "[name]" - var/list/nospecies = list("Abductor", "Shadowling", "Neara", "Monkey", "Stok", "Farwa", "Wolpin") //species that won't show their race no matter what - - var/displayed_species = get_species() + var/displayed_species = dna.species.name for(var/obj/item/clothing/C in src) //Disguise checks if(C == src.head || C == src.wear_suit || C == src.wear_mask || C == src.w_uniform || C == src.belt || C == src.back) if(C.species_disguise) displayed_species = C.species_disguise - if(skipjumpsuit && skipface || (displayed_species in nospecies)) //either obscured or on the nospecies list + if(skipjumpsuit && skipface || (NO_EXAMINE in dna.species.species_traits)) //either obscured or on the nospecies list msg += "!\n" //omit the species when examining else if(displayed_species == "Slime People") //snowflakey because Slime People are defined as a plural msg += ", a slime person!\n" @@ -199,9 +197,9 @@ var/list/wound_flavor_text = list() var/list/is_destroyed = list() - for(var/organ_tag in species.has_limbs) + for(var/organ_tag in dna.species.has_limbs) - var/list/organ_data = species.has_limbs[organ_tag] + var/list/organ_data = dna.species.has_limbs[organ_tag] var/organ_descriptor = organ_data["descriptor"] is_destroyed["[organ_data["descriptor"]]"] = 1 @@ -210,7 +208,7 @@ wound_flavor_text["[organ_tag]"] = "[p_they(TRUE)] [p_are()] missing [p_their()] [organ_descriptor].\n" else if(!isSynthetic()) - if(E.status & ORGAN_ROBOT) + if(E.is_robotic()) wound_flavor_text["[E.limb_name]"] = "[p_they(TRUE)] [p_have()] a robotic [E.name]!\n" else if(E.status & ORGAN_SPLINTED) @@ -324,7 +322,7 @@ var/dodebug = auto.doing2string(auto.doing) var/interestdebug = auto.interest2string(auto.interest) msg += "[p_they(TRUE)] [p_are()] appears to be [interestdebug] and [dodebug].\n" - else if(species.show_ssd) + else if(dna.species.show_ssd) if(!key) msg += "[p_they(TRUE)] [p_are()] totally catatonic. The stresses of life in deep-space must have been too much for [p_them()]. Any recovery is unlikely.\n" else if(!client) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index cca71c1e8d6..1cf1a8bb942 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -4,10 +4,6 @@ voice_name = "unknown" icon = 'icons/mob/human.dmi' icon_state = "body_m_s" - - //why are these here and not in human_defines.dm - //var/list/hud_list[10] - var/datum/species/species //Contains icon generation and language information, set during New(). var/obj/item/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call. /mob/living/carbon/human/New(loc) @@ -15,21 +11,17 @@ log_runtime(EXCEPTION("human/New called with more than 1 argument (REPORT THIS ENTIRE RUNTIME TO A CODER)")) . = ..() -/mob/living/carbon/human/Initialize(mapload, new_species = null) +/mob/living/carbon/human/Initialize(mapload, datum/species/new_species = /datum/species/human) if(!dna) dna = new /datum/dna(null) // Species name is handled by set_species() - if(!species) - if(new_species) - set_species(new_species, 1, delay_icon_update = 1) - else - set_species(delay_icon_update = 1) + set_species(new_species, 1, delay_icon_update = 1, skip_same_check = TRUE) ..() - if(species) - real_name = species.get_random_name(gender) + if(dna.species) + real_name = dna.species.get_random_name(gender) name = real_name if(mind) mind.name = real_name @@ -74,79 +66,92 @@ status_flags = GODMODE|CANPUSH /mob/living/carbon/human/skrell/Initialize(mapload) - ..(mapload, "Skrell") + ..(mapload, /datum/species/skrell) /mob/living/carbon/human/tajaran/Initialize(mapload) - ..(mapload, "Tajaran") + ..(mapload, /datum/species/tajaran) /mob/living/carbon/human/vulpkanin/Initialize(mapload) - ..(mapload, "Vulpkanin") + ..(mapload, /datum/species/vulpkanin) /mob/living/carbon/human/unathi/Initialize(mapload) - ..(mapload, "Unathi") + ..(mapload, /datum/species/unathi) /mob/living/carbon/human/vox/Initialize(mapload) - ..(mapload, "Vox") + ..(mapload, /datum/species/vox) /mob/living/carbon/human/voxarmalis/Initialize(mapload) - ..(mapload, "Vox Armalis") + ..(mapload, /datum/species/vox/armalis) /mob/living/carbon/human/skeleton/Initialize(mapload) - ..(mapload, "Skeleton") + ..(mapload, /datum/species/skeleton) /mob/living/carbon/human/kidan/Initialize(mapload) - ..(mapload, "Kidan") + ..(mapload, /datum/species/kidan) /mob/living/carbon/human/plasma/Initialize(mapload) - ..(mapload, "Plasmaman") + ..(mapload, /datum/species/plasmaman) /mob/living/carbon/human/slime/Initialize(mapload) - ..(mapload, "Slime People") + ..(mapload, /datum/species/slime) /mob/living/carbon/human/grey/Initialize(mapload) - ..(mapload, "Grey") + ..(mapload, /datum/species/grey) /mob/living/carbon/human/abductor/Initialize(mapload) - ..(mapload, "Abductor") - -/mob/living/carbon/human/human/Initialize(mapload) - ..(mapload, "Human") + ..(mapload, /datum/species/abductor) /mob/living/carbon/human/diona/Initialize(mapload) - ..(mapload, "Diona") + ..(mapload, /datum/species/diona) /mob/living/carbon/human/machine/Initialize(mapload) - ..(mapload, "Machine") + ..(mapload, /datum/species/machine) + +/mob/living/carbon/human/machine/created + name = "Integrated Robotic Chassis" + +/mob/living/carbon/human/machine/created/Initialize(mapload) + ..() + rename_character(null, "Integrated Robotic Chassis ([rand(1, 9999)])") + update_dna() + for(var/obj/item/organ/external/E in bodyparts) + if(istype(E, /obj/item/organ/external/chest) || istype(E, /obj/item/organ/external/groin)) + continue + qdel(E) + for(var/obj/item/organ/O in internal_organs) + qdel(O) + regenerate_icons() + death() /mob/living/carbon/human/shadow/Initialize(mapload) - ..(mapload, "Shadow") + ..(mapload, /datum/species/shadow) /mob/living/carbon/human/golem/Initialize(mapload) - ..(mapload, "Golem") + ..(mapload, /datum/species/golem) /mob/living/carbon/human/wryn/Initialize(mapload) - ..(mapload, "Wryn") + ..(mapload, /datum/species/wryn) /mob/living/carbon/human/nucleation/Initialize(mapload) - ..(mapload, "Nucleation") + ..(mapload, /datum/species/nucleation) /mob/living/carbon/human/drask/Initialize(mapload) - ..(mapload, "Drask") + ..(mapload, /datum/species/drask) /mob/living/carbon/human/monkey/Initialize(mapload) - ..(mapload, "Monkey") + ..(mapload, /datum/species/monkey) /mob/living/carbon/human/farwa/Initialize(mapload) - ..(mapload, "Farwa") + ..(mapload, /datum/species/monkey/tajaran) /mob/living/carbon/human/wolpin/Initialize(mapload) - ..(mapload, "Wolpin") + ..(mapload, /datum/species/monkey/vulpkanin) /mob/living/carbon/human/neara/Initialize(mapload) - ..(mapload, "Neara") + ..(mapload, /datum/species/monkey/skrell) /mob/living/carbon/human/stok/Initialize(mapload) - ..(mapload, "Stok") + ..(mapload, /datum/species/monkey/unathi) /mob/living/carbon/human/Stat() ..() @@ -550,7 +555,7 @@ grant_death_vision() return - species.update_sight(src) + dna.species.update_sight(src) //Removed the horrible safety parameter. It was only being used by ninja code anyways. //Now checks siemens_coefficient of the affected area by default @@ -580,8 +585,8 @@ if(gloves) var/obj/item/clothing/gloves/G = gloves gloves_siemens_coeff = G.siemens_coefficient - if(species) - species_siemens_coeff = species.siemens_coeff + if(dna.species) + species_siemens_coeff = dna.species.siemens_coeff siemens_coeff = gloves_siemens_coeff * species_siemens_coeff if(undergoing_cardiac_arrest()) if(shock_damage * siemens_coeff >= 1 && prob(25)) @@ -1032,14 +1037,6 @@ /mob/living/carbon/human/proc/check_dna() dna.check_integrity(src) - return - -/mob/living/carbon/human/get_species() - - if(!species) - set_species() - - return species.name /mob/living/carbon/human/proc/play_xylophone() if(!src.xylophone) @@ -1065,7 +1062,7 @@ if(!affecting) . = 0 fail_msg = "[p_they(TRUE)] [p_are()] missing that limb." - else if(affecting.status & ORGAN_ROBOT) + else if(affecting.is_robotic()) . = 0 fail_msg = "That limb is robotic." else @@ -1140,9 +1137,9 @@ //Replacing lost limbs with the species default. var/mob/living/carbon/human/temp_holder - for(var/limb_type in H.species.has_limbs) + for(var/limb_type in H.dna.species.has_limbs) if(!(limb_type in H.bodyparts_by_name)) - var/list/organ_data = H.species.has_limbs[limb_type] + var/list/organ_data = H.dna.species.has_limbs[limb_type] var/limb_path = organ_data["path"] var/obj/item/organ/external/O = new limb_path(temp_holder) if(H.get_limb_by_name(O.name)) //Check to see if the user already has an limb with the same name as the 'missing limb'. If they do, skip regrowth. @@ -1155,8 +1152,8 @@ //Replacing lost organs with the species default. temp_holder = new /mob/living/carbon/human() - for(var/index in H.species.has_organ) - var/organ = H.species.has_organ[index] + for(var/index in H.dna.species.has_organ) + var/organ = H.dna.species.has_organ[index] if(!(organ in types_of_int_organs)) //If the mob is missing this particular organ... var/obj/item/organ/internal/I = new organ(temp_holder) //Create the organ inside our holder so we can check it before implantation. if(H.get_organ_slot(I.slot)) //Check to see if the user already has an organ in the slot the 'missing organ' belongs to. If they do, skip implantation. @@ -1173,7 +1170,7 @@ surgeries.Cut() //End all surgeries. update_revive() - if(species.name != "Skeleton" && (SKELETON in mutations)) + if(!isskeleton(src) && (SKELETON in mutations)) mutations.Remove(SKELETON) if(NOCLONE in mutations) mutations.Remove(NOCLONE) @@ -1236,7 +1233,7 @@ ..() /mob/living/carbon/human/generate_name() - name = species.makeName(gender,src) + name = dna.species.get_random_name(gender) real_name = name if(dna) dna.real_name = name @@ -1275,88 +1272,90 @@ else to_chat(usr, "[self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)].") -/mob/living/carbon/human/proc/set_species(var/new_species, var/default_colour, var/delay_icon_update = 0) - var/datum/species/oldspecies = species - var/datum/species/NS = all_species[new_species] - if(!dna) - if(!new_species) - new_species = "Human" - else - if(!new_species) - new_species = dna.species - else - dna.species = new_species - - if(species) - if(species.name && species.name == new_species) +/mob/living/carbon/human/proc/set_species(datum/species/new_species, default_colour, delay_icon_update = FALSE, skip_same_check = FALSE) + if(!skip_same_check) + if(dna.species.name == initial(new_species.name)) return - - if(species.language) - remove_language(species.language) - - if(species.default_language) - remove_language(species.default_language) - - if(gender == PLURAL && NS.has_gender) - change_gender(pick(MALE,FEMALE)) - species.handle_pre_change(src) - - species = all_species[new_species] + var/datum/species/oldspecies = dna.species if(oldspecies) + if(oldspecies.language) + remove_language(oldspecies.language) + + if(oldspecies.default_language) + remove_language(oldspecies.default_language) + + if(gender == PLURAL && oldspecies.has_gender) + change_gender(pick(MALE, FEMALE)) + if(oldspecies.default_genes.len) - oldspecies.handle_dna(src,1) // Remove any genes that belong to the old species + oldspecies.handle_dna(src, TRUE) // Remove any genes that belong to the old species - tail = species.tail + oldspecies.handle_pre_change(src) - maxHealth = species.total_health + dna.species = new new_species() - if(species.language) - add_language(species.language) + tail = dna.species.tail - if(species.default_language) - add_language(species.default_language) + maxHealth = dna.species.total_health - hunger_drain = species.hunger_drain - digestion_ratio = species.digestion_ratio + if(dna.species.language) + add_language(dna.species.language) - if(species.base_color && default_colour) + if(dna.species.default_language) + add_language(dna.species.default_language) + + hunger_drain = dna.species.hunger_drain + digestion_ratio = dna.species.digestion_ratio + + if(dna.species.base_color && default_colour) //Apply colour. - skin_colour = species.base_color + skin_colour = dna.species.base_color else skin_colour = "#000000" - if(!(species.bodyflags & HAS_SKIN_TONE)) + if(!(dna.species.bodyflags & HAS_SKIN_TONE)) s_tone = 0 - species.create_organs(src) + var/list/thing_to_check = list(slot_wear_mask, slot_head, slot_shoes, slot_gloves, slot_l_ear, slot_r_ear, slot_glasses, slot_l_hand, slot_r_hand) + var/list/kept_items[0] + + for(var/thing in thing_to_check) + var/obj/item/I = get_item_by_slot(thing) + if(I) + kept_items[I] = thing + + dna.species.create_organs(src) + + for(var/thing in kept_items) + equip_to_slot_or_del(thing, kept_items[thing]) //Handle default hair/head accessories for created mobs. var/obj/item/organ/external/head/H = get_organ("head") - if(species.default_hair) - H.h_style = species.default_hair + if(dna.species.default_hair) + H.h_style = dna.species.default_hair else H.h_style = "Bald" - if(species.default_fhair) - H.f_style = species.default_fhair + if(dna.species.default_fhair) + H.f_style = dna.species.default_fhair else H.f_style = "Shaved" - if(species.default_headacc) - H.ha_style = species.default_headacc + if(dna.species.default_headacc) + H.ha_style = dna.species.default_headacc else H.ha_style = "None" - if(species.default_hair_colour) + if(dna.species.default_hair_colour) //Apply colour. - H.hair_colour = species.default_hair_colour + H.hair_colour = dna.species.default_hair_colour else H.hair_colour = "#000000" - if(species.default_fhair_colour) - H.facial_colour = species.default_fhair_colour + if(dna.species.default_fhair_colour) + H.facial_colour = dna.species.default_fhair_colour else H.facial_colour = "#000000" - if(species.default_headacc_colour) - H.headacc_colour = species.default_headacc_colour + if(dna.species.default_headacc_colour) + H.headacc_colour = dna.species.default_headacc_colour else H.headacc_colour = "#000000" @@ -1364,43 +1363,39 @@ m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. body_accessory = null - if(!dna) - dna = new /datum/dna(null) - dna.species = species.name - dna.real_name = real_name + dna.real_name = real_name - species.handle_post_spawn(src) + dna.species.handle_post_spawn(src) - see_in_dark = species.get_resultant_darksight(src) + see_in_dark = dna.species.get_resultant_darksight(src) if(see_in_dark > 2) see_invisible = SEE_INVISIBLE_LEVEL_ONE else see_invisible = SEE_INVISIBLE_LIVING - species.handle_dna(src) //Give them whatever special dna business they got. + dna.species.handle_dna(src) //Give them whatever special dna business they got. update_client_colour(0) - spawn(0) - overlays.Cut() - update_mutantrace(1) - regenerate_icons() - if(!delay_icon_update) UpdateAppearance() - if(species) - return 1 + overlays.Cut() + update_mutantrace(1) + regenerate_icons() + + if(dna.species) + return TRUE else - return 0 + return FALSE /mob/living/carbon/human/get_default_language() if(default_language) return default_language - if(!species) + if(!dna.species) return null - return species.default_language ? all_languages[species.default_language] : null + return dna.species.default_language ? all_languages[dna.species.default_language] : null /mob/living/carbon/human/proc/bloody_doodle() set category = "IC" @@ -1467,7 +1462,7 @@ to_chat(src, "Where's your head at? Can't change your monitor/display without one.") return - if(species.bodyflags & ALL_RPARTS) //If they can have a fully cybernetic body... + if(dna.species.bodyflags & ALL_RPARTS) //If they can have a fully cybernetic body... var/datum/robolimb/robohead = all_robolimbs[head_organ.model] if(!head_organ) return @@ -1483,7 +1478,7 @@ var/list/hair = list() for(var/i in hair_styles_public_list) var/datum/sprite_accessory/hair/tmp_hair = hair_styles_public_list[i] - if((head_organ.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. + if((head_organ.dna.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. hair += i var/new_style = input(src, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair @@ -1571,8 +1566,8 @@ /mob/living/carbon/human/proc/get_eyecon() var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) var/obj/item/organ/internal/cyberimp/eyes/eye_implant = get_int_organ(/obj/item/organ/internal/cyberimp/eyes) - if(istype(species) && species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes) + if(istype(dna.species) && dna.species.eyes) + var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', dna.species.eyes) if(eye_implant) //Eye implants override native DNA eye colo(u)r eyes_icon = eye_implant.generate_icon() else if(eyes) @@ -1778,7 +1773,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X /mob/living/carbon/human/IsAdvancedToolUser() - if(species.has_fine_manipulation) + if(dna.species.has_fine_manipulation) return 1 return 0 @@ -1813,7 +1808,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X return 1 /mob/living/carbon/human/can_eat(flags = 255) - return species && (species.dietflags & flags) + return dna.species && (dna.species.dietflags & flags) /mob/living/carbon/human/selfFeed(var/obj/item/reagent_containers/food/toEat, fullness) if(!check_has_mouth()) @@ -1823,14 +1818,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X /mob/living/carbon/human/forceFed(var/obj/item/reagent_containers/food/toEat, mob/user, fullness) if(!check_has_mouth()) - if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (get_species() == "Machine")))) + if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (ismachine(src))))) to_chat(user, "Where do you intend to put \the [toEat]? \The [src] doesn't have a mouth!") return 0 return ..() /mob/living/carbon/human/selfDrink(var/obj/item/reagent_containers/food/drinks/toDrink) if(!check_has_mouth()) - if(!get_species() == "Machine") + if(!ismachine(src)) to_chat(src, "Where do you intend to put \the [src]? You don't have a mouth!") return 0 else @@ -1874,7 +1869,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X . |= A.GetAccess() /mob/living/carbon/human/is_mechanical() - return ..() || (species.bodyflags & ALL_RPARTS) != 0 + return ..() || (dna.species.bodyflags & ALL_RPARTS) != 0 /mob/living/carbon/human/can_use_guns(var/obj/item/gun/G) . = ..() @@ -1883,7 +1878,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X if(HULK in mutations) to_chat(src, "Your meaty finger is much too large for the trigger guard!") return 0 - if(NOGUNS in species.species_traits) + if(NOGUNS in dna.species.species_traits) to_chat(src, "Your fingers don't fit in the trigger guard!") return 0 @@ -1950,7 +1945,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X dna.deserialize(data["dna"]) real_name = dna.real_name name = real_name - set_species(dna.species) + set_species(dna.species.type, skip_same_check = TRUE) age = data["age"] undershirt = data["ushirt"] underwear = data["uwear"] @@ -2012,8 +2007,8 @@ Eyes need to have significantly high darksight to shine unless the mob has the X . += "---" /mob/living/carbon/human/get_taste_sensitivity() - if(species) - return species.taste_sensitivity + if(dna.species) + return dna.species.taste_sensitivity else return 1 diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 5ed14b3a18e..80c128ee07f 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -17,7 +17,7 @@ //TODO: fix husking if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD) ChangeToHusk() - if(species.can_revive_by_healing) + if(dna.species.can_revive_by_healing) var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain) if(B) if((health >= (config.health_threshold_dead + config.health_threshold_crit) * 0.5) && stat == DEAD && getBrainLoss()<120) @@ -32,11 +32,11 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(dna.species && dna.species.has_organ["brain"]) var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) - if(species) - amount = amount * species.brain_mod + if(dna.species) + amount = amount * dna.species.brain_mod sponge.receive_damage(amount, 1) brainloss = sponge.damage else @@ -48,11 +48,11 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(dna.species && dna.species.has_organ["brain"]) var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) - if(species) - amount = amount * species.brain_mod + if(dna.species) + amount = amount * dna.species.brain_mod sponge.damage = min(max(amount, 0), (maxHealth*2)) brainloss = sponge.damage else @@ -64,7 +64,7 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(dna.species && dna.species.has_organ["brain"]) var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) brainloss = min(sponge.damage,maxHealth*2) @@ -89,24 +89,24 @@ /mob/living/carbon/human/adjustBruteLoss(amount, damage_source) - if(species) - amount = amount * species.brute_mod + if(dna.species) + amount = amount * dna.species.brute_mod if(amount > 0) take_overall_damage(amount, 0, used_weapon = damage_source) else heal_overall_damage(-amount, 0) /mob/living/carbon/human/adjustFireLoss(amount, damage_source) - if(species) - amount = amount * species.burn_mod + if(dna.species) + amount = amount * dna.species.burn_mod if(amount > 0) take_overall_damage(0, amount, used_weapon = damage_source) else heal_overall_damage(0, -amount) /mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null) - if(species) - amount = amount * species.brute_mod + if(dna.species) + amount = amount * dna.species.brute_mod if(organ_name in bodyparts_by_name) var/obj/item/organ/external/O = get_organ(organ_name) @@ -115,12 +115,12 @@ O.receive_damage(amount, 0, sharp=is_sharp(damage_source), used_weapon=damage_source) else //if you don't want to heal robot organs, they you will have to check that yourself before using this proc. - O.heal_damage(-amount, 0, internal=0, robo_repair=(O.status & ORGAN_ROBOT)) + O.heal_damage(-amount, 0, internal = 0, robo_repair = O.is_robotic()) /mob/living/carbon/human/proc/adjustFireLossByPart(amount, organ_name, obj/damage_source = null) - if(species) - amount = amount * species.burn_mod + if(dna.species) + amount = amount * dna.species.burn_mod if(organ_name in bodyparts_by_name) var/obj/item/organ/external/O = get_organ(organ_name) @@ -129,7 +129,7 @@ O.receive_damage(0, amount, sharp=is_sharp(damage_source), used_weapon=damage_source) else //if you don't want to heal robot organs, they you will have to check that yourself before using this proc. - O.heal_damage(0, -amount, internal=0, robo_repair=(O.status & ORGAN_ROBOT)) + O.heal_damage(0, -amount, internal = 0, robo_repair = O.is_robotic()) /mob/living/carbon/human/Paralyse(amount) @@ -139,8 +139,8 @@ ..() /mob/living/carbon/human/adjustCloneLoss(amount) - if(species) - amount = amount * species.clone_mod + if(dna.species) + amount = amount * dna.species.clone_mod ..() var/heal_prob = max(0, 80 - getCloneLoss()) @@ -149,7 +149,7 @@ if(prob(mut_prob)) var/list/obj/item/organ/external/candidates = list() //TYPECASTED LISTS ARE NOT A FUCKING THING WHAT THE FUCK for(var/obj/item/organ/external/O in bodyparts) - if(O.status & ORGAN_ROBOT) + if(O.is_robotic()) continue if(!(O.status & ORGAN_MUTATED)) candidates |= O @@ -179,23 +179,23 @@ // Defined here solely to take species flags into account without having to recast at mob/living level. /mob/living/carbon/human/adjustOxyLoss(amount) - if(species) - amount = amount * species.oxy_mod + if(dna.species) + amount = amount * dna.species.oxy_mod ..() /mob/living/carbon/human/setOxyLoss(amount) - if(species) - amount = amount * species.oxy_mod + if(dna.species) + amount = amount * dna.species.oxy_mod ..() /mob/living/carbon/human/adjustToxLoss(amount) - if(species) - amount = amount * species.tox_mod + if(dna.species) + amount = amount * dna.species.tox_mod ..() /mob/living/carbon/human/setToxLoss(amount) - if(species) - amount = amount * species.tox_mod + if(dna.species) + amount = amount * dna.species.tox_mod ..() //////////////////////////////////////////// @@ -205,9 +205,9 @@ var/list/obj/item/organ/external/parts = list() for(var/obj/item/organ/external/O in bodyparts) if((brute && O.brute_dam) || (burn && O.burn_dam)) - if(!(flags & AFFECT_ROBOTIC_ORGAN) && O.status & ORGAN_ROBOT) + if(!(flags & AFFECT_ROBOTIC_ORGAN) && O.is_robotic()) continue - if(!(flags & AFFECT_ORGANIC_ORGAN) && !(O.status & ORGAN_ROBOT)) + if(!(flags & AFFECT_ORGANIC_ORGAN) && !O.is_robotic()) continue parts += O return parts @@ -352,8 +352,8 @@ This function restores all organs. switch(damagetype) if(BRUTE) damageoverlaytemp = 20 - if(species) - damage = damage * species.brute_mod + if(dna.species) + damage = damage * dna.species.brute_mod if(organ.receive_damage(damage, 0, sharp, used_weapon)) UpdateDamageIcon() @@ -376,8 +376,8 @@ This function restores all organs. if(BURN) damageoverlaytemp = 20 - if(species) - damage = damage * species.burn_mod + if(dna.species) + damage = damage * dna.species.burn_mod if(organ.receive_damage(0, damage, sharp, used_weapon)) UpdateDamageIcon() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 5b78b450357..6c2bb844155 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -165,7 +165,7 @@ emp_act /mob/living/carbon/human/emag_act(user as mob, var/obj/item/organ/external/affecting) if(!istype(affecting)) return - if(!(affecting.status & ORGAN_ROBOT)) + if(!affecting.is_robotic()) to_chat(user, "That limb isn't robotic.") return if(affecting.sabotaged) @@ -354,7 +354,7 @@ emp_act if(check_shields(user, 15, "the [hulk_verb]ing")) return ..(user, TRUE) - playsound(loc, user.species.unarmed.attack_sound, 25, 1, -1) + playsound(loc, user.dna.species.unarmed.attack_sound, 25, 1, -1) var/message = "[user] has [hulk_verb]ed [src]!" visible_message("[message]", "[message]") adjustBruteLoss(15) @@ -365,7 +365,7 @@ emp_act return if(ishuman(user)) var/mob/living/carbon/human/H = user - species.spec_attack_hand(H, src) + dna.species.spec_attack_hand(H, src) /mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L) if(..()) //successful larva bite. @@ -494,7 +494,7 @@ emp_act /mob/living/carbon/human/water_act(volume, temperature, source) ..() - species.water_act(src,volume,temperature,source) + dna.species.water_act(src,volume,temperature,source) /mob/living/carbon/human/is_eyes_covered(check_glasses = TRUE, check_head = TRUE, check_mask = TRUE) if(check_glasses && glasses && (glasses.flags_cover & GLASSESCOVERSEYES)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index a7fcc6874a2..96693a0d086 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,7 +1,7 @@ var/global/default_martial_art = new/datum/martial_art /mob/living/carbon/human - hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD,GLAND_HUD) //Marking colour and style var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000. diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index a835133f4d0..71a5f0396a1 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -2,7 +2,7 @@ . = 0 . += ..() . += config.human_delay - . += species.movement_delay(src) + . += dna.species.movement_delay(src) /mob/living/carbon/human/Process_Spacemove(movement_dir = 0) @@ -39,12 +39,12 @@ if(!lying && !buckled && !throwing) for(var/obj/item/organ/external/splinted in splinted_limbs) splinted.update_splints() - + if(!has_gravity(loc)) return - + var/obj/item/clothing/shoes/S = shoes - + //Bloody footprints var/turf/T = get_turf(src) var/obj/item/organ/external/l_foot = get_organ("l_foot") @@ -119,7 +119,7 @@ if(step_count % 3) //this basically says, every three moves make a noise return 0 //1st - none, 1%3==1, 2nd - none, 2%3==2, 3rd - noise, 3%3==0 - if(species.silent_steps) + if(dna.species.silent_steps) return 0 //species is silent playsound(T, S, volume, 1, range) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 9a78eafadd8..5dcae16b87a 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -62,7 +62,7 @@ // standing is poor if(stance_damage >= 8) if(!(lying || resting)) - if(!(NO_PAIN in species.species_traits)) + if(!(NO_PAIN in dna.species.species_traits)) emote("scream") custom_emote(1, "collapses!") Weaken(5) //can't emote while weakened, apparently. @@ -90,7 +90,7 @@ continue var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - custom_emote(1, "[(NO_PAIN in species.species_traits) ? "" : emote_scream ]drops what [p_they()] [p_were()] holding in [p_their()] [E.name]!") + custom_emote(1, "[(NO_PAIN in dna.species.species_traits) ? "" : emote_scream ]drops what [p_they()] [p_were()] holding in [p_their()] [E.name]!") else if(E.is_malfunctioning()) @@ -178,7 +178,7 @@ I use this to standardize shadowling dethrall code /mob/living/carbon/human/has_organic_damage() var/odmg = 0 for(var/obj/item/organ/external/O in bodyparts) - if(O.status & ORGAN_ROBOT) + if(O.is_robotic()) odmg += O.brute_dam odmg += O.burn_dam return (health < (100 - odmg)) diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm index a93fd9e8635..763a5ef15be 100644 --- a/code/modules/mob/living/carbon/human/interactive/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm @@ -128,7 +128,7 @@ //this is here because this has no client/prefs/brain whatever. age = rand(AGE_MIN, AGE_MAX) change_gender(pick("male", "female")) - rename_character(real_name, species.get_random_name(gender)) + rename_character(real_name, dna.species.get_random_name(gender)) //job handling myjob = new default_job() job = myjob.title @@ -208,9 +208,9 @@ var/datum/dna/toDoppel = chosen.dna T.real_name = toDoppel.real_name - T.set_species(chosen.species.name) - T.body_accessory = chosen.body_accessory + T.set_species(chosen.dna.species.type) T.dna = toDoppel.Clone() + T.body_accessory = chosen.body_accessory T.UpdateAppearance() domutcheck(T) @@ -245,7 +245,7 @@ MYID.age = age MYID.registered_name = real_name MYID.photo = get_id_photo(src) - MYID.access = Path_ID.access // Automatons have strange powers... strange indeed + MYID.access = Path_ID.access.Copy() // Automatons have strange powers... strange indeed RPID = new(src) RPID.name = "[real_name]'s ID Card ([alt_title])" @@ -257,7 +257,10 @@ RPID.photo = get_id_photo(src) RPID.access = myjob.get_access() - equip_to_slot_or_del(MYID, slot_wear_id) + if(wear_id) + qdel(wear_id) + if(!equip_to_slot_or_del(MYID, slot_wear_id)) + create_attack_log("Deleted ID due to slot contention") if(wear_pda) MYPDA = wear_pda else @@ -403,8 +406,12 @@ if(!hud_used) hud_used = new /datum/hud/human(src) -/mob/living/carbon/human/interactive/New(var/new_loc, var/new_species = null) +/mob/living/carbon/human/interactive/Initialize() ..() + return INITIALIZE_HINT_LATELOAD + +/mob/living/carbon/human/interactive/LateInitialize() + . = ..() snpc_list += src create_mob_hud() @@ -427,6 +434,7 @@ /mob/living/carbon/human/interactive/Destroy() hear_radio_list -= src snpc_list -= src + npc_master.removeBot(src) return ..() /mob/living/carbon/human/interactive/proc/retalTarget(mob/living/target) diff --git a/code/modules/mob/living/carbon/human/interactive/prefabs.dm b/code/modules/mob/living/carbon/human/interactive/prefabs.dm index 6553bb26b70..cee716b66ec 100644 --- a/code/modules/mob/living/carbon/human/interactive/prefabs.dm +++ b/code/modules/mob/living/carbon/human/interactive/prefabs.dm @@ -1,18 +1,18 @@ -/mob/living/carbon/human/interactive/angry/New() +/mob/living/carbon/human/interactive/angry/Initialize(mapload) TRAITS |= TRAIT_ROBUST TRAITS |= TRAIT_MEAN faction += "bot_angry" - ..() + return ..() -/mob/living/carbon/human/interactive/friendly/New() +/mob/living/carbon/human/interactive/friendly/Initialize(mapload) TRAITS |= TRAIT_FRIENDLY TRAITS |= TRAIT_UNROBUST faction += "bot_friendly" faction += "neutral" functions -= "combat" - ..() + return ..() -/mob/living/carbon/human/interactive/greytide/New() +/mob/living/carbon/human/interactive/greytide/Initialize(mapload) TRAITS |= TRAIT_ROBUST TRAITS |= TRAIT_MEAN TRAITS |= TRAIT_THIEVING @@ -21,4 +21,4 @@ targetInterestShift = 2 // likewise faction += "bot_grey" graytide = 1 - ..() \ No newline at end of file + return ..() diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 882501c49f2..50848851646 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -419,7 +419,7 @@ ..(what, who, where, silent = is_silent) /mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0) - switch(species.handle_can_equip(I, slot, disable_warning, src)) + switch(dna.species.handle_can_equip(I, slot, disable_warning, src)) if(1) return 1 if(2) return 0 //if it returns 2, it wants no normal handling diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 22e2e0ffe25..d577a02e2c4 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -15,10 +15,10 @@ handle_heartbeat() handle_heartattack() handle_drunk() - species.handle_life(src) + dna.species.handle_life(src) if(!client) - species.handle_npc(src) + dna.species.handle_npc(src) if(stat != DEAD) //Stuff jammed in your limbs hurts @@ -178,7 +178,7 @@ if(gene_stability < GENETIC_DAMAGE_STAGE_3) gib() - if(!(RADIMMUNE in species.species_traits)) + if(!(RADIMMUNE in dna.species.species_traits)) if(radiation) radiation = Clamp(radiation, 0, 200) @@ -238,7 +238,7 @@ chest.add_autopsy_data("Radiation Poisoning", autopsy_damage) /mob/living/carbon/human/breathe() - if(!species.breathe(src)) + if(!dna.species.breathe(src)) ..() /mob/living/carbon/human/check_breath(datum/gas_mixture/breath) @@ -253,8 +253,8 @@ failed_last_breath = TRUE - if(species) - var/datum/species/S = species + if(dna.species) + var/datum/species/S = dna.species if(S.breathid == "o2") throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) @@ -332,39 +332,39 @@ bodytemperature += min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. - if(bodytemperature > species.heat_level_1) + if(bodytemperature > dna.species.heat_level_1) //Body temperature is too hot. if(status_flags & GODMODE) return 1 //godmode - var/mult = species.heatmod + var/mult = dna.species.heatmod - if(bodytemperature >= species.heat_level_1 && bodytemperature <= species.heat_level_2) + if(bodytemperature >= dna.species.heat_level_1 && bodytemperature <= dna.species.heat_level_2) throw_alert("temp", /obj/screen/alert/hot, 1) take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") - if(bodytemperature > species.heat_level_2 && bodytemperature <= species.heat_level_3) + if(bodytemperature > dna.species.heat_level_2 && bodytemperature <= dna.species.heat_level_3) throw_alert("temp", /obj/screen/alert/hot, 2) take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") - if(bodytemperature > species.heat_level_3 && bodytemperature < INFINITY) + if(bodytemperature > dna.species.heat_level_3 && bodytemperature < INFINITY) throw_alert("temp", /obj/screen/alert/hot, 3) if(on_fire) take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire") else take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") - else if(bodytemperature < species.cold_level_1) + else if(bodytemperature < dna.species.cold_level_1) if(status_flags & GODMODE) return 1 if(stat == DEAD) return 1 if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) - var/mult = species.coldmod - if(bodytemperature >= species.cold_level_2 && bodytemperature <= species.cold_level_1) + var/mult = dna.species.coldmod + if(bodytemperature >= dna.species.cold_level_2 && bodytemperature <= dna.species.cold_level_1) throw_alert("temp", /obj/screen/alert/cold, 1) take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature") - if(bodytemperature >= species.cold_level_3 && bodytemperature < species.cold_level_2) + if(bodytemperature >= dna.species.cold_level_3 && bodytemperature < dna.species.cold_level_2) throw_alert("temp", /obj/screen/alert/cold, 2) take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature") - if(bodytemperature > -INFINITY && bodytemperature < species.cold_level_3) + if(bodytemperature > -INFINITY && bodytemperature < dna.species.cold_level_3) throw_alert("temp", /obj/screen/alert/cold, 3) take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature") else @@ -379,18 +379,18 @@ var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. if(status_flags & GODMODE) return 1 //godmode - if(adjusted_pressure >= species.hazard_high_pressure) + if(adjusted_pressure >= dna.species.hazard_high_pressure) if(!(HEATRES in mutations)) - var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) + var/pressure_damage = min( ( (adjusted_pressure / dna.species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure") throw_alert("pressure", /obj/screen/alert/highpressure, 2) else clear_alert("pressure") - else if(adjusted_pressure >= species.warning_high_pressure) + else if(adjusted_pressure >= dna.species.warning_high_pressure) throw_alert("pressure", /obj/screen/alert/highpressure, 1) - else if(adjusted_pressure >= species.warning_low_pressure) + else if(adjusted_pressure >= dna.species.warning_low_pressure) clear_alert("pressure") - else if(adjusted_pressure >= species.hazard_low_pressure) + else if(adjusted_pressure >= dna.species.hazard_low_pressure) throw_alert("pressure", /obj/screen/alert/lowpressure, 1) else if(COLDRES in mutations) @@ -430,13 +430,13 @@ //END FIRE CODE /mob/living/carbon/human/proc/stabilize_temperature_from_calories() - var/body_temperature_difference = species.body_temperature - bodytemperature + var/body_temperature_difference = dna.species.body_temperature - bodytemperature - if(bodytemperature <= species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. + if(bodytemperature <= dna.species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. bodytemperature += max((body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) - if(bodytemperature >= species.cold_level_1 && bodytemperature <= species.heat_level_1) + if(bodytemperature >= dna.species.cold_level_1 && bodytemperature <= dna.species.heat_level_1) bodytemperature += body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR - if(bodytemperature >= species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects. + if(bodytemperature >= dna.species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects. //We totally need a sweat system cause it totally makes sense...~ bodytemperature += min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers @@ -588,7 +588,7 @@ return 0 //godmode //The fucking FAT mutation is the greatest shit ever. It makes everyone so hot and bothered. - if(CAN_BE_FAT in species.species_traits) + if(CAN_BE_FAT in dna.species.species_traits) if(FAT in mutations) if(overeatduration < 100) becomeSlim() @@ -652,7 +652,7 @@ AdjustDizzy(-3) AdjustJitter(-3) - if(NO_INTORGANS in species.species_traits) + if(NO_INTORGANS in dna.species.species_traits) return handle_trace_chems() @@ -766,10 +766,10 @@ //Vision //god knows why this is here var/obj/item/organ/vision - if(species.vision_organ) - vision = get_int_organ(species.vision_organ) + if(dna.species.vision_organ) + vision = get_int_organ(dna.species.vision_organ) - if(!species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. + if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. SetEyeBlind(0) blinded = 0 SetEyeBlurry(0) @@ -860,10 +860,10 @@ remoteview_target = null reset_perspective(null) - species.handle_vision(src) + dna.species.handle_vision(src) /mob/living/carbon/human/handle_hud_icons() - species.handle_hud_icons(src) + dna.species.handle_hud_icons(src) /mob/living/carbon/human/handle_random_events() // Puke if toxloss is too high @@ -907,7 +907,7 @@ if(times_fired % 5 == 1) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load) - if(NO_BLOOD in species.species_traits) + if(NO_BLOOD in dna.species.species_traits) return PULSE_NONE //No blood, no pulse. if(stat == DEAD) @@ -977,7 +977,7 @@ var/obj/item/clothing/mask/M = H.wear_mask if(M && (M.flags_cover & MASKCOVERSMOUTH)) return - if(NO_BREATHE in H.species.species_traits) + if(NO_BREATHE in H.dna.species.species_traits) return //no puking if you can't smell! // Humans can lack a mind datum, y'know if(H.mind && (H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Coroner")) @@ -993,7 +993,7 @@ if(!H) //H.status will runtime if there is no H (obviously) return - if(H.status & ORGAN_ROBOT) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people. + if(H.is_robotic()) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people. if(shock_stage >= 10 || istype(get_turf(src), /turf/space)) //PULSE_THREADY - maximum value for pulse, currently it 5. //High pulse value corresponds to a fast rate of heartbeat. @@ -1020,10 +1020,7 @@ if(heartbeat >= rate) heartbeat = 0 - if(H.status & ORGAN_ASSISTED) - src << sound('sound/effects/pacemakebeat.ogg',0,0,CHANNEL_HEARTBEAT,50) - else - src << sound('sound/effects/singlebeat.ogg',0,0,CHANNEL_HEARTBEAT,50) + src << sound('sound/effects/singlebeat.ogg',0,0,CHANNEL_HEARTBEAT,50) else heartbeat++ @@ -1057,9 +1054,9 @@ /mob/living/carbon/human/proc/can_heartattack() - if(NO_BLOOD in species.species_traits) + if(NO_BLOOD in dna.species.species_traits) return FALSE - if(NO_INTORGANS in species.species_traits) + if(NO_INTORGANS in dna.species.species_traits) return FALSE return TRUE diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm index d4b160509ea..e16c67a56d0 100644 --- a/code/modules/mob/living/carbon/human/login.dm +++ b/code/modules/mob/living/carbon/human/login.dm @@ -1,7 +1,7 @@ /mob/living/carbon/human/Login() ..() - if(species && species.ventcrawler) + if(dna.species && dna.species.ventcrawler) to_chat(src, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.") update_pipe_vision() return diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 7657a3be3be..7d408ce9199 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -42,7 +42,7 @@ if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak. return 1 - if(species.can_understand(other)) + if(dna.species.can_understand(other)) return 1 //These only pertain to common. Languages are handled by mob/say_understands() @@ -87,7 +87,7 @@ /mob/living/carbon/human/IsVocal() // how do species that don't breathe talk? magic, that's what. - var/breathes = (!(NO_BREATHE in species.species_traits)) + var/breathes = (!(NO_BREATHE in dna.species.species_traits)) var/obj/item/organ/internal/L = get_organ_slot("lungs") if((breathes && !L) || breathes && L && (L.status & ORGAN_DEAD)) return FALSE @@ -219,8 +219,8 @@ /mob/living/carbon/human/handle_speech_sound() var/list/returns[2] - if(species.speech_sounds && prob(species.speech_chance)) - returns[1] = sound(pick(species.speech_sounds)) + if(dna.species.speech_sounds && prob(dna.species.speech_chance)) + returns[1] = sound(pick(dna.species.speech_sounds)) returns[2] = 50 return returns diff --git a/code/modules/mob/living/carbon/human/shock.dm b/code/modules/mob/living/carbon/human/shock.dm index d8dc9356de7..e2d5dd79cec 100644 --- a/code/modules/mob/living/carbon/human/shock.dm +++ b/code/modules/mob/living/carbon/human/shock.dm @@ -23,7 +23,7 @@ /mob/living/carbon/human/proc/handle_shock() if(status_flags & GODMODE) //godmode return - if(NO_PAIN in species.species_traits) + if(NO_PAIN in dna.species.species_traits) return updateshock() diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/_species.dm similarity index 91% rename from code/modules/mob/living/carbon/human/species/species.dm rename to code/modules/mob/living/carbon/human/species/_species.dm index 139f2f7c9bb..6ce91d80ddd 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -1,11 +1,6 @@ -/* - Datum-based species. Should make for much cleaner and easier to maintain mutantrace code. -*/ - /datum/species var/name // Species name. var/name_plural // Pluralized name (since "[name]s" is not always valid) - var/path // Species path var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set. var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set. @@ -18,8 +13,8 @@ var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen. var/butt_sprite = "human" - var/primitive_form // Lesser form, if any (ie. monkey for humans) - var/greater_form // Greater form, if any, ie. human for monkeys. + var/datum/species/primitive_form = null // Lesser form, if any (ie. monkey for humans) + var/datum/species/greater_form = null // Greater form, if any, ie. human for monkeys. var/tail // Name of tail image in species effects icon file. var/datum/unarmed_attack/unarmed //For empty hand harm-intent attack var/unarmed_type = /datum/unarmed_attack @@ -80,6 +75,7 @@ var/clothing_flags = 0 // Underwear and socks. var/exotic_blood + var/skinned_type var/bodyflags = 0 var/dietflags = 0 // Make sure you set this, otherwise it won't be able to digest a lot of foods @@ -94,6 +90,7 @@ //Used in icon caching. var/race_key = 0 var/icon/icon_template + var/is_small var/show_ssd = 1 var/can_revive_by_healing // Determines whether or not this species can be revived by simply healing them @@ -165,11 +162,11 @@ unarmed = new unarmed_type() -/datum/species/proc/get_random_name(var/gender) +/datum/species/proc/get_random_name(gender) var/datum/language/species_language = all_languages[language] return species_language.get_random_name(gender) -/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. +/datum/species/proc/create_organs(mob/living/carbon/human/H) //Handles creation of mob organs. QDEL_LIST(H.internal_organs) QDEL_LIST(H.bodyparts) @@ -262,28 +259,24 @@ . -= 2 return . -/datum/species/proc/handle_post_spawn(var/mob/living/carbon/C) //Handles anything not already covered by basic species assignment. +/datum/species/proc/handle_post_spawn(mob/living/carbon/C) //Handles anything not already covered by basic species assignment. grant_abilities(C) + +/datum/species/proc/updatespeciescolor(mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors. return -/datum/species/proc/updatespeciescolor(var/mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors. - return - -/datum/species/proc/grant_abilities(var/mob/living/carbon/human/H) +/datum/species/proc/grant_abilities(mob/living/carbon/human/H) for(var/proc/ability in species_abilities) H.verbs += ability - return -/datum/species/proc/handle_pre_change(var/mob/living/carbon/human/H) - if(H.butcher_results)//clear it out so we don't butcher a actual human. +/datum/species/proc/handle_pre_change(mob/living/carbon/human/H) + if(H.butcher_results) //clear it out so we don't butcher a actual human. H.butcher_results = null remove_abilities(H) - return -/datum/species/proc/remove_abilities(var/mob/living/carbon/human/H) +/datum/species/proc/remove_abilities(mob/living/carbon/human/H) for(var/proc/ability in species_abilities) H.verbs -= ability - return // Do species-specific reagent handling here // Return 1 if it should do normal processing too @@ -294,47 +287,42 @@ if(R.id == exotic_blood) H.blood_volume = min(H.blood_volume + round(R.volume, 0.1), BLOOD_VOLUME_NORMAL) H.reagents.del_reagent(R.id) - return 0 - return 1 + return FALSE + return TRUE // For special snowflake species effects // (Slime People changing color based on the reagents they consume) -/datum/species/proc/handle_life(var/mob/living/carbon/human/H) +/datum/species/proc/handle_life(mob/living/carbon/human/H) if((NO_BREATHE in species_traits) || (BREATHLESS in H.mutations)) H.setOxyLoss(0) H.SetLoseBreath(0) -/datum/species/proc/handle_dna(var/mob/living/carbon/C, var/remove) //Handles DNA mutations, as that doesn't work at init. Make sure you call genemutcheck on any blocks changed here +/datum/species/proc/handle_dna(mob/living/carbon/C, remove) //Handles DNA mutations, as that doesn't work at init. Make sure you call genemutcheck on any blocks changed here return -// Used for species-specific names (Vox, etc) -/datum/species/proc/makeName(var/gender,var/mob/living/carbon/human/H=null) - if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) - else return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) - -/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). +/datum/species/proc/handle_death(mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). return /datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(attacker_style && attacker_style.help_act(user, target))//adminfu only... - return 1 + return TRUE if(target.health >= config.health_threshold_crit) target.help_shake_act(user) - return 1 + return TRUE else user.do_cpr(target) /datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(attacker_style && attacker_style.grab_act(user, target)) - return 1 + return TRUE else target.grabbedby(user) - return 1 + return TRUE /datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) //Vampire code if(user.mind && user.mind.vampire && (user.mind in ticker.mode.vampires) && !user.mind.vampire.draining && user.zone_sel && user.zone_sel.selecting == "head" && target != user) - if((NO_BLOOD in target.species.species_traits) || target.species.exotic_blood || !target.blood_volume) + if((NO_BLOOD in target.dna.species.species_traits) || target.dna.species.exotic_blood || !target.blood_volume) to_chat(user, "They have no blood!") return if(target.mind && target.mind.vampire && (target.mind in ticker.mode.vampires)) @@ -352,9 +340,9 @@ return //end vampire codes if(attacker_style && attacker_style.harm_act(user, target)) - return 1 + return TRUE else - var/datum/unarmed_attack/attack = user.species.unarmed + var/datum/unarmed_attack/attack = user.dna.species.unarmed user.do_attack_animation(target, attack.animation_type) add_attack_logs(user, target, "Melee attacked with fists", target.ckey ? null : ATKLOG_ALL) @@ -364,12 +352,12 @@ else target.LAssailant = user - var/damage = rand(user.species.punchdamagelow, user.species.punchdamagehigh) + var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh) damage += attack.damage if(!damage) playsound(target.loc, attack.miss_sound, 25, 1, -1) target.visible_message("[user] tried to [pick(attack.attack_verb)] [target]!") - return 0 + return FALSE var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_sel.selecting)) @@ -380,7 +368,7 @@ target.visible_message("[user] [pick(attack.attack_verb)]ed [target]!") target.apply_damage(damage, BRUTE, affecting, armor_block, sharp = attack.sharp) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway. - if((target.stat != DEAD) && damage >= user.species.punchstunthreshold) + if((target.stat != DEAD) && damage >= user.dna.species.punchstunthreshold) target.visible_message("[user] has weakened [target]!", \ "[user] has weakened [target]!") target.apply_effect(4, WEAKEN, armor_block) @@ -390,7 +378,7 @@ /datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(attacker_style && attacker_style.disarm_act(user, target)) - return 1 + return TRUE else add_attack_logs(user, target, "Disarmed", ATKLOG_ALL) user.do_attack_animation(target, ATTACK_EFFECT_DISARM) @@ -463,7 +451,7 @@ if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(0, M.name, attack_type = UNARMED_ATTACK)) add_attack_logs(M, H, "Melee attacked with fists (miss/block)") H.visible_message("[M] attempted to touch [H]!") - return 0 + return FALSE switch(M.a_intent) if(INTENT_HELP) @@ -487,11 +475,11 @@ /datum/species/proc/after_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE) return -/datum/species/proc/can_understand(var/mob/other) +/datum/species/proc/can_understand(mob/other) return // Called in life() when the mob has no client. -/datum/species/proc/handle_npc(var/mob/living/carbon/human/H) +/datum/species/proc/handle_npc(mob/living/carbon/human/H) return //Species unarmed attacks @@ -525,7 +513,7 @@ damage = 6 /datum/species/proc/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user) - return 0 + return FALSE /datum/species/proc/handle_vision(mob/living/carbon/human/H) // Right now this just handles blind, blurry, and similar states @@ -631,7 +619,7 @@ Returns the path corresponding to the corresponding organ It'll return null if the organ doesn't correspond, so include null checks when using this! */ //Fethas Todo:Do i need to redo this? -/datum/species/proc/return_organ(var/organ_slot) +/datum/species/proc/return_organ(organ_slot) if(!(organ_slot in has_organ)) return null return has_organ[organ_slot] @@ -729,4 +717,4 @@ It'll return null if the organ doesn't correspond, so include null checks when u /datum/species/proc/water_act(mob/living/carbon/human/M, volume, temperature, source) if(abs(temperature - M.bodytemperature) > 10) //If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately - M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling + M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm index 8aeb6f88a3d..c205cb6d033 100644 --- a/code/modules/mob/living/carbon/human/species/abductor.dm +++ b/code/modules/mob/living/carbon/human/species/abductor.dm @@ -3,7 +3,6 @@ name_plural = "Abductors" icobase = 'icons/mob/human_races/r_abductor.dmi' deform = 'icons/mob/human_races/r_abductor.dmi' - path = /mob/living/carbon/human/abductor language = "Abductor Mindlink" default_language = "Abductor Mindlink" eyes = "blank_eyes" @@ -16,7 +15,7 @@ "eyes" = /obj/item/organ/internal/eyes/abductor //3 darksight. ) - species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS) + species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_EXAMINE) oxy_mod = 0 @@ -27,14 +26,21 @@ female_scream_sound = 'sound/goonstation/voice/male_scream.ogg' female_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg') female_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg' //Abductors always scream like guys + var/team = 1 + var/scientist = FALSE // vars to not pollute spieces list with castes /datum/species/abductor/can_understand(mob/other) //Abductors can understand everyone, but they can only speak over their mindlink to another team-member - return 1 + return TRUE /datum/species/abductor/handle_post_spawn(mob/living/carbon/human/H) H.gender = NEUTER - if(H.mind) - H.mind.abductor = new /datum/abductor H.languages.Cut() //Under no condition should you be able to speak any language H.add_language("Abductor Mindlink") //other than over the abductor's own mindlink + var/datum/atom_hud/abductor_hud = huds[DATA_HUD_ABDUCTOR] + abductor_hud.add_hud_to(H) return ..() + +/datum/species/abductor/remove_abilities(mob/living/carbon/human/H) + ..() + var/datum/atom_hud/abductor_hud = huds[DATA_HUD_ABDUCTOR] + abductor_hud.remove_hud_from(H) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm new file mode 100644 index 00000000000..7d7b2acd713 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/diona.dm @@ -0,0 +1,114 @@ +/datum/species/diona + name = "Diona" + name_plural = "Dionaea" + icobase = 'icons/mob/human_races/r_diona.dmi' + deform = 'icons/mob/human_races/r_def_plant.dmi' + language = "Rootspeak" + speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16] + speech_chance = 20 + unarmed_type = /datum/unarmed_attack/diona + //primitive_form = "Nymph" + slowdown = 5 + remains_type = /obj/effect/decal/cleanable/ash + + + warning_low_pressure = 50 + hazard_low_pressure = -1 + + cold_level_1 = 50 + cold_level_2 = -1 + cold_level_3 = -1 + + heat_level_1 = 300 + heat_level_2 = 340 + heat_level_3 = 400 + + blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ + species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ + there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \ + Minoris primary being ringed with a cloud of singing space-station-sized entities.

    The Dionaea coexist peacefully with \ + all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \ + even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ + water and other radiation." + + species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN) + clothing_flags = HAS_SOCKS + default_hair_colour = "#000000" + dietflags = 0 //Diona regenerate nutrition in light and water, no diet necessary + taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE + skinned_type = /obj/item/stack/sheet/wood + + oxy_mod = 0 + + body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not + blood_color = "#004400" + flesh_color = "#907E4A" + butt_sprite = "diona" + + reagent_tag = PROCESS_ORG + + has_organ = list( + "nutrient channel" = /obj/item/organ/internal/liver/diona, + "neural strata" = /obj/item/organ/internal/heart/diona, + "receptor node" = /obj/item/organ/internal/eyes/diona, //Default darksight of 2. + "gas bladder" = /obj/item/organ/internal/brain/diona, + "polyp segment" = /obj/item/organ/internal/kidneys/diona, + "anchoring ligament" = /obj/item/organ/internal/appendix/diona + ) + + vision_organ = /obj/item/organ/internal/eyes/diona + has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/chest/diona), + "groin" = list("path" = /obj/item/organ/external/groin/diona), + "head" = list("path" = /obj/item/organ/external/head/diona), + "l_arm" = list("path" = /obj/item/organ/external/arm/diona), + "r_arm" = list("path" = /obj/item/organ/external/arm/right/diona), + "l_leg" = list("path" = /obj/item/organ/external/leg/diona), + "r_leg" = list("path" = /obj/item/organ/external/leg/right/diona), + "l_hand" = list("path" = /obj/item/organ/external/hand/diona), + "r_hand" = list("path" = /obj/item/organ/external/hand/right/diona), + "l_foot" = list("path" = /obj/item/organ/external/foot/diona), + "r_foot" = list("path" = /obj/item/organ/external/foot/right/diona) + ) + + suicide_messages = list( + "is losing branches!", + "pulls out a secret stash of herbicide and takes a hearty swig!", + "is pulling themselves apart!") + +/datum/species/diona/can_understand(var/mob/other) + if(istype(other, /mob/living/simple_animal/diona)) + return 1 + return 0 + +/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H) + H.gender = NEUTER + + return ..() + +/datum/species/diona/handle_life(var/mob/living/carbon/human/H) + H.radiation = Clamp(H.radiation, 0, 100) //We have to clamp this first, then decrease it, or there's a few edge cases of massive heals if we clamp and decrease at the same time. + var/rads = H.radiation / 25 + H.radiation = max(H.radiation-rads, 0) + H.nutrition = min(H.nutrition+rads, NUTRITION_LEVEL_WELL_FED+10) + H.adjustBruteLoss(-(rads)) + H.adjustToxLoss(-(rads)) + + var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing + if(isturf(H.loc)) //else, there's considered to be no light + var/turf/T = H.loc + light_amount = min(T.get_lumcount() * 10, 5) //hardcapped so it's not abused by having a ton of flashlights + H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10) + + if(light_amount > 0) + H.clear_alert("nolight") + else + H.throw_alert("nolight", /obj/screen/alert/nolight) + + if((light_amount >= 5) && !H.suiciding) //if there's enough light, heal + + H.adjustBruteLoss(-(light_amount/2)) + H.adjustFireLoss(-(light_amount/4)) + if(H.nutrition < NUTRITION_LEVEL_STARVING+50) + H.take_overall_damage(10,0) + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/drask.dm b/code/modules/mob/living/carbon/human/species/drask.dm new file mode 100644 index 00000000000..7914c4e7d70 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/drask.dm @@ -0,0 +1,62 @@ +/datum/species/drask + name = "Drask" + name_plural = "Drask" + icobase = 'icons/mob/human_races/r_drask.dmi' + deform = 'icons/mob/human_races/r_drask.dmi' + language = "Orluum" + eyes = "drask_eyes_s" + + speech_sounds = list('sound/voice/DraskTalk.ogg') + speech_chance = 20 + male_scream_sound = 'sound/voice/DraskTalk2.ogg' + female_scream_sound = 'sound/voice/DraskTalk2.ogg' + male_cough_sounds = 'sound/voice/DraskCough.ogg' + female_cough_sounds = 'sound/voice/DraskCough.ogg' + male_sneeze_sound = 'sound/voice/DraskSneeze.ogg' + female_sneeze_sound = 'sound/voice/DraskSneeze.ogg' + + burn_mod = 2 + //exotic_blood = "cryoxadone" + body_temperature = 273 + + blurb = "Hailing from Hoorlm, planet outside what is usually considered a habitable \ + orbit, the Drask evolved to live in extreme cold. Their strange bodies seem \ + to operate better the colder their surroundings are, and can regenerate rapidly \ + when breathing supercooled gas.

    On their homeworld, the Drask live long lives \ + in their labyrinthine settlements, carved out beneath Hoorlm's icy surface, where the air \ + is of breathable density." + + suicide_messages = list( + "is self-warming with friction!", + "is jamming fingers through their big eyes!", + "is sucking in warm air!", + "is holding their breath!") + + species_traits = list(LIPS, IS_WHITELISTED) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT + bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS + dietflags = DIET_OMNI + + cold_level_1 = -1 //Default 260 - Lower is better + cold_level_2 = -1 //Default 200 + cold_level_3 = -1 //Default 120 + coldmod = -1 + + heat_level_1 = 300 //Default 360 - Higher is better + heat_level_2 = 340 //Default 400 + heat_level_3 = 400 //Default 460 + heatmod = 2 + + flesh_color = "#a3d4eb" + reagent_tag = PROCESS_ORG + base_color = "#a3d4eb" + blood_color = "#a3d4eb" + butt_sprite = "drask" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart/drask, + "lungs" = /obj/item/organ/internal/lungs/drask, + "metabolic strainer" = /obj/item/organ/internal/liver/drask, + "eyes" = /obj/item/organ/internal/eyes/drask, //5 darksight. + "brain" = /obj/item/organ/internal/brain/drask + ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 74f3e97d879..772a5ca5ba6 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -5,7 +5,6 @@ icobase = 'icons/mob/human_races/r_golem.dmi' deform = 'icons/mob/human_races/r_golem.dmi' - default_language = "Galactic Common" species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE, NOGUNS) oxy_mod = 0 diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm new file mode 100644 index 00000000000..ad4239c0d05 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/grey.dm @@ -0,0 +1,55 @@ +/datum/species/grey + name = "Grey" + name_plural = "Greys" + icobase = 'icons/mob/human_races/r_grey.dmi' + deform = 'icons/mob/human_races/r_def_grey.dmi' + language = "Psionic Communication" + eyes = "grey_eyes_s" + butt_sprite = "grey" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/grey, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain/grey, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes/grey //5 darksight. + ) + + brute_mod = 1.25 //greys are fragile + + default_genes = list(REMOTE_TALK) + + + species_traits = list(LIPS, IS_WHITELISTED, CAN_BE_FAT) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_BODY_MARKINGS + dietflags = DIET_HERB + reagent_tag = PROCESS_ORG + blood_color = "#A200FF" + +/datum/species/grey/handle_dna(var/mob/living/carbon/C, var/remove) + if(!remove) + C.dna.SetSEState(REMOTETALKBLOCK,1,1) + genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) + else + C.dna.SetSEState(REMOTETALKBLOCK,0,1) + genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) + ..() + +/datum/species/grey/water_act(var/mob/living/carbon/C, volume, temperature, source) + ..() + C.take_organ_damage(5,min(volume,20)) + C.emote("scream") + +/datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H) + var/speech_pref = H.client.prefs.speciesprefs + if(speech_pref) + H.mind.speech_span = "wingdings" + +/datum/species/grey/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) + if(R.id == "sacid") + H.reagents.del_reagent(R.id) + return 0 + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/human.dm b/code/modules/mob/living/carbon/human/species/human.dm new file mode 100644 index 00000000000..2a161ab9318 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/human.dm @@ -0,0 +1,20 @@ +/datum/species/human + name = "Human" + name_plural = "Humans" + icobase = 'icons/mob/human_races/r_human.dmi' + deform = 'icons/mob/human_races/r_def_human.dmi' + primitive_form = /datum/species/monkey + language = "Sol Common" + species_traits = list(LIPS, CAN_BE_FAT) + skinned_type = /obj/item/stack/sheet/animalhide/human + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS + dietflags = DIET_OMNI + blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ + colonies across a wide swathe of space. They hold a wide range of forms and creeds.

    \ + While the central Sol government maintains control of its far-flung people, powerful corporate \ + interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ + worlds tumultous at best." + + reagent_tag = PROCESS_ORG + //Has standard darksight of 2. \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/kidan.dm b/code/modules/mob/living/carbon/human/species/kidan.dm new file mode 100644 index 00000000000..583e098054b --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/kidan.dm @@ -0,0 +1,41 @@ +/datum/species/kidan + name = "Kidan" + name_plural = "Kidan" + icobase = 'icons/mob/human_races/r_kidan.dmi' + deform = 'icons/mob/human_races/r_def_kidan.dmi' + language = "Chittin" + unarmed_type = /datum/unarmed_attack/claws + + brute_mod = 0.8 + + species_traits = list(IS_WHITELISTED) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS + eyes = "kidan_eyes_s" + dietflags = DIET_HERB + blood_color = "#FB9800" + reagent_tag = PROCESS_ORG + //Default styles for created mobs. + default_headacc = "Normal Antennae" + butt_sprite = "kidan" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/kidan, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. + "lantern" = /obj/item/organ/internal/lantern + ) + + allowed_consumed_mobs = list(/mob/living/simple_animal/diona) + + suicide_messages = list( + "is attempting to bite their antenna off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is cracking their exoskeleton!", + "is stabbing themselves with their mandibles!", + "is holding their breath!") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm new file mode 100644 index 00000000000..066677f3104 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -0,0 +1,88 @@ +/datum/species/machine + name = "Machine" + name_plural = "Machines" + + blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \ + robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \ + to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \ + generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \ + inhuman in outlook and perspective." + + icobase = 'icons/mob/human_races/r_machine.dmi' + deform = 'icons/mob/human_races/r_machine.dmi' + language = "Trinary" + remains_type = /obj/effect/decal/remains/robot + skinned_type = /obj/item/stack/sheet/metal // Let's grind up IPCs for station resources! + + eyes = "blank_eyes" + brute_mod = 2.5 // 100% * 2.5 * 0.6 (robolimbs) ~= 150% + burn_mod = 2.5 // So they take 50% extra damage from brute/burn overall. + tox_mod = 0 + clone_mod = 0 + oxy_mod = 0 + death_message = "gives one shrill beep before falling limp, their monitor flashing blue before completely shutting off..." + + species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_BLOOD, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS + dietflags = 0 //IPCs can't eat, so no diet + taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE + blood_color = "#1F181F" + flesh_color = "#AAAAAA" + //Default styles for created mobs. + default_hair = "Blue IPC Screen" + can_revive_by_healing = 1 + has_gender = FALSE + reagent_tag = PROCESS_SYN + male_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' + female_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' + male_cough_sounds = list('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg') + female_cough_sounds = list('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg') + male_sneeze_sound = 'sound/effects/mob_effects/machine_sneeze.ogg' + female_sneeze_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg' + butt_sprite = "machine" + + has_organ = list( + "brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain, + "cell" = /obj/item/organ/internal/cell, + "optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2. + "charger" = /obj/item/organ/internal/cyberimp/arm/power_cord + ) + + vision_organ = /obj/item/organ/internal/eyes/optical_sensor + has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/chest/ipc), + "groin" = list("path" = /obj/item/organ/external/groin/ipc), + "head" = list("path" = /obj/item/organ/external/head/ipc), + "l_arm" = list("path" = /obj/item/organ/external/arm/ipc), + "r_arm" = list("path" = /obj/item/organ/external/arm/right/ipc), + "l_leg" = list("path" = /obj/item/organ/external/leg/ipc), + "r_leg" = list("path" = /obj/item/organ/external/leg/right/ipc), + "l_hand" = list("path" = /obj/item/organ/external/hand/ipc), + "r_hand" = list("path" = /obj/item/organ/external/hand/right/ipc), + "l_foot" = list("path" = /obj/item/organ/external/foot/ipc), + "r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc) + ) + + suicide_messages = list( + "is powering down!", + "is smashing their own monitor!", + "is twisting their own neck!", + "is downloading extra RAM!", + "is frying their own circuits!", + "is blocking their ventilation port!") + + species_abilities = list( + /mob/living/carbon/human/proc/change_monitor + ) + +/datum/species/machine/handle_death(var/mob/living/carbon/human/H) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + if(!head_organ) + return + head_organ.h_style = "Bald" + head_organ.f_style = "Shaved" + spawn(100) + if(H) + H.update_hair() + H.update_fhair() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index c5003b21330..4128024a8c9 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -8,10 +8,11 @@ damage_overlays = 'icons/mob/human_races/masks/dam_monkey.dmi' damage_mask = 'icons/mob/human_races/masks/dam_mask_monkey.dmi' blood_mask = 'icons/mob/human_races/masks/blood_monkey.dmi' - path = /mob/living/carbon/human/monkey language = null default_language = "Chimpanzee" - greater_form = "Human" + species_traits = list(NO_EXAMINE) + skinned_type = /obj/item/stack/sheet/animalhide/monkey + greater_form = /datum/species/human is_small = 1 has_fine_manipulation = 0 ventcrawler = 1 @@ -99,7 +100,7 @@ icobase = 'icons/mob/human_races/monkeys/r_farwa.dmi' deform = 'icons/mob/human_races/monkeys/r_farwa.dmi' - greater_form = "Tajaran" + greater_form = /datum/species/tajaran default_language = "Farwa" flesh_color = "#AFA59E" base_color = "#000000" @@ -123,7 +124,7 @@ icobase = 'icons/mob/human_races/monkeys/r_wolpin.dmi' deform = 'icons/mob/human_races/monkeys/r_wolpin.dmi' - greater_form = "Vulpkanin" + greater_form = /datum/species/vulpkanin default_language = "Wolpin" flesh_color = "#966464" base_color = "#000000" @@ -147,7 +148,7 @@ icobase = 'icons/mob/human_races/monkeys/r_neara.dmi' deform = 'icons/mob/human_races/monkeys/r_neara.dmi' - greater_form = "Skrell" + greater_form = /datum/species/skrell default_language = "Neara" flesh_color = "#8CD7A3" blood_color = "#1D2CBF" @@ -162,7 +163,7 @@ deform = 'icons/mob/human_races/monkeys/r_stok.dmi' tail = "stoktail" - greater_form = "Unathi" + greater_form = /datum/species/unathi default_language = "Stok" flesh_color = "#34AF10" base_color = "#000000" diff --git a/code/modules/mob/living/carbon/human/species/nucleation.dm b/code/modules/mob/living/carbon/human/species/nucleation.dm new file mode 100644 index 00000000000..4fcfae74282 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/nucleation.dm @@ -0,0 +1,41 @@ +/datum/species/nucleation + name = "Nucleation" + name_plural = "Nucleations" + icobase = 'icons/mob/human_races/r_nucleation.dmi' + blurb = "A sub-race of unfortunates who have been exposed to too much supermatter radiation. As a result, \ + supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \ + has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \ + negating the need for the individual to breathe. Their massive change in biology, however, renders most medicines \ + obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \ + and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \ + way as lepers were back on Earth." + language = "Sol Common" + burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores + brute_mod = 2 // damn, double wham, double dam + oxy_mod = 0 + species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_SCAN, RADIMMUNE) + dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet + + //Default styles for created mobs. + default_hair = "Nucleation Crystals" + + reagent_tag = PROCESS_ORG + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "crystallized brain" = /obj/item/organ/internal/brain/crystal, + "eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, //Standard darksight of 2. + "strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal + ) + vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal + +/datum/species/nucleation/handle_post_spawn(var/mob/living/carbon/human/H) + H.light_color = "#1C1C00" + H.set_light(2) + return ..() + +/datum/species/nucleation/handle_death(var/mob/living/carbon/human/H) + var/turf/T = get_turf(H) + H.visible_message("[H]'s body explodes, leaving behind a pile of microscopic crystals!") + explosion(T, 0, 0, 2, 2) // Create a small explosion burst upon death +// new /obj/item/shard/supermatter( T ) + qdel(H) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 692a23c470a..46270219735 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -6,6 +6,7 @@ //language = "Clatter" species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING) + skinned_type = /obj/item/stack/sheet/mineral/plasma // We're low on plasma, R&D! *eyes plasmaman co-worker intently* dietflags = DIET_OMNI reagent_tag = PROCESS_ORG diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm index 7480d7e3a66..0e8bd2e91e2 100644 --- a/code/modules/mob/living/carbon/human/species/shadow.dm +++ b/code/modules/mob/living/carbon/human/species/shadow.dm @@ -5,7 +5,6 @@ icobase = 'icons/mob/human_races/r_shadow.dmi' deform = 'icons/mob/human_races/r_shadow.dmi' - default_language = "Galactic Common" unarmed_type = /datum/unarmed_attack/claws ignored_by = list(/mob/living/simple_animal/hostile/faithless) diff --git a/code/modules/mob/living/carbon/human/species/shadowling.dm b/code/modules/mob/living/carbon/human/species/shadowling.dm new file mode 100644 index 00000000000..e7d7982a765 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/shadowling.dm @@ -0,0 +1,85 @@ +/datum/species/shadow/ling + //Normal shadowpeople but with enhanced effects + name = "Shadowling" + + icobase = 'icons/mob/human_races/r_shadowling.dmi' + deform = 'icons/mob/human_races/r_shadowling.dmi' + + blood_color = "#555555" + flesh_color = "#222222" + + species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NOGUNS, NO_EXAMINE) //Can't use guns due to muzzle flash + burn_mod = 1.5 //1.5x burn damage, 2x is excessive + oxy_mod = 0 + heatmod = 1.5 + + silent_steps = 1 + grant_vision_toggle = 0 + + has_organ = list( + "brain" = /obj/item/organ/internal/brain, + "eyes" = /obj/item/organ/internal/eyes) + +/datum/species/shadow/ling/handle_life(var/mob/living/carbon/human/H) + if(!H.weakeyes) + H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs + var/light_amount = 0 + H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry + if(isturf(H.loc)) + var/turf/T = H.loc + light_amount = T.get_lumcount() * 10 + if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) //Can survive in very small light levels. Also doesn't take damage while incorporeal, for shadow walk purposes + H.throw_alert("lightexposure", /obj/screen/alert/lightexposure) + H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN) + if(H.stat != DEAD) + to_chat(H, "The light burns you!")//Message spam to say "GET THE FUCK OUT" + H << 'sound/weapons/sear.ogg' + else if(light_amount < LIGHT_HEAL_THRESHOLD) + H.clear_alert("lightexposure") + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) + if(istype(E)) + E.receive_damage(-1) + H.heal_overall_damage(5, 5) + H.adjustToxLoss(-5) + H.adjustBrainLoss(-25) //Shad O. Ling gibbers, "CAN U BE MY THRALL?!!" + H.AdjustEyeBlurry(-1) + H.CureNearsighted() + H.CureBlind() + H.adjustCloneLoss(-1) + H.SetWeakened(0) + H.SetStunned(0) + ..() + + +/datum/species/shadow/ling/lesser //Empowered thralls. Obvious, but powerful + name = "Lesser Shadowling" + + icobase = 'icons/mob/human_races/r_lshadowling.dmi' + deform = 'icons/mob/human_races/r_lshadowling.dmi' + + blood_color = "#CCCCCC" + flesh_color = "#AAAAAA" + + species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE) + burn_mod = 1.1 + oxy_mod = 0 + heatmod = 1.1 + +/datum/species/shadow/ling/lesser/handle_life(var/mob/living/carbon/human/H) + if(!H.weakeyes) + H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs + var/light_amount = 0 + H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry + if(isturf(H.loc)) + var/turf/T = H.loc + light_amount = T.get_lumcount() * 10 + if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) + H.throw_alert("lightexposure", /obj/screen/alert/lightexposure) + H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN/2) + else if(light_amount < LIGHT_HEAL_THRESHOLD) + H.clear_alert("lightexposure") + H.heal_overall_damage(2,2) + H.adjustToxLoss(-5) + H.adjustBrainLoss(-25) + H.adjustCloneLoss(-1) + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm index 9da4d1222f6..8afc35f743a 100644 --- a/code/modules/mob/living/carbon/human/species/skeleton.dm +++ b/code/modules/mob/living/carbon/human/species/skeleton.dm @@ -6,13 +6,12 @@ icobase = 'icons/mob/human_races/r_skeleton.dmi' deform = 'icons/mob/human_races/r_skeleton.dmi' - path = /mob/living/carbon/human/skeleton - default_language = "Galactic Common" blood_color = "#FFFFFF" flesh_color = "#E6E6C6" species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE) + skinned_type = /obj/item/stack/sheet/bone oxy_mod = 0 diff --git a/code/modules/mob/living/carbon/human/species/skrell.dm b/code/modules/mob/living/carbon/human/species/skrell.dm new file mode 100644 index 00000000000..a7c24cd338c --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/skrell.dm @@ -0,0 +1,46 @@ +/datum/species/skrell + name = "Skrell" + name_plural = "Skrell" + icobase = 'icons/mob/human_races/r_skrell.dmi' + deform = 'icons/mob/human_races/r_def_skrell.dmi' + language = "Skrellian" + primitive_form = /datum/species/monkey/skrell + + blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ + the royals' or 'Light of the Crown'.

    Skrell are a highly advanced and logical race who live under the rule \ + of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \ + herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ + the secrets of their empire to their allies." + + species_traits = list(LIPS) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_SKIN_COLOR | HAS_BODY_MARKINGS + dietflags = DIET_HERB + taste_sensitivity = TASTE_SENSITIVITY_DULL + flesh_color = "#8CD7A3" + blood_color = "#1D2CBF" + base_color = "#38b661" //RGB: 56, 182, 97. + default_hair_colour = "#38b661" + eyes = "skrell_eyes_s" + //Default styles for created mobs. + default_hair = "Skrell Male Tentacles" + reagent_tag = PROCESS_ORG + butt_sprite = "skrell" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/skrell, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. + "headpocket" = /obj/item/organ/internal/headpocket + ) + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their thumbs into their eye sockets!", + "is twisting their own neck!", + "makes like a fish and suffocates!", + "is strangling themselves with their own tendrils!") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm new file mode 100644 index 00000000000..77fa54491e0 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/slime.dm @@ -0,0 +1,200 @@ +/datum/species/slime + name = "Slime People" + name_plural = "Slime People" + language = "Bubblish" + icobase = 'icons/mob/human_races/r_slime.dmi' + deform = 'icons/mob/human_races/r_slime.dmi' + remains_type = /obj/effect/decal/remains/slime + + // More sensitive to the cold + cold_level_1 = 280 + cold_level_2 = 240 + cold_level_3 = 200 + coldmod = 3 + + oxy_mod = 0 + brain_mod = 2.5 + + male_cough_sounds = list('sound/effects/slime_squish.ogg') + female_cough_sounds = list('sound/effects/slime_squish.ogg') + + species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_INTORGANS, NO_SCAN) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_SKIN_COLOR | NO_EYES + dietflags = DIET_CARN + reagent_tag = PROCESS_ORG + + blood_color = "#0064C8" + exotic_blood = "water" + blood_damage_type = TOX + + butt_sprite = "slime" + //Has default darksight of 2. + + has_organ = list( + "brain" = /obj/item/organ/internal/brain/slime + ) + + suicide_messages = list( + "is melting into a puddle!", + "is ripping out their own core!", + "is turning a dull, brown color and melting into a puddle!") + + var/reagent_skin_coloring = FALSE + + var/datum/action/innate/regrow/grow = new() + + species_abilities = list( + /mob/living/carbon/human/verb/toggle_recolor_verb, + /mob/living/carbon/human/proc/regrow_limbs + ) + +/datum/species/slime/handle_post_spawn(var/mob/living/carbon/human/H) + grow.Grant(H) + ..() + +/datum/action/innate/regrow + name = "Regrow limbs" + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "greenglow" + +/datum/action/innate/regrow/Activate() + var/mob/living/carbon/human/user = owner + user.regrow_limbs() + + +/datum/species/slime/handle_life(var/mob/living/carbon/human/H) +//This is allegedly for code "style". Like a plaid sweater? +#define SLIMEPERSON_COLOR_SHIFT_TRIGGER 0.1 +#define SLIMEPERSON_ICON_UPDATE_PERIOD 200 // 20 seconds +#define SLIMEPERSON_BLOOD_SCALING_FACTOR 5 // Used to adjust how much of an effect the blood has on the rate of color change. Higher is slower. + // Slowly shifting to the color of the reagents + if(reagent_skin_coloring && H.reagents.total_volume > SLIMEPERSON_COLOR_SHIFT_TRIGGER) + var/blood_amount = H.blood_volume + var/r_color = mix_color_from_reagents(H.reagents.reagent_list) + var/new_body_color = BlendRGB(r_color, H.skin_colour, (blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)/((blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)+(H.reagents.total_volume))) + H.skin_colour = new_body_color + if(world.time % SLIMEPERSON_ICON_UPDATE_PERIOD > SLIMEPERSON_ICON_UPDATE_PERIOD - 20) // The 20 is because this gets called every 2 seconds, from the mob controller + for(var/organname in H.bodyparts_by_name) + var/obj/item/organ/external/E = H.bodyparts_by_name[organname] + if(istype(E) && E.dna && istype(E.dna.species, /datum/species/slime)) + E.sync_colour_to_human(H) + H.update_hair(0) + H.update_body() + ..() + +#undef SLIMEPERSON_COLOR_SHIFT_TRIGGER +#undef SLIMEPERSON_ICON_UPDATE_PERIOD +#undef SLIMEPERSON_BLOOD_SCALING_FACTOR + +/mob/living/carbon/human/proc/toggle_recolor(silent = FALSE) + if(!isslimeperson(src)) + if(!silent) + to_chat(src, "You're not a slime person!") + return + + var/datum/species/slime/S = dna.species + if(S.reagent_skin_coloring) + S.reagent_skin_coloring = TRUE + if(!silent) + to_chat(src, "You adjust your internal chemistry to filter out pigments from things you consume.") + else + S.reagent_skin_coloring = TRUE + if(!silent) + to_chat(src, "You adjust your internal chemistry to permit pigments in chemicals you consume to tint you.") + +/mob/living/carbon/human/verb/toggle_recolor_verb() + set category = "IC" + set name = "Toggle Reagent Recoloring" + set desc = "While active, you'll slowly adjust your body's color to that of the reagents inside of you, moderated by how much blood you have." + + toggle_recolor() + + +/mob/living/carbon/human/proc/regrow_limbs() + set category = "IC" + set name = "Regrow Limbs" + set desc = "Regrow one of your missing limbs at the cost of a large amount of hunger" + +#define SLIMEPERSON_HUNGERCOST 50 +#define SLIMEPERSON_MINHUNGER 250 +#define SLIMEPERSON_REGROWTHDELAY 450 // 45 seconds + + if(stat || paralysis || stunned) + to_chat(src, "You cannot regenerate missing limbs in your current state.") + return + + if(nutrition < SLIMEPERSON_MINHUNGER) + to_chat(src, "You're too hungry to regenerate a limb!") + return + + var/list/missing_limbs = list() + for(var/l in bodyparts_by_name) + var/obj/item/organ/external/E = bodyparts_by_name[l] + if(!istype(E)) + var/list/limblist = dna.species.has_limbs[l] + var/obj/item/organ/external/limb = limblist["path"] + var/parent_organ = initial(limb.parent_organ) + var/obj/item/organ/external/parentLimb = bodyparts_by_name[parent_organ] + if(!istype(parentLimb)) + continue + missing_limbs[initial(limb.name)] = l + + if(!missing_limbs.len) + to_chat(src, "You're not missing any limbs!") + return + + var/limb_select = input(src, "Choose a limb to regrow", "Limb Regrowth") as null|anything in missing_limbs + var/chosen_limb = missing_limbs[limb_select] + + visible_message("[src] begins to hold still and concentrate on [p_their()] missing [limb_select]...", "You begin to focus on regrowing your missing [limb_select]... (This will take [round(SLIMEPERSON_REGROWTHDELAY/10)] seconds, and you must hold still.)") + if(do_after(src, SLIMEPERSON_REGROWTHDELAY, needhand=0, target = src)) + if(stat || paralysis || stunned) + to_chat(src, "You cannot regenerate missing limbs in your current state.") + return + + if(nutrition < SLIMEPERSON_MINHUNGER) + to_chat(src, "You're too hungry to regenerate a limb!") + return + + var/obj/item/organ/external/O = bodyparts_by_name[chosen_limb] + + var/stored_brute = 0 + var/stored_burn = 0 + if(istype(O)) + to_chat(src, "You distribute the damaged tissue around your body, out of the way of your new pseudopod!") + var/obj/item/organ/external/doomedStump = O + stored_brute = doomedStump.brute_dam + stored_burn = doomedStump.burn_dam + qdel(O) + + var/limb_list = dna.species.has_limbs[chosen_limb] + var/obj/item/organ/external/limb_path = limb_list["path"] + // Parent check + var/obj/item/organ/external/potential_parent = bodyparts_by_name[initial(limb_path.parent_organ)] + if(!istype(potential_parent)) + to_chat(src, "You've lost the organ that you've been growing your new part on!") + return // No rayman for you + // Grah this line will leave a "not used" warning, in spite of the fact that the new() proc WILL do the thing. + // Bothersome. + var/obj/item/organ/external/new_limb = new limb_path(src) + new_limb.open = 0 // This is just so that the compiler won't think that new_limb is unused, because the compiler is horribly stupid. + adjustBruteLoss(stored_brute) + adjustFireLoss(stored_burn) + update_body() + updatehealth() + UpdateDamageIcon() + nutrition -= SLIMEPERSON_HUNGERCOST + visible_message("[src] finishes regrowing [p_their()] missing [new_limb]!", "You finish regrowing your [limb_select]") + else + to_chat(src, "You need to hold still in order to regrow a limb!") + return + +#undef SLIMEPERSON_HUNGERCOST +#undef SLIMEPERSON_MINHUNGER +#undef SLIMEPERSON_REGROWTHDELAY + +/datum/species/slime/handle_pre_change(mob/living/carbon/human/H) + ..() + if(reagent_skin_coloring) + H.toggle_recolor(silent = 1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm deleted file mode 100644 index 6b692601226..00000000000 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ /dev/null @@ -1,1068 +0,0 @@ -/datum/species/human - name = "Human" - name_plural = "Humans" - icobase = 'icons/mob/human_races/r_human.dmi' - deform = 'icons/mob/human_races/r_def_human.dmi' - primitive_form = "Monkey" - path = /mob/living/carbon/human/human - language = "Sol Common" - species_traits = list(LIPS, CAN_BE_FAT) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS - dietflags = DIET_OMNI - blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ - colonies across a wide swathe of space. They hold a wide range of forms and creeds.

    \ - While the central Sol government maintains control of its far-flung people, powerful corporate \ - interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ - worlds tumultous at best." - - reagent_tag = PROCESS_ORG - //Has standard darksight of 2. - -/datum/species/unathi - name = "Unathi" - name_plural = "Unathi" - icobase = 'icons/mob/human_races/r_lizard.dmi' - deform = 'icons/mob/human_races/r_def_lizard.dmi' - path = /mob/living/carbon/human/unathi - default_language = "Galactic Common" - language = "Sinta'unathi" - tail = "sogtail" - unarmed_type = /datum/unarmed_attack/claws - primitive_form = "Stok" - - blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \ - Uuosa-Eso system, which roughly translates to 'burning mother'.

    Coming from a harsh, radioactive \ - desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \ - else, frequently even their own lives. They prefer warmer temperatures than most species and \ - their native tongue is a heavy hissing laungage called Sinta'Unathi." - - species_traits = list(LIPS) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_BODY_MARKINGS | HAS_HEAD_MARKINGS | HAS_SKIN_COLOR | HAS_ALT_HEADS | TAIL_WAGGING - dietflags = DIET_CARN - - cold_level_1 = 280 //Default 260 - Lower is better - cold_level_2 = 220 //Default 200 - cold_level_3 = 140 //Default 120 - - heat_level_1 = 380 //Default 360 - Higher is better - heat_level_2 = 420 //Default 400 - heat_level_3 = 480 //Default 460 - - flesh_color = "#34AF10" - reagent_tag = PROCESS_ORG - base_color = "#066000" - //Default styles for created mobs. - default_headacc = "Simple" - default_headacc_colour = "#404040" - butt_sprite = "unathi" - brute_mod = 1.05 - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/unathi, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes/unathi //3 darksight. - ) - - allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, - /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!") - - var/datum/action/innate/tail_lash/lash = new() - - -/datum/species/unathi/handle_post_spawn(var/mob/living/carbon/human/H) - lash.Grant(H) - ..() - -/datum/action/innate/tail_lash - name = "Tail lash" - icon_icon = 'icons/effects/effects.dmi' - button_icon_state = "tail" - -/datum/action/innate/tail_lash/Activate() - var/mob/living/carbon/human/user = owner - if(!user.restrained() || !user.buckled) - to_chat(user, "You need freedom of movement to tail lash!") - return - if(user.getStaminaLoss() >= 50) - to_chat(user, "Rest before tail lashing again!") - return - for(var/mob/living/carbon/human/C in orange(1)) - var/obj/item/organ/external/E = C.get_organ(pick("l_leg", "r_leg", "l_foot", "r_foot", "groin")) - if(E) - user.changeNext_move(CLICK_CD_MELEE) - user.visible_message("[src] smacks [C] in [E] with their tail! ", "You hit [C] in [E] with your tail!") - user.adjustStaminaLoss(15) - C.apply_damage(5, BRUTE, E) - user.spin(20, 1) - playsound(user.loc, 'sound/weapons/slash.ogg', 50, 0) - - - -/datum/species/unathi/handle_death(var/mob/living/carbon/human/H) - H.stop_tail_wagging(1) - -/datum/species/tajaran - name = "Tajaran" - name_plural = "Tajaran" - icobase = 'icons/mob/human_races/r_tajaran.dmi' - deform = 'icons/mob/human_races/r_def_tajaran.dmi' - path = /mob/living/carbon/human/tajaran - default_language = "Galactic Common" - language = "Siik'tajr" - tail = "tajtail" - unarmed_type = /datum/unarmed_attack/claws - - blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \ - S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \ - influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ - of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \ - using unique inflections their mouths form." - - cold_level_1 = 240 - cold_level_2 = 180 - cold_level_3 = 100 - - heat_level_1 = 340 - heat_level_2 = 380 - heat_level_3 = 440 - - primitive_form = "Farwa" - - species_traits = list(LIPS, CAN_BE_FAT) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING - dietflags = DIET_OMNI - taste_sensitivity = TASTE_SENSITIVITY_SHARP - reagent_tag = PROCESS_ORG - flesh_color = "#AFA59E" - base_color = "#424242" - butt_sprite = "tajaran" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/tajaran, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes/tajaran /*Most Tajara see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2) - unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/ - ) - - allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/chick, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, - /mob/living/simple_animal/tribble) - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!") - -/datum/species/tajaran/handle_death(var/mob/living/carbon/human/H) - H.stop_tail_wagging(1) - -/datum/species/vulpkanin - name = "Vulpkanin" - name_plural = "Vulpkanin" - icobase = 'icons/mob/human_races/r_vulpkanin.dmi' - deform = 'icons/mob/human_races/r_vulpkanin.dmi' - path = /mob/living/carbon/human/vulpkanin - default_language = "Galactic Common" - language = "Canilunzt" - primitive_form = "Wolpin" - tail = "vulptail" - unarmed_type = /datum/unarmed_attack/claws - - blurb = "Vulpkanin are a species of sharp-witted canine-pideds residing on the planet Altam just barely within the \ - dual-star Vazzend system. Their politically de-centralized society and independent natures have led them to become a species and \ - culture both feared and respected for their scientific breakthroughs. Discovery, loyalty, and utilitarianism dominates their lifestyles \ - to the degree it can cause conflict with more rigorous and strict authorities. They speak a guttural language known as 'Canilunzt' \ - which has a heavy emphasis on utilizing tail positioning and ear twitches to communicate intent." - - species_traits = list(LIPS) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR - dietflags = DIET_OMNI - hunger_drain = 0.11 - taste_sensitivity = TASTE_SENSITIVITY_SHARP - reagent_tag = PROCESS_ORG - flesh_color = "#966464" - base_color = "#CF4D2F" - butt_sprite = "vulp" - - scream_verb = "yelps" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/vulpkanin, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes/vulpkanin /*Most Vulpkanin see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2) - unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/ - ) - - allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, - /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!") - -/datum/species/vulpkanin/handle_death(var/mob/living/carbon/human/H) - H.stop_tail_wagging(1) - -/datum/species/skrell - name = "Skrell" - name_plural = "Skrell" - icobase = 'icons/mob/human_races/r_skrell.dmi' - deform = 'icons/mob/human_races/r_def_skrell.dmi' - path = /mob/living/carbon/human/skrell - default_language = "Galactic Common" - language = "Skrellian" - primitive_form = "Neara" - - blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ - the royals' or 'Light of the Crown'.

    Skrell are a highly advanced and logical race who live under the rule \ - of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \ - herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ - the secrets of their empire to their allies." - - species_traits = list(LIPS) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | HAS_BODY_MARKINGS - dietflags = DIET_HERB - taste_sensitivity = TASTE_SENSITIVITY_DULL - flesh_color = "#8CD7A3" - blood_color = "#1D2CBF" - base_color = "#38b661" //RGB: 56, 182, 97. - default_hair_colour = "#38b661" - eyes = "skrell_eyes_s" - //Default styles for created mobs. - default_hair = "Skrell Male Tentacles" - reagent_tag = PROCESS_ORG - butt_sprite = "skrell" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/skrell, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. - "headpocket" = /obj/item/organ/internal/headpocket - ) - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their thumbs into their eye sockets!", - "is twisting their own neck!", - "makes like a fish and suffocates!", - "is strangling themselves with their own tendrils!") - -/datum/species/vox - name = "Vox" - name_plural = "Vox" - icobase = 'icons/mob/human_races/vox/r_vox.dmi' - deform = 'icons/mob/human_races/vox/r_def_vox.dmi' - path = /mob/living/carbon/human/vox - - default_language = "Galactic Common" - language = "Vox-pidgin" - tail = "voxtail" - speech_sounds = list('sound/voice/shriek1.ogg') - speech_chance = 20 - unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too. - - blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ - scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \ - alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \ - refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \ - smell.

    Most humans will never meet a Vox raider, instead learning of this insular species through \ - dealing with their traders and merchants; those that do rarely enjoy the experience." - - brute_mod = 1.2 //20% more brute damage. Fragile bird bones. - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - breathid = "n2" - - eyes = "vox_eyes_s" - - species_traits = list(NO_SCAN, IS_WHITELISTED, NOTRANSSTING) - clothing_flags = HAS_SOCKS - dietflags = DIET_OMNI - bodyflags = HAS_ICON_SKIN_TONE | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_BODY_MARKINGS | HAS_TAIL_MARKINGS - - blood_color = "#2299FC" - flesh_color = "#808D11" - //Default styles for created mobs. - default_hair = "Short Vox Quills" - default_hair_colour = "#614f19" //R: 97, G: 79, B: 25 - butt_sprite = "vox" - - reagent_tag = PROCESS_ORG - scream_verb = "shrieks" - male_scream_sound = 'sound/voice/shriek1.ogg' - female_scream_sound = 'sound/voice/shriek1.ogg' - male_cough_sounds = list('sound/voice/shriekcough.ogg') - female_cough_sounds = list('sound/voice/shriekcough.ogg') - male_sneeze_sound = 'sound/voice/shrieksneeze.ogg' - female_sneeze_sound = 'sound/voice/shrieksneeze.ogg' - - icon_skin_tones = list( - 1 = "Default Green", - 2 = "Dark Green", - 3 = "Brown", - 4 = "Grey", - 5 = "Emerald", - 6 = "Azure" - ) - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs/vox, - "liver" = /obj/item/organ/internal/liver/vox, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. - "stack" = /obj/item/organ/internal/stack/vox //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used - ) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ. - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!", - "is deeply inhaling oxygen!") - -/datum/species/vox/handle_death(var/mob/living/carbon/human/H) - H.stop_tail_wagging(1) - -/datum/species/vox/makeName(var/gender,var/mob/living/carbon/human/H=null) - var/sounds = rand(2,8) - var/i = 0 - var/newname = "" - - while(i<=sounds) - i++ - newname += pick(vox_name_syllables) - return capitalize(newname) - -/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H) - if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime") - H.unEquip(H.wear_mask) - H.unEquip(H.l_hand) - - H.equip_or_collect(new /obj/item/clothing/mask/breath/vox(H), slot_wear_mask) - var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null - if(tank_pref)//Diseasel, here you go - H.equip_or_collect(new /obj/item/tank/nitrogen(H), slot_l_hand) - else - H.equip_or_collect(new /obj/item/tank/emergency_oxygen/vox(H), slot_l_hand) - to_chat(H, "You are now running on nitrogen internals from the [H.l_hand] in your hand. Your species finds oxygen toxic, so you must breathe nitrogen only.") - H.internal = H.l_hand - H.update_action_buttons_icon() - -/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H) - updatespeciescolor(H) - H.update_icons() - //H.verbs += /mob/living/carbon/human/proc/leap - ..() - -/datum/species/vox/updatespeciescolor(var/mob/living/carbon/human/H, var/owner_sensitive = 1) //Handling species-specific skin-tones for the Vox race. - if(H.species.bodyflags & HAS_ICON_SKIN_TONE) //Making sure we don't break Armalis. - var/new_icobase = 'icons/mob/human_races/vox/r_vox.dmi' //Default Green Vox. - var/new_deform = 'icons/mob/human_races/vox/r_def_vox.dmi' //Default Green Vox. - switch(H.s_tone) - if(6) //Azure Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxazu.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxazu.dmi' - H.tail = "voxtail_azu" - if(5) //Emerald Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxemrl.dmi' - H.tail = "voxtail_emrl" - if(4) //Grey Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxgry.dmi' - H.tail = "voxtail_gry" - if(3) //Brown Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxbrn.dmi' - H.tail = "voxtail_brn" - if(2) //Dark Green Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxdgrn.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxdgrn.dmi' - H.tail = "voxtail_dgrn" - else //Default Green Vox. - H.tail = "voxtail" //Ensures they get an appropriately coloured tail depending on the skin-tone. - - H.change_icobase(new_icobase, new_deform, owner_sensitive) //Update the icobase/deform of all our organs, but make sure we don't mess with frankenstein limbs in doing so. - H.update_dna() - -/datum/species/vox/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R) - if(R.id == "oxygen") //Armalis are above such petty things. - H.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER) //Same as plasma. - H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM) - return 0 //Handling reagent removal on our own. - - return ..() - -/datum/species/vox/armalis/handle_post_spawn(var/mob/living/carbon/human/H) - H.verbs += /mob/living/carbon/human/proc/leap - H.verbs += /mob/living/carbon/human/proc/gut - ..() - -/datum/species/vox/armalis - name = "Vox Armalis" - name_plural = "Vox Armalis" - icobase = 'icons/mob/human_races/r_armalis.dmi' - deform = 'icons/mob/human_races/r_armalis.dmi' - path = /mob/living/carbon/human/voxarmalis - unarmed_type = /datum/unarmed_attack/claws/armalis - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - heat_level_1 = 2000 - heat_level_2 = 3000 - heat_level_3 = 4000 - - brute_mod = 0.2 - burn_mod = 0.2 - - eyes = "blank_eyes" - - species_traits = list(NO_SCAN, NO_BLOOD, NO_PAIN, IS_WHITELISTED) - bodyflags = HAS_TAIL - dietflags = DIET_OMNI //should inherit this from vox, this is here just in case - - blood_color = "#2299FC" - flesh_color = "#808D11" - - reagent_tag = PROCESS_ORG - - tail = "armalis_tail" - icon_template = 'icons/mob/human_races/r_armalis.dmi' - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs/vox, - "liver" = /obj/item/organ/internal/liver, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. - "stack" = /obj/item/organ/internal/stack/vox //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used - ) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ. - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!", - "is huffing oxygen!") - -/datum/species/vox/armalis/handle_reagents() //Skip the Vox oxygen reagent toxicity. Armalis are above such things. - return 1 - -/datum/species/kidan - name = "Kidan" - name_plural = "Kidan" - icobase = 'icons/mob/human_races/r_kidan.dmi' - deform = 'icons/mob/human_races/r_def_kidan.dmi' - path = /mob/living/carbon/human/kidan - default_language = "Galactic Common" - language = "Chittin" - unarmed_type = /datum/unarmed_attack/claws - - brute_mod = 0.8 - - species_traits = list(IS_WHITELISTED) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS - eyes = "kidan_eyes_s" - dietflags = DIET_HERB - blood_color = "#FB9800" - reagent_tag = PROCESS_ORG - //Default styles for created mobs. - default_headacc = "Normal Antennae" - butt_sprite = "kidan" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/kidan, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. - "lantern" = /obj/item/organ/internal/lantern - ) - - allowed_consumed_mobs = list(/mob/living/simple_animal/diona) - - suicide_messages = list( - "is attempting to bite their antenna off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is cracking their exoskeleton!", - "is stabbing themselves with their mandibles!", - "is holding their breath!") - -/datum/species/slime - name = "Slime People" - name_plural = "Slime People" - default_language = "Galactic Common" - language = "Bubblish" - icobase = 'icons/mob/human_races/r_slime.dmi' - deform = 'icons/mob/human_races/r_slime.dmi' - path = /mob/living/carbon/human/slime - remains_type = /obj/effect/decal/remains/slime - - // More sensitive to the cold - cold_level_1 = 280 - cold_level_2 = 240 - cold_level_3 = 200 - coldmod = 3 - - oxy_mod = 0 - brain_mod = 2.5 - - male_cough_sounds = list('sound/effects/slime_squish.ogg') - female_cough_sounds = list('sound/effects/slime_squish.ogg') - - species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_INTORGANS, NO_SCAN) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | NO_EYES - dietflags = DIET_CARN - reagent_tag = PROCESS_ORG - - blood_color = "#0064C8" - exotic_blood = "water" - blood_damage_type = TOX - - butt_sprite = "slime" - //Has default darksight of 2. - - has_organ = list( - "brain" = /obj/item/organ/internal/brain/slime - ) - - suicide_messages = list( - "is melting into a puddle!", - "is ripping out their own core!", - "is turning a dull, brown color and melting into a puddle!") - - var/list/mob/living/carbon/human/recolor_list = list() - - var/datum/action/innate/regrow/grow = new() - - species_abilities = list( - /mob/living/carbon/human/verb/toggle_recolor_verb, - /mob/living/carbon/human/proc/regrow_limbs - ) - -/datum/species/slime/handle_post_spawn(var/mob/living/carbon/human/H) - grow.Grant(H) - ..() - -/datum/action/innate/regrow - name = "Regrow limbs" - icon_icon = 'icons/effects/effects.dmi' - button_icon_state = "greenglow" - -/datum/action/innate/regrow/Activate() - var/mob/living/carbon/human/user = owner - user.regrow_limbs() - - -/datum/species/slime/handle_life(var/mob/living/carbon/human/H) -//This is allegedly for code "style". Like a plaid sweater? -#define SLIMEPERSON_COLOR_SHIFT_TRIGGER 0.1 -#define SLIMEPERSON_ICON_UPDATE_PERIOD 200 // 20 seconds -#define SLIMEPERSON_BLOOD_SCALING_FACTOR 5 // Used to adjust how much of an effect the blood has on the rate of color change. Higher is slower. - // Slowly shifting to the color of the reagents - if((H in recolor_list) && H.reagents.total_volume > SLIMEPERSON_COLOR_SHIFT_TRIGGER) - var/blood_amount = H.blood_volume - var/r_color = mix_color_from_reagents(H.reagents.reagent_list) - var/new_body_color = BlendRGB(r_color, H.skin_colour, (blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)/((blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)+(H.reagents.total_volume))) - H.skin_colour = new_body_color - if(world.time % SLIMEPERSON_ICON_UPDATE_PERIOD > SLIMEPERSON_ICON_UPDATE_PERIOD - 20) // The 20 is because this gets called every 2 seconds, from the mob controller - for(var/organname in H.bodyparts_by_name) - var/obj/item/organ/external/E = H.bodyparts_by_name[organname] - if(istype(E) && E.dna.species == "Slime People") - E.sync_colour_to_human(H) - H.update_hair(0) - H.update_body() - ..() - -#undef SLIMEPERSON_COLOR_SHIFT_TRIGGER -#undef SLIMEPERSON_ICON_UPDATE_PERIOD -#undef SLIMEPERSON_BLOOD_SCALING_FACTOR - -/mob/living/carbon/human/proc/toggle_recolor(var/silent = 0) - var/datum/species/slime/S = all_species[get_species()] - if(!istype(S)) - if(!silent) - to_chat(src, "You're not a slime person!") - return - - if(src in S.recolor_list) - S.recolor_list -= src - if(!silent) - to_chat(src, "You adjust your internal chemistry to filter out pigments from things you consume.") - else - S.recolor_list += src - if(!silent) - to_chat(src, "You adjust your internal chemistry to permit pigments in chemicals you consume to tint you.") - -/mob/living/carbon/human/verb/toggle_recolor_verb() - set category = "IC" - set name = "Toggle Reagent Recoloring" - set desc = "While active, you'll slowly adjust your body's color to that of the reagents inside of you, moderated by how much blood you have." - - toggle_recolor() - - -/mob/living/carbon/human/proc/regrow_limbs() - set category = "IC" - set name = "Regrow Limbs" - set desc = "Regrow one of your missing limbs at the cost of a large amount of hunger" - -#define SLIMEPERSON_HUNGERCOST 50 -#define SLIMEPERSON_MINHUNGER 250 -#define SLIMEPERSON_REGROWTHDELAY 450 // 45 seconds - - if(stat || paralysis || stunned) - to_chat(src, "You cannot regenerate missing limbs in your current state.") - return - - if(nutrition < SLIMEPERSON_MINHUNGER) - to_chat(src, "You're too hungry to regenerate a limb!") - return - - var/list/missing_limbs = list() - for(var/l in bodyparts_by_name) - var/obj/item/organ/external/E = bodyparts_by_name[l] - if(!istype(E)) - var/list/limblist = species.has_limbs[l] - var/obj/item/organ/external/limb = limblist["path"] - var/parent_organ = initial(limb.parent_organ) - var/obj/item/organ/external/parentLimb = bodyparts_by_name[parent_organ] - if(!istype(parentLimb)) - continue - missing_limbs[initial(limb.name)] = l - - if(!missing_limbs.len) - to_chat(src, "You're not missing any limbs!") - return - - var/limb_select = input(src, "Choose a limb to regrow", "Limb Regrowth") as null|anything in missing_limbs - var/chosen_limb = missing_limbs[limb_select] - - visible_message("[src] begins to hold still and concentrate on [p_their()] missing [limb_select]...", "You begin to focus on regrowing your missing [limb_select]... (This will take [round(SLIMEPERSON_REGROWTHDELAY/10)] seconds, and you must hold still.)") - if(do_after(src, SLIMEPERSON_REGROWTHDELAY, needhand=0, target = src)) - if(stat || paralysis || stunned) - to_chat(src, "You cannot regenerate missing limbs in your current state.") - return - - if(nutrition < SLIMEPERSON_MINHUNGER) - to_chat(src, "You're too hungry to regenerate a limb!") - return - - var/obj/item/organ/external/O = bodyparts_by_name[chosen_limb] - - var/stored_brute = 0 - var/stored_burn = 0 - if(istype(O)) - to_chat(src, "You distribute the damaged tissue around your body, out of the way of your new pseudopod!") - var/obj/item/organ/external/doomedStump = O - stored_brute = doomedStump.brute_dam - stored_burn = doomedStump.burn_dam - qdel(O) - - var/limb_list = species.has_limbs[chosen_limb] - var/obj/item/organ/external/limb_path = limb_list["path"] - // Parent check - var/obj/item/organ/external/potential_parent = bodyparts_by_name[initial(limb_path.parent_organ)] - if(!istype(potential_parent)) - to_chat(src, "You've lost the organ that you've been growing your new part on!") - return // No rayman for you - // Grah this line will leave a "not used" warning, in spite of the fact that the new() proc WILL do the thing. - // Bothersome. - var/obj/item/organ/external/new_limb = new limb_path(src) - new_limb.open = 0 // This is just so that the compiler won't think that new_limb is unused, because the compiler is horribly stupid. - adjustBruteLoss(stored_brute) - adjustFireLoss(stored_burn) - update_body() - updatehealth() - UpdateDamageIcon() - nutrition -= SLIMEPERSON_HUNGERCOST - visible_message("[src] finishes regrowing [p_their()] missing [new_limb]!", "You finish regrowing your [limb_select]") - else - to_chat(src, "You need to hold still in order to regrow a limb!") - return - -#undef SLIMEPERSON_HUNGERCOST -#undef SLIMEPERSON_MINHUNGER -#undef SLIMEPERSON_REGROWTHDELAY - -/datum/species/slime/handle_pre_change(var/mob/living/carbon/human/H) - ..() - if(H in recolor_list) - H.toggle_recolor(silent = 1) - -/datum/species/grey - name = "Grey" - name_plural = "Greys" - icobase = 'icons/mob/human_races/r_grey.dmi' - deform = 'icons/mob/human_races/r_def_grey.dmi' - default_language = "Galactic Common" - language = "Psionic Communication" - eyes = "grey_eyes_s" - butt_sprite = "grey" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/grey, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain/grey, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes/grey //5 darksight. - ) - - brute_mod = 1.25 //greys are fragile - - default_genes = list(REMOTE_TALK) - - - species_traits = list(LIPS, IS_WHITELISTED, CAN_BE_FAT) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_BODY_MARKINGS - dietflags = DIET_HERB - reagent_tag = PROCESS_ORG - blood_color = "#A200FF" - -/datum/species/grey/handle_dna(var/mob/living/carbon/C, var/remove) - if(!remove) - C.dna.SetSEState(REMOTETALKBLOCK,1,1) - genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) - else - C.dna.SetSEState(REMOTETALKBLOCK,0,1) - genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) - ..() - -/datum/species/grey/water_act(var/mob/living/carbon/C, volume, temperature, source) - ..() - C.take_organ_damage(5,min(volume,20)) - C.emote("scream") - -/datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H) - var/speech_pref = H.client.prefs.speciesprefs - if(speech_pref) - H.mind.speech_span = "wingdings" - -/datum/species/grey/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) - if(R.id == "sacid") - H.reagents.del_reagent(R.id) - return 0 - return ..() - -/datum/species/diona - name = "Diona" - name_plural = "Dionaea" - icobase = 'icons/mob/human_races/r_diona.dmi' - deform = 'icons/mob/human_races/r_def_plant.dmi' - path = /mob/living/carbon/human/diona - default_language = "Galactic Common" - language = "Rootspeak" - speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16] - speech_chance = 20 - unarmed_type = /datum/unarmed_attack/diona - //primitive_form = "Nymph" - slowdown = 5 - remains_type = /obj/effect/decal/cleanable/ash - - - warning_low_pressure = 50 - hazard_low_pressure = -1 - - cold_level_1 = 50 - cold_level_2 = -1 - cold_level_3 = -1 - - heat_level_1 = 300 - heat_level_2 = 340 - heat_level_3 = 400 - - blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ - species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ - there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \ - Minoris primary being ringed with a cloud of singing space-station-sized entities.

    The Dionaea coexist peacefully with \ - all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \ - even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ - water and other radiation." - - species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN) - clothing_flags = HAS_SOCKS - default_hair_colour = "#000000" - dietflags = 0 //Diona regenerate nutrition in light and water, no diet necessary - taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE - - oxy_mod = 0 - - body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not - blood_color = "#004400" - flesh_color = "#907E4A" - butt_sprite = "diona" - - reagent_tag = PROCESS_ORG - - has_organ = list( - "nutrient channel" = /obj/item/organ/internal/liver/diona, - "neural strata" = /obj/item/organ/internal/heart/diona, - "receptor node" = /obj/item/organ/internal/eyes/diona, //Default darksight of 2. - "gas bladder" = /obj/item/organ/internal/brain/diona, - "polyp segment" = /obj/item/organ/internal/kidneys/diona, - "anchoring ligament" = /obj/item/organ/internal/appendix/diona - ) - - vision_organ = /obj/item/organ/internal/eyes/diona - has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest/diona), - "groin" = list("path" = /obj/item/organ/external/groin/diona), - "head" = list("path" = /obj/item/organ/external/head/diona), - "l_arm" = list("path" = /obj/item/organ/external/arm/diona), - "r_arm" = list("path" = /obj/item/organ/external/arm/right/diona), - "l_leg" = list("path" = /obj/item/organ/external/leg/diona), - "r_leg" = list("path" = /obj/item/organ/external/leg/right/diona), - "l_hand" = list("path" = /obj/item/organ/external/hand/diona), - "r_hand" = list("path" = /obj/item/organ/external/hand/right/diona), - "l_foot" = list("path" = /obj/item/organ/external/foot/diona), - "r_foot" = list("path" = /obj/item/organ/external/foot/right/diona) - ) - - suicide_messages = list( - "is losing branches!", - "pulls out a secret stash of herbicide and takes a hearty swig!", - "is pulling themselves apart!") - -/datum/species/diona/can_understand(var/mob/other) - if(istype(other, /mob/living/simple_animal/diona)) - return 1 - return 0 - -/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H) - H.gender = NEUTER - - return ..() - -/datum/species/diona/handle_life(var/mob/living/carbon/human/H) - H.radiation = Clamp(H.radiation, 0, 100) //We have to clamp this first, then decrease it, or there's a few edge cases of massive heals if we clamp and decrease at the same time. - var/rads = H.radiation / 25 - H.radiation = max(H.radiation-rads, 0) - H.nutrition = min(H.nutrition+rads, NUTRITION_LEVEL_WELL_FED+10) - H.adjustBruteLoss(-(rads)) - H.adjustToxLoss(-(rads)) - - var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing - if(isturf(H.loc)) //else, there's considered to be no light - var/turf/T = H.loc - light_amount = min(T.get_lumcount() * 10, 5) //hardcapped so it's not abused by having a ton of flashlights - H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10) - - if(light_amount > 0) - H.clear_alert("nolight") - else - H.throw_alert("nolight", /obj/screen/alert/nolight) - - if((light_amount >= 5) && !H.suiciding) //if there's enough light, heal - - H.adjustBruteLoss(-(light_amount/2)) - H.adjustFireLoss(-(light_amount/4)) - if(H.nutrition < NUTRITION_LEVEL_STARVING+50) - H.take_overall_damage(10,0) - ..() - -/datum/species/machine - name = "Machine" - name_plural = "Machines" - - blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \ - robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \ - to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \ - generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \ - inhuman in outlook and perspective." - - icobase = 'icons/mob/human_races/r_machine.dmi' - deform = 'icons/mob/human_races/r_machine.dmi' - path = /mob/living/carbon/human/machine - default_language = "Galactic Common" - language = "Trinary" - remains_type = /obj/effect/decal/remains/robot - - eyes = "blank_eyes" - brute_mod = 2.5 // 100% * 2.5 * 0.6 (robolimbs) ~= 150% - burn_mod = 2.5 // So they take 50% extra damage from brute/burn overall. - tox_mod = 0 - clone_mod = 0 - oxy_mod = 0 - death_message = "gives one shrill beep before falling limp, their monitor flashing blue before completely shutting off..." - - species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_BLOOD, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS - dietflags = 0 //IPCs can't eat, so no diet - taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE - blood_color = "#1F181F" - flesh_color = "#AAAAAA" - //Default styles for created mobs. - default_hair = "Blue IPC Screen" - can_revive_by_healing = 1 - has_gender = FALSE - reagent_tag = PROCESS_SYN - male_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' - female_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' - male_cough_sounds = list('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg') - female_cough_sounds = list('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg') - male_sneeze_sound = 'sound/effects/mob_effects/machine_sneeze.ogg' - female_sneeze_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg' - butt_sprite = "machine" - - has_organ = list( - "brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain, - "cell" = /obj/item/organ/internal/cell, - "optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2. - "charger" = /obj/item/organ/internal/cyberimp/arm/power_cord - ) - - vision_organ = /obj/item/organ/internal/eyes/optical_sensor - has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest/ipc), - "groin" = list("path" = /obj/item/organ/external/groin/ipc), - "head" = list("path" = /obj/item/organ/external/head/ipc), - "l_arm" = list("path" = /obj/item/organ/external/arm/ipc), - "r_arm" = list("path" = /obj/item/organ/external/arm/right/ipc), - "l_leg" = list("path" = /obj/item/organ/external/leg/ipc), - "r_leg" = list("path" = /obj/item/organ/external/leg/right/ipc), - "l_hand" = list("path" = /obj/item/organ/external/hand/ipc), - "r_hand" = list("path" = /obj/item/organ/external/hand/right/ipc), - "l_foot" = list("path" = /obj/item/organ/external/foot/ipc), - "r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc) - ) - - suicide_messages = list( - "is powering down!", - "is smashing their own monitor!", - "is twisting their own neck!", - "is downloading extra RAM!", - "is frying their own circuits!", - "is blocking their ventilation port!") - - species_abilities = list( - /mob/living/carbon/human/proc/change_monitor - ) - -/datum/species/machine/handle_death(var/mob/living/carbon/human/H) - var/obj/item/organ/external/head/head_organ = H.get_organ("head") - if(!head_organ) - return - head_organ.h_style = "Bald" - head_organ.f_style = "Shaved" - spawn(100) - if(H) - H.update_hair() - H.update_fhair() - -/datum/species/drask - name = "Drask" - name_plural = "Drask" - icobase = 'icons/mob/human_races/r_drask.dmi' - deform = 'icons/mob/human_races/r_drask.dmi' - path = /mob/living/carbon/human/drask - default_language = "Galactic Common" - language = "Orluum" - eyes = "drask_eyes_s" - - speech_sounds = list('sound/voice/DraskTalk.ogg') - speech_chance = 20 - male_scream_sound = 'sound/voice/DraskTalk2.ogg' - female_scream_sound = 'sound/voice/DraskTalk2.ogg' - male_cough_sounds = 'sound/voice/DraskCough.ogg' - female_cough_sounds = 'sound/voice/DraskCough.ogg' - male_sneeze_sound = 'sound/voice/DraskSneeze.ogg' - female_sneeze_sound = 'sound/voice/DraskSneeze.ogg' - - burn_mod = 2 - //exotic_blood = "cryoxadone" - body_temperature = 273 - - blurb = "Hailing from Hoorlm, planet outside what is usually considered a habitable \ - orbit, the Drask evolved to live in extreme cold. Their strange bodies seem \ - to operate better the colder their surroundings are, and can regenerate rapidly \ - when breathing supercooled gas.

    On their homeworld, the Drask live long lives \ - in their labyrinthine settlements, carved out beneath Hoorlm's icy surface, where the air \ - is of breathable density." - - suicide_messages = list( - "is self-warming with friction!", - "is jamming fingers through their big eyes!", - "is sucking in warm air!", - "is holding their breath!") - - species_traits = list(LIPS, IS_WHITELISTED) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT - bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS - dietflags = DIET_OMNI - - cold_level_1 = -1 //Default 260 - Lower is better - cold_level_2 = -1 //Default 200 - cold_level_3 = -1 //Default 120 - coldmod = -1 - - heat_level_1 = 300 //Default 360 - Higher is better - heat_level_2 = 340 //Default 400 - heat_level_3 = 400 //Default 460 - heatmod = 2 - - flesh_color = "#a3d4eb" - reagent_tag = PROCESS_ORG - base_color = "#a3d4eb" - blood_color = "#a3d4eb" - butt_sprite = "drask" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart/drask, - "lungs" = /obj/item/organ/internal/lungs/drask, - "metabolic strainer" = /obj/item/organ/internal/liver/drask, - "eyes" = /obj/item/organ/internal/eyes/drask, //5 darksight. - "brain" = /obj/item/organ/internal/brain/drask - ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/tajaran.dm b/code/modules/mob/living/carbon/human/species/tajaran.dm new file mode 100644 index 00000000000..0eaede54dbf --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/tajaran.dm @@ -0,0 +1,58 @@ +/datum/species/tajaran + name = "Tajaran" + name_plural = "Tajaran" + icobase = 'icons/mob/human_races/r_tajaran.dmi' + deform = 'icons/mob/human_races/r_def_tajaran.dmi' + language = "Siik'tajr" + tail = "tajtail" + skinned_type = /obj/item/stack/sheet/fur + unarmed_type = /datum/unarmed_attack/claws + + blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \ + S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \ + influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ + of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \ + using unique inflections their mouths form." + + cold_level_1 = 240 + cold_level_2 = 180 + cold_level_3 = 100 + + heat_level_1 = 340 + heat_level_2 = 380 + heat_level_3 = 440 + + primitive_form = /datum/species/monkey/tajaran + + species_traits = list(LIPS, CAN_BE_FAT) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING + dietflags = DIET_OMNI + taste_sensitivity = TASTE_SENSITIVITY_SHARP + reagent_tag = PROCESS_ORG + flesh_color = "#AFA59E" + base_color = "#424242" + butt_sprite = "tajaran" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/tajaran, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes/tajaran /*Most Tajara see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2) + unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/ + ) + + allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/chick, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, + /mob/living/simple_animal/tribble) + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!") + +/datum/species/tajaran/handle_death(var/mob/living/carbon/human/H) + H.stop_tail_wagging(1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm new file mode 100644 index 00000000000..243baa0ebfd --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/unathi.dm @@ -0,0 +1,92 @@ +/datum/species/unathi + name = "Unathi" + name_plural = "Unathi" + icobase = 'icons/mob/human_races/r_lizard.dmi' + deform = 'icons/mob/human_races/r_def_lizard.dmi' + language = "Sinta'unathi" + tail = "sogtail" + skinned_type = /obj/item/stack/sheet/animalhide/lizard + unarmed_type = /datum/unarmed_attack/claws + primitive_form = /datum/species/monkey/unathi + + blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \ + Uuosa-Eso system, which roughly translates to 'burning mother'.

    Coming from a harsh, radioactive \ + desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \ + else, frequently even their own lives. They prefer warmer temperatures than most species and \ + their native tongue is a heavy hissing laungage called Sinta'Unathi." + + species_traits = list(LIPS) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_BODY_MARKINGS | HAS_HEAD_MARKINGS | HAS_SKIN_COLOR | HAS_ALT_HEADS | TAIL_WAGGING + dietflags = DIET_CARN + + cold_level_1 = 280 //Default 260 - Lower is better + cold_level_2 = 220 //Default 200 + cold_level_3 = 140 //Default 120 + + heat_level_1 = 380 //Default 360 - Higher is better + heat_level_2 = 420 //Default 400 + heat_level_3 = 480 //Default 460 + + flesh_color = "#34AF10" + reagent_tag = PROCESS_ORG + base_color = "#066000" + //Default styles for created mobs. + default_headacc = "Simple" + default_headacc_colour = "#404040" + butt_sprite = "unathi" + brute_mod = 1.05 + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/unathi, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes/unathi //3 darksight. + ) + + allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, + /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!") + + var/datum/action/innate/tail_lash/lash = new() + + +/datum/species/unathi/handle_post_spawn(var/mob/living/carbon/human/H) + lash.Grant(H) + ..() + +/datum/action/innate/tail_lash + name = "Tail lash" + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "tail" + +/datum/action/innate/tail_lash/Activate() + var/mob/living/carbon/human/user = owner + if(!user.restrained() || !user.buckled) + to_chat(user, "You need freedom of movement to tail lash!") + return + if(user.getStaminaLoss() >= 50) + to_chat(user, "Rest before tail lashing again!") + return + for(var/mob/living/carbon/human/C in orange(1)) + var/obj/item/organ/external/E = C.get_organ(pick("l_leg", "r_leg", "l_foot", "r_foot", "groin")) + if(E) + user.changeNext_move(CLICK_CD_MELEE) + user.visible_message("[src] smacks [C] in [E] with their tail! ", "You hit [C] in [E] with your tail!") + user.adjustStaminaLoss(15) + C.apply_damage(5, BRUTE, E) + user.spin(20, 1) + playsound(user.loc, 'sound/weapons/slash.ogg', 50, 0) + + + +/datum/species/unathi/handle_death(var/mob/living/carbon/human/H) + H.stop_tail_wagging(1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm new file mode 100644 index 00000000000..e86185a4d9b --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/vox.dm @@ -0,0 +1,201 @@ +/datum/species/vox + name = "Vox" + name_plural = "Vox" + icobase = 'icons/mob/human_races/vox/r_vox.dmi' + deform = 'icons/mob/human_races/vox/r_def_vox.dmi' + language = "Vox-pidgin" + tail = "voxtail" + speech_sounds = list('sound/voice/shriek1.ogg') + speech_chance = 20 + unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too. + + blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ + scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \ + alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \ + refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \ + smell.

    Most humans will never meet a Vox raider, instead learning of this insular species through \ + dealing with their traders and merchants; those that do rarely enjoy the experience." + + brute_mod = 1.2 //20% more brute damage. Fragile bird bones. + + warning_low_pressure = 50 + hazard_low_pressure = 0 + + cold_level_1 = 80 + cold_level_2 = 50 + cold_level_3 = 0 + + breathid = "n2" + + eyes = "vox_eyes_s" + + species_traits = list(NO_SCAN, IS_WHITELISTED, NOTRANSSTING) + clothing_flags = HAS_SOCKS + dietflags = DIET_OMNI + bodyflags = HAS_ICON_SKIN_TONE | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_BODY_MARKINGS | HAS_TAIL_MARKINGS + + blood_color = "#2299FC" + flesh_color = "#808D11" + //Default styles for created mobs. + default_hair = "Short Vox Quills" + default_hair_colour = "#614f19" //R: 97, G: 79, B: 25 + butt_sprite = "vox" + + reagent_tag = PROCESS_ORG + scream_verb = "shrieks" + male_scream_sound = 'sound/voice/shriek1.ogg' + female_scream_sound = 'sound/voice/shriek1.ogg' + male_cough_sounds = list('sound/voice/shriekcough.ogg') + female_cough_sounds = list('sound/voice/shriekcough.ogg') + male_sneeze_sound = 'sound/voice/shrieksneeze.ogg' + female_sneeze_sound = 'sound/voice/shrieksneeze.ogg' + + icon_skin_tones = list( + 1 = "Default Green", + 2 = "Dark Green", + 3 = "Brown", + 4 = "Grey", + 5 = "Emerald", + 6 = "Azure" + ) + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs/vox, + "liver" = /obj/item/organ/internal/liver/vox, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. + "stack" = /obj/item/organ/internal/stack //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used + ) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ. + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!", + "is deeply inhaling oxygen!") + +/datum/species/vox/handle_death(var/mob/living/carbon/human/H) + H.stop_tail_wagging(1) + +/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H) + if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime") + H.unEquip(H.wear_mask) + H.unEquip(H.l_hand) + + H.equip_or_collect(new /obj/item/clothing/mask/breath/vox(H), slot_wear_mask) + var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null + if(tank_pref)//Diseasel, here you go + H.equip_or_collect(new /obj/item/tank/nitrogen(H), slot_l_hand) + else + H.equip_or_collect(new /obj/item/tank/emergency_oxygen/vox(H), slot_l_hand) + to_chat(H, "You are now running on nitrogen internals from the [H.l_hand] in your hand. Your species finds oxygen toxic, so you must breathe nitrogen only.") + H.internal = H.l_hand + H.update_action_buttons_icon() + +/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H) + updatespeciescolor(H) + H.update_icons() + //H.verbs += /mob/living/carbon/human/proc/leap + ..() + +/datum/species/vox/updatespeciescolor(var/mob/living/carbon/human/H, var/owner_sensitive = 1) //Handling species-specific skin-tones for the Vox race. + if(H.dna.species.bodyflags & HAS_ICON_SKIN_TONE) //Making sure we don't break Armalis. + var/new_icobase = 'icons/mob/human_races/vox/r_vox.dmi' //Default Green Vox. + var/new_deform = 'icons/mob/human_races/vox/r_def_vox.dmi' //Default Green Vox. + switch(H.s_tone) + if(6) //Azure Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxazu.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxazu.dmi' + H.tail = "voxtail_azu" + if(5) //Emerald Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxemrl.dmi' + H.tail = "voxtail_emrl" + if(4) //Grey Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxgry.dmi' + H.tail = "voxtail_gry" + if(3) //Brown Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxbrn.dmi' + H.tail = "voxtail_brn" + if(2) //Dark Green Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxdgrn.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxdgrn.dmi' + H.tail = "voxtail_dgrn" + else //Default Green Vox. + H.tail = "voxtail" //Ensures they get an appropriately coloured tail depending on the skin-tone. + + H.change_icobase(new_icobase, new_deform, owner_sensitive) //Update the icobase/deform of all our organs, but make sure we don't mess with frankenstein limbs in doing so. + H.update_dna() + +/datum/species/vox/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R) + if(R.id == "oxygen") //Armalis are above such petty things. + H.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER) //Same as plasma. + H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM) + return 0 //Handling reagent removal on our own. + + return ..() + +/datum/species/vox/armalis/handle_post_spawn(var/mob/living/carbon/human/H) + H.verbs += /mob/living/carbon/human/proc/leap + H.verbs += /mob/living/carbon/human/proc/gut + ..() + +/datum/species/vox/armalis + name = "Vox Armalis" + name_plural = "Vox Armalis" + icobase = 'icons/mob/human_races/r_armalis.dmi' + deform = 'icons/mob/human_races/r_armalis.dmi' + unarmed_type = /datum/unarmed_attack/claws/armalis + + warning_low_pressure = 50 + hazard_low_pressure = 0 + + cold_level_1 = 80 + cold_level_2 = 50 + cold_level_3 = 0 + + heat_level_1 = 2000 + heat_level_2 = 3000 + heat_level_3 = 4000 + + brute_mod = 0.2 + burn_mod = 0.2 + + eyes = "blank_eyes" + + species_traits = list(NO_SCAN, NO_BLOOD, NO_PAIN, IS_WHITELISTED) + bodyflags = HAS_TAIL + dietflags = DIET_OMNI //should inherit this from vox, this is here just in case + + blood_color = "#2299FC" + flesh_color = "#808D11" + + reagent_tag = PROCESS_ORG + + tail = "armalis_tail" + icon_template = 'icons/mob/human_races/r_armalis.dmi' + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs/vox, + "liver" = /obj/item/organ/internal/liver, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. + "stack" = /obj/item/organ/internal/stack //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used + ) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ. + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!", + "is huffing oxygen!") + +/datum/species/vox/armalis/handle_reagents() //Skip the Vox oxygen reagent toxicity. Armalis are above such things. + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/vulpkanin.dm b/code/modules/mob/living/carbon/human/species/vulpkanin.dm new file mode 100644 index 00000000000..5746fe125c9 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/vulpkanin.dm @@ -0,0 +1,52 @@ +/datum/species/vulpkanin + name = "Vulpkanin" + name_plural = "Vulpkanin" + icobase = 'icons/mob/human_races/r_vulpkanin.dmi' + deform = 'icons/mob/human_races/r_vulpkanin.dmi' + language = "Canilunzt" + primitive_form = /datum/species/monkey/vulpkanin + tail = "vulptail" + skinned_type = /obj/item/stack/sheet/fur + unarmed_type = /datum/unarmed_attack/claws + + blurb = "Vulpkanin are a species of sharp-witted canine-pideds residing on the planet Altam just barely within the \ + dual-star Vazzend system. Their politically de-centralized society and independent natures have led them to become a species and \ + culture both feared and respected for their scientific breakthroughs. Discovery, loyalty, and utilitarianism dominates their lifestyles \ + to the degree it can cause conflict with more rigorous and strict authorities. They speak a guttural language known as 'Canilunzt' \ + which has a heavy emphasis on utilizing tail positioning and ear twitches to communicate intent." + + species_traits = list(LIPS) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR + dietflags = DIET_OMNI + hunger_drain = 0.11 + taste_sensitivity = TASTE_SENSITIVITY_SHARP + reagent_tag = PROCESS_ORG + flesh_color = "#966464" + base_color = "#CF4D2F" + butt_sprite = "vulp" + + scream_verb = "yelps" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/vulpkanin, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes/vulpkanin /*Most Vulpkanin see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2) + unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/ + ) + + allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, + /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!") + +/datum/species/vulpkanin/handle_death(var/mob/living/carbon/human/H) + H.stop_tail_wagging(1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/wryn.dm similarity index 61% rename from code/modules/mob/living/carbon/human/species/apollo.dm rename to code/modules/mob/living/carbon/human/species/wryn.dm index 5a3e1d4cde9..5606cd81e9b 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/wryn.dm @@ -75,46 +75,4 @@ add_attack_logs(user, target, "Antennae removed") return 0 else - ..() - -/datum/species/nucleation - name = "Nucleation" - name_plural = "Nucleations" - icobase = 'icons/mob/human_races/r_nucleation.dmi' - blurb = "A sub-race of unfortunates who have been exposed to too much supermatter radiation. As a result, \ - supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \ - has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \ - negating the need for the individual to breathe. Their massive change in biology, however, renders most medicines \ - obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \ - and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \ - way as lepers were back on Earth." - language = "Sol Common" - burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores - brute_mod = 2 // damn, double wham, double dam - oxy_mod = 0 - species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_SCAN, RADIMMUNE) - dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet - - //Default styles for created mobs. - default_hair = "Nucleation Crystals" - - reagent_tag = PROCESS_ORG - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "crystallized brain" = /obj/item/organ/internal/brain/crystal, - "eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, //Standard darksight of 2. - "strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal - ) - vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal - -/datum/species/nucleation/handle_post_spawn(var/mob/living/carbon/human/H) - H.light_color = "#1C1C00" - H.set_light(2) - return ..() - -/datum/species/nucleation/handle_death(var/mob/living/carbon/human/H) - var/turf/T = get_turf(H) - H.visible_message("[H]'s body explodes, leaving behind a pile of microscopic crystals!") - explosion(T, 0, 0, 2, 2) // Create a small explosion burst upon death -// new /obj/item/shard/supermatter( T ) - qdel(H) \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index 5f74f202603..e7a65129017 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -1,19 +1,19 @@ /mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0) - if(species) - amount = amount * species.stun_mod + if(dna.species) + amount = amount * dna.species.stun_mod ..() /mob/living/carbon/human/SetWeakened(amount, updating = 1, force = 0) - if(species) - amount = amount * species.stun_mod + if(dna.species) + amount = amount * dna.species.stun_mod ..() /mob/living/carbon/human/SetParalysis(amount, updating = 1, force = 0) - if(species) - amount = amount * species.stun_mod + if(dna.species) + amount = amount * dna.species.stun_mod ..() /mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE) - if(species) - amount = amount * species.stun_mod + if(dna.species) + amount = amount * dna.species.stun_mod ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 328e4c14ab8..450b7a6c1a4 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -185,7 +185,7 @@ var/global/list/damage_icon_parts = list() previous_damage_appearance = damage_appearance - var/icon/standing = new /icon(species.damage_overlays, "00") + var/icon/standing = new /icon(dna.species.damage_overlays, "00") var/image/standing_image = new /image("icon" = standing) @@ -194,12 +194,12 @@ var/global/list/damage_icon_parts = list() O.update_icon() if(O.damage_state == "00") continue var/icon/DI - var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.name]" + var/cache_index = "[O.damage_state]/[O.icon_name]/[dna.species.blood_color]/[dna.species.name]" if(damage_icon_parts[cache_index] == null) - DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human - DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels - DI.Blend(species.blood_color, ICON_MULTIPLY) + DI = new /icon(dna.species.damage_overlays, O.damage_state) // the damage icon for whole human + DI.Blend(new /icon(dna.species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels + DI.Blend(dna.species.blood_color, ICON_MULTIPLY) damage_icon_parts[cache_index] = DI else DI = damage_icon_parts[cache_index] @@ -220,15 +220,15 @@ var/global/list/damage_icon_parts = list() var/hulk = (HULK in mutations) var/skeleton = (SKELETON in mutations) - if(species && species.bodyflags & HAS_ICON_SKIN_TONE) - species.updatespeciescolor(src) + if(dna.species && dna.species.bodyflags & HAS_ICON_SKIN_TONE) + dna.species.updatespeciescolor(src) //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. //Create a new, blank icon for our mob to use. if(stand_icon) qdel(stand_icon) - stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank") + stand_icon = new(dna.species.icon_template ? dna.species.icon_template : 'icons/mob/human.dmi',"blank") var/icon_key = "" var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) @@ -237,11 +237,11 @@ var/global/list/damage_icon_parts = list() else icon_key += "#000000" - for(var/organ_tag in species.has_limbs) + for(var/organ_tag in dna.species.has_limbs) var/obj/item/organ/external/part = bodyparts_by_name[organ_tag] if(isnull(part)) icon_key += "0" - else if(part.status & ORGAN_ROBOT) + else if(part.is_robotic()) icon_key += "2[part.model ? "-[part.model]": ""]" else if(part.status & ORGAN_DEAD) icon_key += "3" @@ -249,7 +249,8 @@ var/global/list/damage_icon_parts = list() icon_key += "1" if(part) - icon_key += "[part.species.race_key]" + var/datum/species/S = GLOB.all_species[part.dna.species.name] //This has to reference the species datums from round start, since they're global and unchanging + icon_key += "[S.race_key]" icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]" icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]" if(part.s_col) @@ -307,7 +308,7 @@ var/global/list/damage_icon_parts = list() //END CACHED ICON GENERATION. stand_icon.Blend(base_icon,ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the user's species is flagged to have a tail that needs to be overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the user's species is flagged to have a tail that needs to be overlapped by limbs... (having a non-tail body accessory like the snake body will override this) overlays_standing[LIMBS_LAYER] = image(stand_icon) // Diverts limbs to their own layer so they can overlay things (i.e. tails). else overlays_standing[LIMBS_LAYER] = null // So we don't get the old species' sprite splatted on top of the new one's @@ -316,18 +317,18 @@ var/global/list/damage_icon_parts = list() overlays_standing[UNDERWEAR_LAYER] = null var/icon/underwear_standing = new/icon('icons/mob/underwear.dmi',"nude") - if(underwear && species.clothing_flags & HAS_UNDERWEAR) + if(underwear && dna.species.clothing_flags & HAS_UNDERWEAR) var/datum/sprite_accessory/underwear/U = underwear_list[underwear] if(U) underwear_standing.Blend(new /icon(U.icon, "uw_[U.icon_state]_s"), ICON_OVERLAY) - if(undershirt && species.clothing_flags & HAS_UNDERSHIRT) + if(undershirt && dna.species.clothing_flags & HAS_UNDERSHIRT) var/datum/sprite_accessory/undershirt/U2 = undershirt_list[undershirt] if(U2) underwear_standing.Blend(new /icon(U2.icon, "us_[U2.icon_state]_s"), ICON_OVERLAY) - if(socks && species.clothing_flags & HAS_SOCKS) + if(socks && dna.species.clothing_flags & HAS_SOCKS) var/datum/sprite_accessory/socks/U3 = socks_list[socks] if(U3) underwear_standing.Blend(new /icon(U3.icon, "sk_[U3.icon_state]_s"), ICON_OVERLAY) @@ -339,7 +340,7 @@ var/global/list/damage_icon_parts = list() if(update_icons) update_icons() - if(lip_style && (LIPS in species.species_traits)) + if(lip_style && (LIPS in dna.species.species_traits)) var/icon/lips = icon("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[lip_style]_s") lips.Blend(lip_color, ICON_ADD) @@ -369,7 +370,7 @@ var/global/list/damage_icon_parts = list() if(chest_organ && m_styles["body"]) var/body_marking = m_styles["body"] var/datum/sprite_accessory/body_marking_style = marking_styles_list[body_marking] - if(body_marking_style && body_marking_style.species_allowed && (species.name in body_marking_style.species_allowed)) + if(body_marking_style && body_marking_style.species_allowed && (dna.species.name in body_marking_style.species_allowed)) var/icon/b_marking_s = new/icon("icon" = body_marking_style.icon, "icon_state" = "[body_marking_style.icon_state]_s") if(body_marking_style.do_colouration) b_marking_s.Blend(m_colours["body"], ICON_ADD) @@ -379,7 +380,7 @@ var/global/list/damage_icon_parts = list() if(head_organ && m_styles["head"]) //If the head is destroyed, forget the head markings. This prevents floating optical markings on decapitated IPCs, for example. var/head_marking = m_styles["head"] var/datum/sprite_accessory/head_marking_style = marking_styles_list[head_marking] - if(head_marking_style && head_marking_style.species_allowed && (head_organ.species.name in head_marking_style.species_allowed)) + if(head_marking_style && head_marking_style.species_allowed && (head_organ.dna.species.name in head_marking_style.species_allowed)) var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(m_colours["head"], ICON_ADD) @@ -407,10 +408,10 @@ var/global/list/damage_icon_parts = list() //base icons var/icon/head_accessory_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") - if(head_organ.ha_style && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY)) + if(head_organ.ha_style && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY)) var/datum/sprite_accessory/head_accessory/head_accessory_style = head_accessory_styles_list[head_organ.ha_style] if(head_accessory_style && head_accessory_style.species_allowed) - if(head_organ.species.name in head_accessory_style.species_allowed) + if(head_organ.dna.species.name in head_accessory_style.species_allowed) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) head_accessory_s.Blend(head_organ.headacc_colour, ICON_ADD) @@ -448,12 +449,12 @@ var/global/list/damage_icon_parts = list() if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()))) var/datum/sprite_accessory/hair/hair_style = hair_styles_full_list[head_organ.h_style] - //if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN + //if(!src.get_int_organ(/obj/item/organ/internal/brain) && !ismachine(src))//make it obvious we have NO BRAIN // hair_standing.Blend(debrained_s, ICON_OVERLAY) if(hair_style && hair_style.species_allowed) - if((head_organ.species.name in hair_style.species_allowed) || (head_organ.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... + if((head_organ.dna.species.name in hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(head_organ.species.name == "Slime People") // I am el worstos + if(istype(head_organ.dna.species, /datum/species/slime)) // I am el worstos hair_s.Blend("[skin_colour]A0", ICON_AND) else if(hair_style.do_colouration) hair_s.Blend(head_organ.hair_colour, ICON_ADD) @@ -497,9 +498,9 @@ var/global/list/damage_icon_parts = list() if(head_organ.f_style) var/datum/sprite_accessory/facial_hair/facial_hair_style = facial_hair_styles_list[head_organ.f_style] if(facial_hair_style && facial_hair_style.species_allowed) - if((head_organ.species.name in facial_hair_style.species_allowed) || (head_organ.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... + if((head_organ.dna.species.name in facial_hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(head_organ.species.name == "Slime People") // I am el worstos + if(istype(head_organ.dna.species, /datum/species/slime)) // I am el worstos facial_s.Blend("[skin_colour]A0", ICON_AND) else if(facial_hair_style.do_colouration) facial_s.Blend(head_organ.facial_colour, ICON_ADD) @@ -644,11 +645,11 @@ var/global/list/damage_icon_parts = list() if(w_uniform.icon_override) standing.icon = w_uniform.icon_override - else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[species.name]) - standing.icon = w_uniform.sprite_sheets[species.name] + else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[dna.species.name]) + standing.icon = w_uniform.sprite_sheets[dna.species.name] if(w_uniform.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "uniformblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "uniformblood") bloodsies.color = w_uniform.blood_color standing.overlays += bloodsies @@ -658,8 +659,8 @@ var/global/list/damage_icon_parts = list() if(!tie_color) tie_color = A.icon_state if(A.icon_override) standing.overlays += image("icon" = A.icon_override, "icon_state" = "[A.icon_state]") - else if(A.sprite_sheets && A.sprite_sheets[species.name]) - standing.overlays += image("icon" = A.sprite_sheets[species.name], "icon_state" = "[A.icon_state]") + else if(A.sprite_sheets && A.sprite_sheets[dna.species.name]) + standing.overlays += image("icon" = A.sprite_sheets[dna.species.name], "icon_state" = "[A.icon_state]") else standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") @@ -720,19 +721,19 @@ var/global/list/damage_icon_parts = list() var/image/standing if(gloves.icon_override) standing = image("icon" = gloves.icon_override, "icon_state" = "[t_state]") - else if(gloves.sprite_sheets && gloves.sprite_sheets[species.name]) - standing = image("icon" = gloves.sprite_sheets[species.name], "icon_state" = "[t_state]") + else if(gloves.sprite_sheets && gloves.sprite_sheets[dna.species.name]) + standing = image("icon" = gloves.sprite_sheets[dna.species.name], "icon_state" = "[t_state]") else standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]") if(gloves.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "bloodyhands") bloodsies.color = gloves.blood_color standing.overlays += bloodsies overlays_standing[GLOVES_LAYER] = standing else if(blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "bloodyhands") bloodsies.color = hand_blood_color overlays_standing[GLOVES_LAYER] = bloodsies else @@ -759,8 +760,8 @@ var/global/list/damage_icon_parts = list() if(glasses.icon_override) new_glasses = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]") - else if(glasses.sprite_sheets && glasses.sprite_sheets[head_organ.species.name]) - new_glasses = image("icon" = glasses.sprite_sheets[head_organ.species.name], "icon_state" = "[glasses.icon_state]") + else if(glasses.sprite_sheets && glasses.sprite_sheets[head_organ.dna.species.name]) + new_glasses = image("icon" = glasses.sprite_sheets[head_organ.dna.species.name], "icon_state" = "[glasses.icon_state]") else new_glasses = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]") @@ -795,9 +796,9 @@ var/global/list/damage_icon_parts = list() if(l_ear.icon_override) t_type = "[t_type]_l" overlays_standing[EARS_LAYER] = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]") - else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.name]) + else if(l_ear.sprite_sheets && l_ear.sprite_sheets[dna.species.name]) t_type = "[t_type]_l" - overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[species.name], "icon_state" = "[t_type]") + overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[dna.species.name], "icon_state" = "[t_type]") else overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") @@ -811,9 +812,9 @@ var/global/list/damage_icon_parts = list() if(r_ear.icon_override) t_type = "[t_type]_r" overlays_standing[EARS_LAYER] = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]") - else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.name]) + else if(r_ear.sprite_sheets && r_ear.sprite_sheets[dna.species.name]) t_type = "[t_type]_r" - overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[species.name], "icon_state" = "[t_type]") + overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[dna.species.name], "icon_state" = "[t_type]") else overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") @@ -837,20 +838,20 @@ var/global/list/damage_icon_parts = list() var/image/standing if(shoes.icon_override) standing = image("icon" = shoes.icon_override, "icon_state" = "[shoes.icon_state]") - else if(shoes.sprite_sheets && shoes.sprite_sheets[species.name]) - standing = image("icon" = shoes.sprite_sheets[species.name], "icon_state" = "[shoes.icon_state]") + else if(shoes.sprite_sheets && shoes.sprite_sheets[dna.species.name]) + standing = image("icon" = shoes.sprite_sheets[dna.species.name], "icon_state" = "[shoes.icon_state]") else standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]") if(shoes.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood") bloodsies.color = shoes.blood_color standing.overlays += bloodsies overlays_standing[SHOES_LAYER] = standing else if(feet_blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood") bloodsies.color = feet_blood_color overlays_standing[SHOES_LAYER] = bloodsies else @@ -891,13 +892,13 @@ var/global/list/damage_icon_parts = list() var/image/standing if(head.icon_override) standing = image("icon" = head.icon_override, "icon_state" = "[head.icon_state]") - else if(head.sprite_sheets && head.sprite_sheets[species.name]) - standing = image("icon" = head.sprite_sheets[species.name], "icon_state" = "[head.icon_state]") + else if(head.sprite_sheets && head.sprite_sheets[dna.species.name]) + standing = image("icon" = head.sprite_sheets[dna.species.name], "icon_state" = "[head.icon_state]") else standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]") if(head.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "helmetblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "helmetblood") bloodsies.color = head.blood_color standing.overlays += bloodsies overlays_standing[HEAD_LAYER] = standing @@ -925,8 +926,8 @@ var/global/list/damage_icon_parts = list() if(belt.icon_override) t_state = "[t_state]_be" overlays_standing[BELT_LAYER] = image("icon" = belt.icon_override, "icon_state" = "[t_state]") - else if(belt.sprite_sheets && belt.sprite_sheets[species.name]) - overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[species.name], "icon_state" = "[t_state]") + else if(belt.sprite_sheets && belt.sprite_sheets[dna.species.name]) + overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[dna.species.name], "icon_state" = "[t_state]") else overlays_standing[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]") else @@ -949,8 +950,8 @@ var/global/list/damage_icon_parts = list() var/image/standing if(wear_suit.icon_override) standing = image("icon" = wear_suit.icon_override, "icon_state" = "[wear_suit.icon_state]") - else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.name]) - standing = image("icon" = wear_suit.sprite_sheets[species.name], "icon_state" = "[wear_suit.icon_state]") + else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name]) + standing = image("icon" = wear_suit.sprite_sheets[dna.species.name], "icon_state" = "[wear_suit.icon_state]") else if(FAT in mutations) if(wear_suit.flags_size & ONESIZEFITSALL) standing = image("icon" = 'icons/mob/suit_fat.dmi', "icon_state" = "[wear_suit.icon_state]") @@ -969,7 +970,7 @@ var/global/list/damage_icon_parts = list() if(wear_suit.blood_DNA) var/obj/item/clothing/suit/S = wear_suit - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood") bloodsies.color = wear_suit.blood_color standing.overlays += bloodsies @@ -1035,14 +1036,14 @@ var/global/list/damage_icon_parts = list() if(wear_mask.icon_override) mask_icon = new(wear_mask.icon_override) standing = image("icon" = wear_mask.icon_override, "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]") - else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[species.name]) - mask_icon = new(wear_mask.sprite_sheets[species.name]) - standing = image("icon" = wear_mask.sprite_sheets[species.name], "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]") + else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[dna.species.name]) + mask_icon = new(wear_mask.sprite_sheets[dna.species.name]) + standing = image("icon" = wear_mask.sprite_sheets[dna.species.name], "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]") else standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]") if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "maskblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "maskblood") bloodsies.color = wear_mask.blood_color standing.overlays += bloodsies overlays_standing[FACEMASK_LAYER] = standing @@ -1062,8 +1063,8 @@ var/global/list/damage_icon_parts = list() //If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc. var/obj/item/rig/rig = back standing = rig.mob_icon - else if(back.sprite_sheets && back.sprite_sheets[species.name]) - standing = image("icon" = back.sprite_sheets[species.name], "icon_state" = "[back.icon_state]") + else if(back.sprite_sheets && back.sprite_sheets[dna.species.name]) + standing = image("icon" = back.sprite_sheets[dna.species.name], "icon_state" = "[back.icon_state]") else standing = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]") @@ -1163,7 +1164,7 @@ var/global/list/damage_icon_parts = list() var/icon/tail_marking_icon var/datum/sprite_accessory/body_markings/tail/tail_marking_style - if(m_styles["tail"] != "None" && (species.bodyflags & HAS_TAIL_MARKINGS)) + if(m_styles["tail"] != "None" && (dna.species.bodyflags & HAS_TAIL_MARKINGS)) var/tail_marking = m_styles["tail"] tail_marking_style = marking_styles_list[tail_marking] tail_marking_icon = new/icon("icon" = tail_marking_style.icon, "icon_state" = "[tail_marking_style.icon_state]_s") @@ -1172,11 +1173,11 @@ var/global/list/damage_icon_parts = list() if(body_accessory) if(body_accessory.try_restrictions(src)) var/icon/accessory_s = new/icon("icon" = body_accessory.icon, "icon_state" = body_accessory.icon_state) - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) accessory_s.Blend(skin_colour, body_accessory.blend_mode) if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "accessory_none_s") under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH) @@ -1194,14 +1195,14 @@ var/global/list/damage_icon_parts = list() else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) - else if(tail && species.bodyflags & HAS_TAIL) //no tailless tajaran + else if(tail && dna.species.bodyflags & HAS_TAIL) //no tailless tajaran if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]_s") - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) tail_s.Blend(skin_colour, ICON_ADD) if(tail_marking_icon && !tail_marking_style.tails_allowed) tail_s.Blend(tail_marking_icon, ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "blank") under.Insert(new/icon(tail_s, dir=SOUTH), dir=SOUTH) @@ -1230,7 +1231,7 @@ var/global/list/damage_icon_parts = list() var/icon/tail_marking_icon var/datum/sprite_accessory/body_markings/tail/tail_marking_style - if(m_styles["tail"] != "None" && (species.bodyflags & HAS_TAIL_MARKINGS)) + if(m_styles["tail"] != "None" && (dna.species.bodyflags & HAS_TAIL_MARKINGS)) var/tail_marking = m_styles["tail"] tail_marking_style = marking_styles_list[tail_marking] tail_marking_icon = new/icon("icon" = tail_marking_style.icon, "icon_state" = "[tail_marking_style.icon_state]w_s") @@ -1238,15 +1239,15 @@ var/global/list/damage_icon_parts = list() if(body_accessory) var/icon/accessory_s = new/icon("icon" = body_accessory.get_animated_icon(), "icon_state" = body_accessory.get_animated_icon_state()) - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) accessory_s.Blend(skin_colour, body_accessory.blend_mode) if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") - if(body_accessory.allowed_species && (species.name in body_accessory.allowed_species)) - under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") + if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species)) + under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH) under.Insert(new/icon(accessory_s, dir=EAST), dir=EAST) under.Insert(new/icon(accessory_s, dir=WEST), dir=WEST) @@ -1255,23 +1256,23 @@ var/global/list/damage_icon_parts = list() // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") - if(body_accessory.allowed_species && (species.name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank - over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") + if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank + over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") over.Insert(new/icon(accessory_s, dir=NORTH), dir=NORTH) overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) - else if(tail && species.bodyflags & HAS_TAIL) + else if(tail && dna.species.bodyflags & HAS_TAIL) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]w_s") - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) tailw_s.Blend(skin_colour, ICON_ADD) if(tail_marking_icon && !tail_marking_style.tails_allowed) tailw_s.Blend(tail_marking_icon, ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. - var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") + var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") under.Insert(new/icon(tailw_s, dir=SOUTH), dir=SOUTH) under.Insert(new/icon(tailw_s, dir=EAST), dir=EAST) under.Insert(new/icon(tailw_s, dir=WEST), dir=WEST) @@ -1279,7 +1280,7 @@ var/global/list/damage_icon_parts = list() overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under) // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. - var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") + var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") over.Insert(new/icon(tailw_s, dir=NORTH), dir=NORTH) overlays_standing[TAIL_LAYER] = image(over) @@ -1314,8 +1315,8 @@ var/global/list/damage_icon_parts = list() var/icon/icon_file = new(icon_path) if(wear_suit.icon_state in icon_file.IconStates()) standing = image("icon" = icon_file, "icon_state" = "[wear_suit.icon_state]") - else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.name]) - var/icon_path = "[wear_suit.sprite_sheets[species.name]]" + else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name]) + var/icon_path = "[wear_suit.sprite_sheets[dna.species.name]]" icon_path = "[copytext(icon_path, 1, findtext(icon_path, "/suit.dmi"))]/collar.dmi" //If this file doesn't exist, the end result is that COLLAR_LAYER will be unchanged (empty). if(fexists(icon_path)) //Just ensuring the nonexistance of a file with the above path won't cause a runtime. var/icon/icon_file = new(icon_path) diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/carbon/slime/life.dm index 80ed9fdbffd..5b0ee885ce7 100644 --- a/code/modules/mob/living/carbon/slime/life.dm +++ b/code/modules/mob/living/carbon/slime/life.dm @@ -337,7 +337,7 @@ if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men var/mob/living/carbon/human/H = L - if(H.species.name == "Slime People") + if(isslimeperson(H)) continue if(!L.canmove) // Only one slime can latch on at a time. diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index d9c7a9f12ef..50b22a2c8ed 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -217,7 +217,7 @@ to_chat(target, "You must follow the orders of [user], and help [user.p_them()] succeed in [user.p_their()] dastardly schemes.") to_chat(target, "You may not harm other Greyshirt or [user]. However, you do not need to obey other Greyshirts.") ticker.mode.greyshirts += target.mind - target.set_species("Human") + target.set_species(/datum/species/human) head_organ.h_style = "Bald" head_organ.f_style = "Shaved" target.s_tone = 35 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bff49e7c527..4cfdc7bb1f4 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1,4 +1,4 @@ -/mob/living/New() +/mob/living/Initialize() . = ..() var/datum/atom_hud/data/human/medical/advanced/medhud = huds[DATA_HUD_MEDICAL_ADVANCED] medhud.add_to_hud(src) @@ -660,14 +660,14 @@ TH.transfer_mob_blood_dna(src) if(ishuman(src)) var/mob/living/carbon/human/H = src - if(H.species.blood_color) - TH.color = H.species.blood_color + if(H.dna.species.blood_color) + TH.color = H.dna.species.blood_color else TH.color = "#A10808" /mob/living/carbon/human/makeTrail(turf/T) - if((NO_BLOOD in species.species_traits) || species.exotic_blood || !bleed_rate || bleedsuppress) + if((NO_BLOOD in dna.species.species_traits) || dna.species.exotic_blood || !bleed_rate || bleedsuppress) return ..() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index bf11356b3a5..c0393d78f92 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -1249,4 +1249,16 @@ var/list/ai_verbs_default = list( to_chat(src, "Unable to locate an airlock near [target].") else - to_chat(src, "Target is not on or near any active cameras on the station.") \ No newline at end of file + to_chat(src, "Target is not on or near any active cameras on the station.") + +/mob/living/silicon/ai/handle_fire() + return + +/mob/living/silicon/ai/update_fire() + return + +/mob/living/silicon/ai/IgniteMob() + return FALSE + +/mob/living/silicon/ai/ExtinguishMob() + return diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index d24518d4888..d28ce620a0c 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -114,8 +114,6 @@ pda.name = pda.owner + " (" + pda.ownjob + ")" var/datum/data/pda/app/messenger/M = pda.find_program(/datum/data/pda/app/messenger) M.toff = 1 - var/datum/data/pda/app/chatroom/C = pda.find_program(/datum/data/pda/app/chatroom) - C.toff = 1 ..() /mob/living/silicon/pai/Destroy() diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index bf9e4eeab0d..48c1c1d7d10 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -226,123 +226,6 @@ M.create_message(P, target, 1) return 1 -/datum/pai_software/chatroom - name = "Digital Chatroom" - ram_cost = 5 - id = "chatroom" - toggle = 0 - - autoupdate = 1 - template_file = "pai_chatroom.tmpl" - ui_title = "Digital Chatroom" - -/datum/pai_software/chatroom/on_ui_data(mob/living/silicon/pai/user, datum/topic_state/state = self_state) - var/data[0] - - if(!user.pda) - log_runtime(EXCEPTION("pAI found without PDA."), user) - return data - var/datum/data/pda/app/chatroom/M = user.pda.find_program(/datum/data/pda/app/chatroom) - if(!M) - log_runtime(EXCEPTION("pAI PDA lacks a chatroom program"), user) - return data - - data["receiver_off"] = M.toff - data["ringer_off"] = M.notify_silent - - var/list/rooms[0] - for(var/datum/chatroom/c in chatrooms) - if((M in c.users) || (M in c.invites) || c.is_public) - rooms += list(list(name = "[c]", ref = "\ref[c]")) - data["rooms"] = rooms - - if(M.disconnected || !M.messaging_available(1)) - data["disconnected"] = 1 - else if(M.current_room) - data["current_room"] = "\ref[M.current_room]" - data["current_room_name"] = M.current_room.name - data["current_room_topic"] = M.current_room.topic - data["messages"] = M.current_room.logs - var/list/users[0] - for(var/U in M.current_room.users) - var/datum/data/pda/app/chatroom/ch = U - users += "[ch.pda.owner]" - for(var/U in (M.current_room.invites - M.current_room.users)) - var/datum/data/pda/app/chatroom/ch = U - users += "[ch.pda.owner]" - data["users"] = users - - return data - -/datum/pai_software/chatroom/Topic(href, href_list) - var/mob/living/silicon/pai/P = usr - if(!istype(P)) - return - - if(!isnull(P.pda) && P.pda.can_use()) - var/datum/data/pda/app/chatroom/M = P.pda.find_program(/datum/data/pda/app/chatroom) - if(!M) - return - - if(href_list["toggler"]) - M.toff = href_list["toggler"] != "1" - return 1 - else if(href_list["ringer"]) - M.notify_silent = href_list["ringer"] != "1" - return 1 - else if(href_list["topic"]) - if(!M.current_room) - return 1 - - var/t = input("Enter new topic:", M.current_room, M.current_room.topic) as text|null - spawn() - if(!t || !M.check_messaging_available() || !P.pda.can_use()) - return - t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) - t = readd_quotes(t) - if(!t) - return - - M.current_room.topic = t - M.current_room.announce(M, "Topic has been changed to '[t]' by [P.pda.owner].") - return 1 - else if(href_list["select"]) - var/s = href_list["select"] - if(s == "*NONE*") - M.current_room = null - else - var/datum/chatroom/CR = locate(s) - if(istype(CR)) - if(!(M in CR.users)) - if(!CR.login(M)) - return - M.current_room = CR - return 1 - else if(href_list["target"]) - if(P.silence_time) - return alert("Communications circuits remain uninitialized.") - - var/datum/chatroom/target = locate(href_list["target"]) - if(istype(target)) - if(!(M in target.users)) - if(!target.login(M)) - return - var/t = input("Please enter message", target) as text|null - spawn() - if(!t || !M.check_messaging_available()) - return - t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) - t = readd_quotes(t) - if(!t || !P.pda.can_use()) - return - - target.post(M, t) - return 1 - else if(href_list["reconnect"]) - spawn() - M.messaging_available() - return 1 - /datum/pai_software/med_records name = "Medical Records" ram_cost = 15 diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index e3407c06f3d..cc5108d89f8 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -234,10 +234,10 @@ var/organ_found if(H.internal_organs.len) for(var/obj/item/organ/external/E in H.bodyparts) - if(!(E.status & ORGAN_ROBOT)) + if(!E.is_robotic()) continue organ_found = 1 - to_chat(user, "[E.name]: [round(E.brute_dam)] [round(E.burn_dam)]") + to_chat(user, "[E.name]: [E.brute_dam] [E.burn_dam]") if(!organ_found) to_chat(user, "No prosthetics located.") to_chat(user, "
    ") @@ -245,7 +245,7 @@ organ_found = null if(H.internal_organs.len) for(var/obj/item/organ/internal/O in H.internal_organs) - if(!(O.status & ORGAN_ROBOT)) + if(!O.is_robotic()) continue organ_found = 1 to_chat(user, "[capitalize(O.name)]: [O.damage]") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 5fb42f5f121..755b874667a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -131,8 +131,8 @@ var/list/robot_verbs_default = list( camera.status = 0 if(mmi == null) - mmi = new /obj/item/mmi/posibrain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a posibrain, but it works) - mmi.icon_state="posibrain-occupied" + mmi = new /obj/item/mmi/robotic_brain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a robotic brain, but it works) + mmi.icon_state = "boris" initialize_components() //if(!unfinished) @@ -210,7 +210,7 @@ var/list/robot_verbs_default = list( if(prefix) modtype = prefix if(mmi) - if(istype(mmi, /obj/item/mmi/posibrain)) + if(istype(mmi, /obj/item/mmi/robotic_brain)) braintype = "Android" else braintype = "Cyborg" @@ -738,7 +738,7 @@ var/list/robot_verbs_default = list( else if(istype(W, /obj/item/borg/upgrade/)) var/obj/item/borg/upgrade/U = W if(!opened) - to_chat(user, "You must access the borgs internals!") + to_chat(user, "You must access the borg's internals!") else if(!src.module && U.require_module) to_chat(user, "The borg must choose a module before it can be upgraded!") else if(U.locked) @@ -752,6 +752,21 @@ var/list/robot_verbs_default = list( else to_chat(user, "Upgrade error.") + else if(istype(W, /obj/item/mmi_radio_upgrade)) + if(!opened) + to_chat(user, "You must access the borg's internals!") + return + else if(!mmi) + to_chat(user, "This cyborg does not have an MMI to augment!") + return + else if(mmi.radio) + to_chat(user, "A radio upgrade is already installed in the MMI!") + return + else if(user.drop_item()) + to_chat(user, "You apply the upgrade to [src].") + to_chat(src, "MMI radio capability installed.") + mmi.install_radio() + qdel(W) else return ..() @@ -1442,4 +1457,4 @@ var/list/robot_verbs_default = list( return eye_protection /mob/living/silicon/robot/check_ear_prot() - return ear_protection \ No newline at end of file + return ear_protection diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 6cdffd48f16..a60dfc344ca 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -373,7 +373,7 @@ // is secretly a silicon if(ishuman(C)) var/mob/living/carbon/human/H = C - if(H.species && H.species.reagent_tag == PROCESS_SYN) + if(H.dna.species && H.dna.species.reagent_tag == PROCESS_SYN) return 0 if(emagged == 2) //Everyone needs our medicine. (Our medicine is toxins) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 3243061273f..0efaefcce07 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -715,7 +715,7 @@ var/list/blood_dna = H.get_blood_dna_list() if(blood_dna) transfer_blood_dna(blood_dna) - currentBloodColor = H.species.blood_color + currentBloodColor = H.dna.species.blood_color return /mob/living/simple_animal/bot/mulebot/bot_control_message(command, mob/user, user_turf) diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm index 64fe7d05b9b..669271f3ead 100644 --- a/code/modules/mob/living/simple_animal/friendly/diona.dm +++ b/code/modules/mob/living/simple_animal/friendly/diona.dm @@ -54,7 +54,7 @@ /mob/living/simple_animal/diona/attack_hand(mob/living/carbon/human/M) //Let people pick the little buggers up. if(M.a_intent == INTENT_HELP) - if(M.species && M.species.name == "Diona") + if(isdiona(M)) to_chat(M, "You feel your being twine with that of [src] as it merges with your biomass.") to_chat(src, "You feel your being twine with that of [M] as you merge with its biomass.") verbs += /mob/living/simple_animal/diona/proc/split @@ -82,7 +82,7 @@ if(ishuman(C)) var/mob/living/carbon/human/D = C - if(D.species && D.species.name == "Diona") + if(isdiona(D)) choices += C var/mob/living/M = input(src,"Who do you wish to merge with?") in null|choices @@ -142,7 +142,7 @@ visible_message("[src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.","You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.") var/mob/living/carbon/human/diona/adult = new(get_turf(loc)) - adult.set_species("Diona") + adult.set_species(/datum/species/diona) if(istype(loc, /obj/item/holder/diona)) var/obj/item/holder/diona/L = loc @@ -156,8 +156,7 @@ adult.name = "diona ([rand(100,999)])" adult.real_name = adult.name adult.ckey = ckey - adult.real_name = pick(diona_names) //I hate this being here of all places but unfortunately dna is based on real_name! - adult.rename_self("diona") + adult.real_name = adult.dna.species.get_random_name() //I hate this being here of all places but unfortunately dna is based on real_name! for(var/obj/item/W in contents) unEquip(W) @@ -178,7 +177,7 @@ if(!M || !src) return - if(NO_BLOOD in M.species.species_traits) + if(NO_BLOOD in M.dna.species.species_traits) to_chat(src, "That donor has no blood to take.") return diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index a8784a6d150..370418134c3 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -234,7 +234,7 @@ var/global/chicken_count = 0 can_hide = 1 can_collar = 1 var/list/feedMessages = list("It clucks happily.","It clucks happily.") - var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.") + var/list/layMessage = EGG_LAYING_MESSAGES var/list/validColors = list("brown","black","white") gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index b98d4181475..37ed25f15e8 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -157,7 +157,7 @@ if(istype(mmi, /obj/item/mmi)) icon_state = "spiderbot-chassis-mmi" icon_living = "spiderbot-chassis-mmi" - if(istype(mmi, /obj/item/mmi/posibrain)) + if(istype(mmi, /obj/item/mmi/robotic_brain)) icon_state = "spiderbot-chassis-posi" icon_living = "spiderbot-chassis-posi" diff --git a/code/modules/mob/living/simple_animal/hostile/deathsquid.dm b/code/modules/mob/living/simple_animal/hostile/deathsquid.dm index e825bb2d273..065247a538d 100644 --- a/code/modules/mob/living/simple_animal/hostile/deathsquid.dm +++ b/code/modules/mob/living/simple_animal/hostile/deathsquid.dm @@ -11,6 +11,8 @@ icon_state = "deathsquid" icon_living = "deathsquid" icon_dead = "deathsquiddead" + pixel_x = -24 + pixel_y = -24 attacktext = "slices" attack_sound = 'sound/weapons/bladeslice.ogg' diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 283936acb44..f3e31925228 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -178,7 +178,7 @@ if(ishuman(the_target)) var/mob/living/carbon/human/H = the_target - if(is_type_in_list(src, H.species.ignored_by)) + if(is_type_in_list(src, H.dna.species.ignored_by)) return 0 if(istype(the_target, /obj/mecha)) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm index 3462e8e18e7..7b10c0e828a 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm @@ -27,4 +27,41 @@ speak_emote = list("gnashes") faction = list("carp") - flying = 1 \ No newline at end of file + flying = 1 + + +/mob/living/simple_animal/hostile/retaliate/carp/koi + name = "space koi" + desc = "A gentle space-faring koi." + icon = 'icons/obj/fish_items.dmi' + icon_state = "koi1" + icon_living = "koi1" + icon_dead = "koi1-dead" + + harm_intent_damage = 1 + melee_damage_lower = 2 + melee_damage_upper = 2 + speak_emote = list("blurps") + butcher_results = null + + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 0 + maxbodytemp = 1500 + + gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE + +/mob/living/simple_animal/hostile/retaliate/carp/koi/New() + ..() + var/koinum = rand(1, 4) + icon_state = "koi[koinum]" + icon_living = "koi[koinum]" + icon_dead = "koi[koinum]-dead" + + +/mob/living/simple_animal/hostile/retaliate/carp/koi/Process_Spacemove(var/movement_dir) + return TRUE + +/mob/living/simple_animal/hostile/retaliate/carp/koi/honk + icon_state = "koi5" + icon_living = "koi5" + icon_dead = "koi5-dead" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index 235a161c595..693ca724ac6 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -196,7 +196,7 @@ var/global/list/ts_spiderling_list = list() var/can_poison = 1 if(ishuman(G)) var/mob/living/carbon/human/H = G - if(!(H.species.reagent_tag & PROCESS_ORG) || (!H.species.tox_mod)) + if(!(H.dna.species.reagent_tag & PROCESS_ORG) || (!H.dna.species.tox_mod)) can_poison = 0 spider_specialattack(G,can_poison) else diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index c7b82dc44b8..cc50f2aa56e 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -79,7 +79,7 @@ var/death_sound = null //The sound played on death -/mob/living/simple_animal/New() +/mob/living/simple_animal/Initialize() ..() simple_animal_list += src verbs -= /mob/verb/observe @@ -130,8 +130,8 @@ if(..()) //alive if(health < 1) death() - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/proc/handle_automated_action() return @@ -270,7 +270,7 @@ if((Proj.damage_type != STAMINA)) adjustBruteLoss(Proj.damage) Proj.on_hit(src, 0) - return 0 + return FALSE /mob/living/simple_animal/attackby(obj/item/O, mob/living/user) if(can_collar && !collar && istype(O, /obj/item/clothing/accessory/petcollar)) @@ -342,7 +342,7 @@ /mob/living/simple_animal/proc/adjustHealth(amount) if(status_flags & GODMODE) - return 0 + return FALSE bruteloss = Clamp(bruteloss + amount, 0, maxHealth) handle_regular_status_updates() @@ -372,20 +372,20 @@ /mob/living/simple_animal/proc/CanAttack(var/atom/the_target) if(see_invisible < the_target.invisibility) - return 0 + return FALSE if(isliving(the_target)) var/mob/living/L = the_target if(L.stat != CONSCIOUS) - return 0 + return FALSE if(istype(the_target, /obj/mecha)) var/obj/mecha/M = the_target if(M.occupant) - return 0 + return FALSE if(istype(the_target,/obj/spacepod)) var/obj/spacepod/S = the_target if(S.pilot) - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/handle_fire() return @@ -394,7 +394,7 @@ return /mob/living/simple_animal/IgniteMob() - return 0 + return FALSE /mob/living/simple_animal/ExtinguishMob() return @@ -502,19 +502,19 @@ switch(slot) if(slot_collar) if(collar) - return 0 + return FALSE if(!can_collar) - return 0 + return FALSE if(!istype(I, /obj/item/clothing/accessory/petcollar)) - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/equip_to_slot(obj/item/W, slot) if(!istype(W)) - return 0 + return FALSE if(!slot) - return 0 + return FALSE W.forceMove(src) W.equipped(src, slot) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index fb62ad3a629..2d024ec786e 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -58,8 +58,8 @@ if(istype(src,/mob/living/carbon/human)) var/mob/living/carbon/human/H = src - if(H.species && H.species.abilities) - client.verbs |= H.species.abilities + if(H.dna.species && H.dna.species.abilities) + client.verbs |= H.dna.species.abilities client.screen += client.void diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index beba84eaa3f..fc09105e948 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -24,7 +24,7 @@ ..() return QDEL_HINT_HARDDEL -/mob/New() +/mob/Initialize() mob_list += src if(stat == DEAD) dead_mob_list += src @@ -1080,9 +1080,6 @@ var/list/slot_equipment_priority = list( \ /mob/proc/activate_hand(selhand) return -/mob/proc/get_species() - return "" - /mob/dead/observer/verb/respawn() set name = "Respawn as NPC" set category = "Ghost" diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 458138b9db0..93941d6e7d2 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -410,7 +410,7 @@ return 1 var/mob/living/carbon/human/H = attacker - if(ishuman(H) && is_type_in_list(prey, H.species.allowed_consumed_mobs)) //species eating of other mobs + if(ishuman(H) && is_type_in_list(prey, H.dna.species.allowed_consumed_mobs)) //species eating of other mobs return 1 return 0 diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index d06028625b8..d622c78f680 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -1,7 +1,7 @@ /proc/issmall(A) if(A && istype(A, /mob/living/carbon/human)) var/mob/living/carbon/human/H = A - if(H.species && H.species.is_small) + if(H.dna.species && H.dna.species.is_small) return 1 return 0 @@ -16,9 +16,9 @@ return 0 /mob/living/carbon/human/isSynthetic() - if(get_species() == "Machine") - return 1 - return 0 + if(ismachine(src)) + return TRUE + return FALSE /mob/proc/get_screen_colour() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 274c1602e04..a2586dd65a1 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -395,7 +395,7 @@ var/arrivalmessage = announcer.arrivalmsg arrivalmessage = replacetext(arrivalmessage,"$name",character.real_name) arrivalmessage = replacetext(arrivalmessage,"$rank",rank ? "[rank]" : "visitor") - arrivalmessage = replacetext(arrivalmessage,"$species",character.species.name) + arrivalmessage = replacetext(arrivalmessage,"$species",character.dna.species.name) arrivalmessage = replacetext(arrivalmessage,"$age",num2text(character.age)) arrivalmessage = replacetext(arrivalmessage,"$gender",character.gender == FEMALE ? "Female" : "Male") announcer.say(";[arrivalmessage]") @@ -537,9 +537,6 @@ else if(mind.assigned_role == "Mime") new_character.real_name = pick(mime_names) new_character.rename_self("mime") - else if(new_character.species == "Diona") - new_character.real_name = pick(diona_names) //I hate this being here of all places but unfortunately dna is based on real_name! - new_character.rename_self("diona") mind.original = new_character mind.transfer_to(new_character) //won't transfer key since the mind is not active @@ -552,7 +549,7 @@ /mob/new_player/proc/check_prefs_are_sane() var/datum/species/chosen_species if(client.prefs.species) - chosen_species = all_species[client.prefs.species] + chosen_species = GLOB.all_species[client.prefs.species] if(!(chosen_species && (is_species_whitelisted(chosen_species) || has_admin_rights()))) // Have to recheck admin due to no usr at roundstart. Latejoins are fine though. log_runtime(EXCEPTION("[src] had species [client.prefs.species], though they weren't supposed to. Setting to Human."), src) @@ -591,19 +588,6 @@ if(!S) return 1 return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(IS_WHITELISTED in S.species_traits) -/mob/new_player/get_species() - var/datum/species/chosen_species - if(client.prefs.species) - chosen_species = all_species[client.prefs.species] - - if(!chosen_species) - return "Human" - - if(is_species_whitelisted(chosen_species) || has_admin_rights()) - return chosen_species.name - - return "Human" - /mob/new_player/get_gender() if(!client || !client.prefs) ..() return client.prefs.gender diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index d57c46e513c..fc97658896f 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -1,10 +1,10 @@ /datum/preferences //The mob should have a gender you want before running this proc. Will run fine without H /datum/preferences/proc/random_character(gender_override) - var/datum/species/S = all_species[species] + var/datum/species/S = GLOB.all_species[species] if(!istype(S)) //The species was invalid. Set the species to the default, fetch the datum for that species and generate a random character. species = initial(species) - S = all_species[species] + S = GLOB.all_species[species] var/datum/robolimb/robohead if(S.bodyflags & ALL_RPARTS) @@ -216,20 +216,20 @@ if(gender == FEMALE) g = "f" var/icon/icobase - var/datum/species/current_species = all_species[species] + var/datum/species/current_species = GLOB.all_species[species] //Icon-based species colour. var/coloured_tail if(current_species) if(current_species.bodyflags & HAS_ICON_SKIN_TONE) //Handling species-specific icon-based skin tones by flagged race. var/mob/living/carbon/human/H = new - H.species = current_species + H.dna.species = current_species H.s_tone = s_tone - H.species.updatespeciescolor(H, 0) //The mob's species wasn't set, so it's almost certainly different than the character's species at the moment. Thus, we need to be owner-insensitive. + H.dna.species.updatespeciescolor(H, 0) //The mob's species wasn't set, so it's almost certainly different than the character's species at the moment. Thus, we need to be owner-insensitive. var/obj/item/organ/external/chest/C = H.get_organ("chest") - icobase = C.icobase ? C.icobase : C.species.icobase - if(H.species.bodyflags & HAS_TAIL) - coloured_tail = H.tail ? H.tail : H.species.tail + icobase = C.icobase ? C.icobase : C.dna.species.icobase + if(H.dna.species.bodyflags & HAS_TAIL) + coloured_tail = H.tail ? H.tail : H.dna.species.tail qdel(H) else diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 82aebda3a42..a1ed4f0bde9 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -86,7 +86,7 @@ if(O.mind && O.mind.assigned_role == "Cyborg") if(O.mind.role_alt_title == "Android") - O.mmi = new /obj/item/mmi/posibrain(O) + O.mmi = new /obj/item/mmi/robotic_brain(O) else if(O.mind.role_alt_title == "Robot") O.mmi = null //Robots do not have removable brains. else diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index 6e0be3b385f..5dd324945fa 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -36,6 +36,7 @@ var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] hard_drive.store_file(new/datum/computer_file/program/power_monitor()) hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) + hard_drive.store_file(new/datum/computer_file/program/supermatter_monitor()) // ===== RESEARCH CONSOLE ===== /obj/machinery/modular_computer/console/preset/research diff --git a/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm new file mode 100644 index 00000000000..db9081f6ad1 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm @@ -0,0 +1,139 @@ +/datum/computer_file/program/supermatter_monitor + filename = "smmonitor" + filedesc = "Supermatter Monitoring" + ui_header = "smmon_0.gif" + program_icon_state = "smmon_0" + extended_desc = "This program connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines." + requires_ntnet = TRUE + transfer_access = access_construction + network_destination = "supermatter monitoring system" + size = 5 + var/last_status = SUPERMATTER_INACTIVE + var/list/supermatters + var/obj/machinery/power/supermatter_shard/active // Currently selected supermatter crystal. + + +/datum/computer_file/program/supermatter_monitor/process_tick() + ..() + var/new_status = get_status() + if(last_status != new_status) + last_status = new_status + if(last_status == SUPERMATTER_ERROR) + last_status = SUPERMATTER_INACTIVE + ui_header = "smmon_[last_status].gif" + program_icon_state = "smmon_[last_status]" + if(istype(computer)) + computer.update_icon() + +/datum/computer_file/program/supermatter_monitor/run_program(mob/living/user) + . = ..(user) + refresh() + +/datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE) + active = null + supermatters = null + ..() + +// Refreshes list of active supermatter crystals +/datum/computer_file/program/supermatter_monitor/proc/refresh() + supermatters = list() + var/turf/T = get_turf(nano_host()) + if(!T) + return + for(var/obj/machinery/power/supermatter_shard/S in SSair.atmos_machinery) + // Delaminating, not within coverage, not on a tile. + if(!(is_station_level(S.z) || is_mining_level(S.z) || atoms_share_level(S, T) || !istype(S.loc, /turf/simulated/))) + continue + supermatters.Add(S) + + if(!(active in supermatters)) + active = null + +/datum/computer_file/program/supermatter_monitor/proc/get_status() + . = SUPERMATTER_INACTIVE + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + . = max(., S.get_status()) + +/datum/computer_file/program/supermatter_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) + assets.send(user) + ui = new(user, src, ui_key, "supermatter_monitor.tmpl", "Supermatter Monitoring", 600, 400) + ui.set_auto_update(TRUE) + ui.set_layout_key("program") + ui.open() + +/datum/computer_file/program/supermatter_monitor/ui_data() + var/list/data = get_header_data() + + if(istype(active)) + var/turf/T = get_turf(active) + if(!T) + active = null + refresh() + return + var/datum/gas_mixture/air = T.return_air() + if(!air) + active = null + return + + data["active"] = TRUE + data["SM_integrity"] = active.get_integrity() + data["SM_power"] = active.power + data["SM_ambienttemp"] = air.temperature + data["SM_ambientpressure"] = air.return_pressure() + //data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01) + var/other_moles = 0.0 + for(var/datum/gas/G in air.trace_gases) + other_moles+=G.moles + var/TM = air.total_moles() + if(TM) + data["SM_gas_O2"] = round(100*air.oxygen/TM,0.01) + data["SM_gas_CO2"] = round(100*air.carbon_dioxide/TM,0.01) + data["SM_gas_N2"] = round(100*air.nitrogen/TM,0.01) + data["SM_gas_PL"] = round(100*air.toxins/TM,0.01) + if(other_moles) + data["SM_gas_OTHER"] = round(100*other_moles/TM,0.01) + else + data["SM_gas_OTHER"] = 0 + else + data["SM_gas_O2"] = 0 + data["SM_gas_CO2"] = 0 + data["SM_gas_N2"] = 0 + data["SM_gas_PH"] = 0 + data["SM_gas_OTHER"] = 0 + else + var/list/SMS = list() + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + var/area/A = get_area(S) + if(!A) + continue + + SMS.Add(list(list( + "area_name" = A.name, + "integrity" = S.get_integrity(), + "uid" = S.uid + ))) + + data["active"] = FALSE + data["supermatters"] = SMS + + return data + + +/datum/computer_file/program/supermatter_monitor/Topic(href, href_list) + if(..()) + return TRUE + if(href_list["clear"]) + active = null + return TRUE + if(href_list["refresh"]) + refresh() + return TRUE + if(href_list["set"]) + var/newuid = text2num(href_list["set"]) + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + if(S.uid == newuid) + active = S + return TRUE diff --git a/code/modules/nano/interaction/default.dm b/code/modules/nano/interaction/default.dm index 3f9155ed162..e5062bc0b12 100644 --- a/code/modules/nano/interaction/default.dm +++ b/code/modules/nano/interaction/default.dm @@ -59,10 +59,14 @@ return STATUS_CLOSE -//Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI. +//Some atoms such as vehicles might have special limitations for how mobs inside them interact with NanoUI. /atom/proc/contents_nano_distance(var/src_object, var/mob/living/user) return user.shared_living_nano_distance(src_object) +//Some atoms such as vehicles might have special benefits for how mobs inside them interact with NanoUI. +/atom/proc/contents_nano_interact(var/src_object, var/mob/living/user) + return STATUS_CLOSE // No help at all by default + /mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object) if(!(src_object in view(4, src))) // If the src object is not in visable, disable updates return STATUS_CLOSE @@ -84,6 +88,16 @@ if(STATUS_INTERACTIVE) return STATUS_UPDATE +/mob/living/carbon/brain/default_can_use_topic(var/src_object) + . = shared_nano_interaction(src_object) + if(. <= STATUS_DISABLED) + return + // Maybe add a handler here to call an "interaction state" thing on the MMI, + // later + if(loc) + . = max(., loc.contents_nano_interact(src_object, src)) // This is an "augment" on interaction + . = min(., loc.contents_nano_distance(src_object, src)) // This is a "limit" on interaction + /mob/living/carbon/human/default_can_use_topic(var/src_object) . = shared_nano_interaction(src_object) if(. != STATUS_CLOSE) diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index ad7a8f5cff6..07810eb92a0 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -31,7 +31,8 @@ if(href_list["race"]) if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species)) - if(owner.change_species(href_list["race"])) + var/datum/species/S = GLOB.all_species[href_list["race"]] + if(owner.set_species(S.type)) cut_and_generate_data() // Species change creates new organs - runtimes ahoy if we forget this head_organ = owner.get_organ("head") @@ -44,24 +45,24 @@ if(href_list["skin_tone"]) if(can_change_skin_tone()) var/new_s_tone = null - if(owner.species.bodyflags & HAS_SKIN_TONE) + if(owner.dna.species.bodyflags & HAS_SKIN_TONE) new_s_tone = input(usr, "Choose your character's skin tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null if(isnum(new_s_tone) && can_still_topic(state)) new_s_tone = 35 - max(min(round(new_s_tone), 220),1) - else if(owner.species.bodyflags & HAS_ICON_SKIN_TONE) + else if(owner.dna.species.bodyflags & HAS_ICON_SKIN_TONE) var/const/MAX_LINE_ENTRIES = 4 - var/prompt = "Choose your character's skin tone: 1-[owner.species.icon_skin_tones.len]\n(" - for(var/i = 1 to owner.species.icon_skin_tones.len) + var/prompt = "Choose your character's skin tone: 1-[owner.dna.species.icon_skin_tones.len]\n(" + for(var/i = 1 to owner.dna.species.icon_skin_tones.len) if(i > MAX_LINE_ENTRIES && !((i - 1) % MAX_LINE_ENTRIES)) prompt += "\n" - prompt += "[i] = [owner.species.icon_skin_tones[i]]" - if(i != owner.species.icon_skin_tones.len) + prompt += "[i] = [owner.dna.species.icon_skin_tones[i]]" + if(i != owner.dna.species.icon_skin_tones.len) prompt += ", " prompt += ")" new_s_tone = input(usr, prompt, "Skin Tone", owner.s_tone) as num|null if(isnum(new_s_tone) && can_still_topic(state)) - new_s_tone = max(min(round(new_s_tone), owner.species.icon_skin_tones.len), 1) + new_s_tone = max(min(round(new_s_tone), owner.dna.species.icon_skin_tones.len), 1) if(new_s_tone) return owner.change_skin_tone(new_s_tone) @@ -183,9 +184,9 @@ generate_data(check_whitelist, whitelist, blacklist) var/data[0] - data["specimen"] = owner.species.name + data["specimen"] = owner.dna.species.name data["gender"] = owner.gender - data["has_gender"] = owner.species.has_gender + data["has_gender"] = owner.dna.species.has_gender data["change_race"] = can_change(APPEARANCE_RACE) if(data["change_race"]) var/species[0] @@ -283,25 +284,25 @@ return owner && (flags & flag) /datum/nano_module/appearance_changer/proc/can_change_skin_tone() - return owner && (flags & APPEARANCE_SKIN) && ((owner.species.bodyflags & HAS_SKIN_TONE) || (owner.species.bodyflags & HAS_ICON_SKIN_TONE)) + return owner && (flags & APPEARANCE_SKIN) && ((owner.dna.species.bodyflags & HAS_SKIN_TONE) || (owner.dna.species.bodyflags & HAS_ICON_SKIN_TONE)) /datum/nano_module/appearance_changer/proc/can_change_skin_color() - return owner && (flags & APPEARANCE_SKIN) && (owner.species.bodyflags & HAS_SKIN_COLOR) + return owner && (flags & APPEARANCE_SKIN) && (owner.dna.species.bodyflags & HAS_SKIN_COLOR) /datum/nano_module/appearance_changer/proc/can_change_head_accessory() if(!head_organ) log_runtime(EXCEPTION("Missing head!"), owner) return 0 - return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY) /datum/nano_module/appearance_changer/proc/can_change_markings(var/location = "body") var/marking_flag = HAS_BODY_MARKINGS - var/body_flags = owner.species.bodyflags + var/body_flags = owner.dna.species.bodyflags if(location == "head") if(!head_organ) log_debug("Missing head!") return 0 - body_flags = head_organ.species.bodyflags + body_flags = head_organ.dna.species.bodyflags marking_flag = HAS_HEAD_MARKINGS if(location == "body") marking_flag = HAS_BODY_MARKINGS @@ -311,13 +312,13 @@ return owner && (flags & APPEARANCE_MARKINGS) && (body_flags & marking_flag) /datum/nano_module/appearance_changer/proc/can_change_body_accessory() - return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.species.bodyflags & HAS_TAIL) + return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.dna.species.bodyflags & HAS_TAIL) /datum/nano_module/appearance_changer/proc/can_change_alt_head() if(!head_organ) log_debug("Missing head!") return 0 - return owner && (flags & APPEARANCE_ALT_HEAD) && (head_organ.species.bodyflags & HAS_ALT_HEADS) + return owner && (flags & APPEARANCE_ALT_HEAD) && (head_organ.dna.species.bodyflags & HAS_ALT_HEADS) /datum/nano_module/appearance_changer/proc/cut_and_generate_data() // Making the assumption that the available species remain constant diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index 2700c8702db..74bee9867ab 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -7,34 +7,28 @@ var/labels_left = 30 var/mode = 0 //off or on. -/obj/item/hand_labeler/afterattack(atom/A, mob/user as mob, proximity) - if(!proximity) return +/obj/item/hand_labeler/afterattack(atom/A, mob/user, proximity) + if(!proximity) + return if(!mode) //if it's off, give up. return - if(A == loc) // if placing the labeller into something (e.g. backpack) - return // don't set a label if(!labels_left) - to_chat(user, "No labels left.") + to_chat(user, "No labels left!") return if(!label || !length(label)) - to_chat(user, "No text set.") + to_chat(user, "No text set!") return if(length(A.name) + length(label) > 64) - to_chat(user, "Label too big.") + to_chat(user, "Label too big!") return - if(ishuman(A)) - to_chat(user, "You can't label humans.") - return - if(issilicon(A)) - to_chat(user, "You can't label cyborgs.") - return - if(istype(A, /obj/item/reagent_containers/glass)) - to_chat(user, "The label can't stick to the [A.name]. (Try using a pen)") + if(ismob(A)) + to_chat(user, "You can't label creatures!") // use a collar return user.visible_message("[user] labels [A] as [label].", \ "You label [A] as [label].") + investigate_log("[key_name(user)] labelled [A] as [label].", INVESTIGATE_LABEL) // Investigate goes BEFORE rename so the original name is preserved in the log A.name = "[A.name] ([label])" /obj/item/hand_labeler/attack_self(mob/user as mob) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index d37506b3d82..e8858a4dd31 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -34,6 +34,8 @@ var/contact_poison // Reagent ID to transfer on contact var/contact_poison_volume = 0 var/contact_poison_poisoner = null + var/paper_width = 400//Width of the window that opens + var/paper_height = 400//Height of the window that opens var/const/deffont = "Verdana" var/const/signfont = "Times New Roman" @@ -72,12 +74,12 @@ if((!user.say_understands(null, all_languages["Galactic Common"]) && !forceshow) || forcestars) //assuming all paper is written in common is better than hardcoded type checks data = "[name][stars(info)][stamps]" if(view) - usr << browse(data, "window=[name]") + usr << browse(data, "window=[name];size=[paper_width]x[paper_height]") onclose(usr, "[name]") else data = "[name][infolinks ? info_links : info][stamps]" if(view) - usr << browse(data, "window=[name]") + usr << browse(data, "window=[name];size=[paper_width]x[paper_height]") onclose(usr, "[name]") return data @@ -476,6 +478,20 @@ /obj/item/paper/crumpled/bloody icon_state = "scrap_bloodied" +/obj/item/paper/fortune + name = "fortune" + icon_state = "slip" + paper_height = 150 + +/obj/item/paper/fortune/New() + ..() + var/fortunemessage = pick(GLOB.fortune_cookie_messages) + info = "

    [fortunemessage]

    " + info += "

    Lucky numbers: [rand(1,49)], [rand(1,49)], [rand(1,49)], [rand(1,49)], [rand(1,49)]

    " + +/obj/item/paper/fortune/update_icon() + ..() + icon_state = initial(icon_state) /* * Premade paper */ diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 41799958c4f..ed5b7c1cfd4 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -260,7 +260,7 @@ emag_cooldown = world.time + EMAG_DELAY if(ishuman(ass)) //Suit checks are in check_ass var/mob/living/carbon/human/H = ass - temp_img = icon('icons/obj/butts.dmi', H.species.butt_sprite) + temp_img = icon('icons/obj/butts.dmi', H.dna.species.butt_sprite) else if(istype(ass,/mob/living/silicon/robot/drone)) temp_img = icon('icons/obj/butts.dmi', "drone") else if(istype(ass,/mob/living/simple_animal/diona)) diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm index 703ec2bd628..38422a89528 100755 --- a/code/modules/pda/PDA.dm +++ b/code/modules/pda/PDA.dm @@ -44,7 +44,6 @@ var/global/list/obj/item/pda/PDAs = list() new/datum/data/pda/app/notekeeper, new/datum/data/pda/app/messenger, new/datum/data/pda/app/manifest, - new/datum/data/pda/app/chatroom, new/datum/data/pda/app/atmos_scanner, new/datum/data/pda/utility/scanmode/notes, new/datum/data/pda/utility/flashlight) diff --git a/code/modules/pda/chatroom.dm b/code/modules/pda/chatroom.dm deleted file mode 100644 index ef9027b888c..00000000000 --- a/code/modules/pda/chatroom.dm +++ /dev/null @@ -1,265 +0,0 @@ -var/list/chatrooms = list(new /datum/chatroom("General Discussion")) - -/datum/chatroom - var/name = "Generic Chatroom" - var/list/users = list() - var/list/invites = list() - var/list/logs = list() // chat logs - var/topic = "Discussion" // topic message for the chatroom - var/is_public = 1 - var/announcer = "CyberiadAI" - -/datum/chatroom/New(n) - name = n - -/datum/chatroom/proc/post(user, message, username) - if(!user || !message) - return - - if(!username) - if(istype(user, /datum/data/pda/app/chatroom)) - var/datum/data/pda/app/chatroom/c = user - if(!c.pda.owner) - return - username = c.pda.owner - else - return - - logs += list(list(username = username, message = message)) - - for(var/datum/data/pda/app/chatroom/u in users) - spawn() - if(u.messaging_available() && !u.toff && user != u) - u.notify("Post from [username] in #[name], \"[message]\" (Post)") - -/datum/chatroom/proc/announce(user, message) - post(user, "[message]", announcer) - -/datum/chatroom/proc/login(datum/data/pda/app/chatroom/user) - if(!user || !user.pda.owner) - return 0 - - if(user in users) - return 1 - - if(!is_public && !(user in invites)) - return 0 - - users |= user - announce(user, "[user.pda.owner] has entered #[name].") - return 1 - -/datum/chatroom/proc/logout(datum/data/pda/app/chatroom/user) - if(!user || !user.pda.owner || !(user in users)) - return - - users -= user - invites -= user - announce(user, "[user.pda.owner] has left #[name].") - -/datum/data/pda/app/chatroom - name = "Chatbuddy" - icon = "hashtag" - notify_icon = "comments" - template = "pda_chatroom" - var/toff = 0 - var/datum/chatroom/current_room = null - var/inviting = 0 - var/channels_created = 0 - var/max_channels_created = 3 - var/latest_post = 0 - var/auto_scroll = 1 - var/disconnected = 0 - -/datum/data/pda/app/chatroom/Destroy() - for(var/C in chatrooms) - var/datum/chatroom/ch = C - if(src in ch.users) - ch.users -= src - if(src in ch.invites) - ch.invites -= src - return ..() - -/datum/data/pda/app/chatroom/start() - . = ..() - unnotify() - latest_post = 0 - -/datum/data/pda/app/chatroom/update_ui(mob/user as mob, list/data) - data["silent"] = notify_silent - data["toff"] = toff - if(disconnected || !messaging_available(1)) - data["no_server"] = 1 - has_back = 0 - else if(current_room) - data["room"] = current_room.name - data["topic"] = current_room.topic - if(inviting) - data["inviting"] = 1 - var/list/pdas = list() - for(var/A in PDAs) - var/obj/item/pda/P = A - var/datum/data/pda/app/chatroom/C = P.find_program(/datum/data/pda/app/chatroom) - var/datum/data/pda/app/messenger/PM = P.find_program(/datum/data/pda/app/messenger) - - if(!P.owner || P == pda || PM.m_hidden || (C in current_room.invites) || (C in current_room.users)) - continue - pdas += list(list(name = "[P.owner] ([P.ownjob])", ref = "\ref[C]")) - data["people"] = pdas - else - data["history"] = current_room.logs - var/list/users[0] - for(var/U in current_room.users) - var/datum/data/pda/app/chatroom/ch = U - users += "[ch.pda.owner]" - for(var/U in (current_room.invites - current_room.users)) - var/datum/data/pda/app/chatroom/ch = U - users += "[ch.pda.owner]" - data["users"] = users - data["auto_scroll"] = auto_scroll - data["latest_post"] = latest_post - latest_post = current_room.logs.len - has_back = 1 - else - var/list/rooms[0] - for(var/datum/chatroom/c in chatrooms) - if((src in c.users) || (src in c.invites) || c.is_public) - rooms += list(list(name = "[c]", ref = "\ref[c]")) - data["rooms"] = rooms - has_back = 0 - -/datum/data/pda/app/chatroom/proc/messaging_available(cheap = 0) - . = 0 - if(message_servers) - for(var/A in message_servers) - var/obj/machinery/message_server/MS = A - if(MS.active) - . = cheap || pda.test_telecomms() - disconnected = !. - -/datum/data/pda/app/chatroom/proc/check_messaging_available() - . = messaging_available() - if(!.) - to_chat(usr, "ERROR: Messaging server is not responding.") - -/datum/data/pda/app/chatroom/Topic(href, list/href_list) - if(!pda.can_use()) - return - unnotify() - - switch(href_list["choice"]) - if("Toggle Chatroom") - toff = !toff - if("Toggle Ringer") - notify_silent = !notify_silent - if("Back") - if(inviting) - inviting = 0 - else - current_room = null - latest_post = 0 - if("Join") - if(href_list["room"]) - current_room = locate(href_list["room"]) - if(!(src in current_room.users)) - if(!current_room.login(src)) - current_room = null - latest_post = 0 - if("Post") - var/datum/chatroom/target - if(href_list["target"]) - target = locate(href_list["target"]) - else - target = current_room - - if(!target) - return - - var/t = input("Please enter message", target) as text|null - spawn() - if(!t || !check_messaging_available()) - return - t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) - t = readd_quotes(t) - if(!t || !pda.can_use()) - return - - target.post(src, t) - if("Topic") - if(!current_room) - return - - var/t = input("Enter new topic:", current_room, current_room.topic) as text|null - spawn() - if(!t || !check_messaging_available() || !pda.can_use()) - return - t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) - t = readd_quotes(t) - if(!t) - return - - current_room.topic = t - current_room.announce(src, "Topic has been changed to '[t]' by [pda.owner].") - if("Leave") - if(!current_room) - return - - current_room.logout(src) - current_room = null - latest_post = 0 - if("Invite") - if(!current_room) - return - - inviting = 1 - if("Invite PDA") - spawn() - if(!check_messaging_available() || !current_room || !href_list["user"]) - return - - var/datum/data/pda/app/chatroom/C = locate(href_list["user"]) - if(C) - current_room.invites |= C - spawn() - if(C.messaging_available() && !C.toff) - C.notify("Invite to #[current_room] (Join)") - if("New Room") - if(channels_created >= max_channels_created) - alert("This PDA has already reached its maximum channels created.", name) - return - - var/t = input("Enter room name:", name) as text|null - if(!t) - return - t = sanitize(copytext(t, 1, MAX_NAME_LEN)) - t = readd_quotes(t) - - var/access = input("Room access?", current_room) as null|anything in list("Public", "Private") - if(!access) - return - - spawn() - if(!t || !check_messaging_available() || !pda.can_use()) - return - - // check if already taken - for(var/datum/chatroom/C in chatrooms) - if(C.name == t) - alert("Channel with that name already exists.", name) - return - - channels_created++ - current_room = new /datum/chatroom(t) - chatrooms += current_room - latest_post = 0 - - current_room.invites |= src - current_room.is_public = access == "Public" - current_room.login(src) - if(!current_room.is_public) - current_room.announce(src, "Users must be invited to join this room.") - if("Autoscroll") - auto_scroll = !auto_scroll - if("Reconnect") - spawn() - messaging_available() \ No newline at end of file diff --git a/code/modules/pda/messenger_plugins.dm b/code/modules/pda/messenger_plugins.dm index 7e228445d3f..2666b82c5df 100644 --- a/code/modules/pda/messenger_plugins.dm +++ b/code/modules/pda/messenger_plugins.dm @@ -35,9 +35,6 @@ if(.) user.show_message("Virus sent!", 1) var/datum/data/pda/app/M = P.find_program(/datum/data/pda/app/messenger) - if(M) - M.notify_silent = 1 - M = P.find_program(/datum/data/pda/app/chatroom) if(M) M.notify_silent = 1 P.ttone = "silence" diff --git a/code/modules/pda/pdas.dm b/code/modules/pda/pdas.dm index a9a4cbb9714..676d193a6d3 100644 --- a/code/modules/pda/pdas.dm +++ b/code/modules/pda/pdas.dm @@ -54,9 +54,6 @@ var/datum/data/pda/app/M = find_program(/datum/data/pda/app/messenger) if(M) M.notify_silent = 1 - M = find_program(/datum/data/pda/app/chatroom) - if(M) - M.notify_silent = 1 /obj/item/pda/heads default_cartridge = /obj/item/cartridge/head @@ -161,9 +158,6 @@ var/datum/data/pda/app/M = find_program(/datum/data/pda/app/messenger) if(M) M.notify_silent = 1 //Quiet in the library! - M = find_program(/datum/data/pda/app/chatroom) - if(M) - M.notify_silent = 1 //Quiet in the library! /obj/item/pda/clear icon_state = "pda-transp" diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 25a47f19e04..ae64d5d4d6e 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -528,7 +528,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( if(!S) return - if(!(S.status & ORGAN_ROBOT) || user.a_intent != INTENT_HELP || S.open == 2) + if(!S.is_robotic() || user.a_intent != INTENT_HELP || S.open == 2) return ..() if(S.burn_dam) diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 27229a2d8b3..e5a669ef860 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -13,6 +13,7 @@ icon_state = "smes" density = 1 anchored = 1 + defer_process = 1 var/capacity = 5e6 // maximum charge var/charge = 0 // actual charge @@ -39,7 +40,6 @@ var/building_terminal = 0 //Suggestions about how to avoid clickspam building several terminals accepted! var/obj/machinery/power/terminal/terminal = null - /obj/machinery/power/smes/New() ..() component_parts = list() diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 43d418aadf7..fd031f987c6 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -1,21 +1,33 @@ -//Ported from /vg/station13, which was in turn forked from baystation12; -//Please do not bother them with bugs from this port, however, as it has been modified quite a bit. -//Modifications include removing the world-ending full supermatter variation, and leaving only the shard. +#define NITROGEN_RETARDATION_FACTOR 0.15 //Higher == N2 slows reaction more +#define THERMAL_RELEASE_MODIFIER 10000 //Higher == more heat released during reaction +#define PLASMA_RELEASE_MODIFIER 1500 //Higher == less phor.. plasma released by reaction +#define OXYGEN_RELEASE_MODIFIER 15000 //Higher == less oxygen released at high temperature/power +#define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power -#define NITROGEN_RETARDATION_FACTOR 2 //Higher == N2 slows reaction more -#define THERMAL_RELEASE_MODIFIER 5 //Higher == less heat released during reaction -#define PLASMA_RELEASE_MODIFIER 750 //Higher == less plasma released by reaction -#define OXYGEN_RELEASE_MODIFIER 325 //Higher == less oxygen released at high temperature/power -#define REACTION_POWER_MODIFIER 0.55 //Higher == more overall power +/* + How to tweak the SM + POWER_FACTOR directly controls how much power the SM puts out at a given level of excitation (power var). Making this lower means you have to work the SM harder to get the same amount of power. + CRITICAL_TEMPERATURE The temperature at which the SM starts taking damage. + CHARGING_FACTOR Controls how much emitter shots excite the SM. + DAMAGE_RATE_LIMIT Controls the maximum rate at which the SM will take damage due to high temperatures. +*/ + +//Controls how much power is produced by each collector in range - this is the main parameter for tweaking SM balance, as it basically controls how the power variable relates to the rest of the game. +#define POWER_FACTOR 1.0 +#define DECAY_FACTOR 700 //Affects how fast the supermatter power decays +#define CRITICAL_TEMPERATURE 5000 //K +#define CHARGING_FACTOR 0.05 +#define DAMAGE_RATE_LIMIT 4.5 //damage rate cap at power = 300, scales linearly with power -//These would be what you would get at point blank, decreases with distance +// Base variants are applied to everyone on the same Z level +// Range variants are applied on per-range basis: numbers here are on point blank, it scales with the map size (assumes square shaped Z levels) #define DETONATION_RADS 200 #define DETONATION_HALLUCINATION 600 -#define WARNING_DELAY 30 //seconds between warnings. +#define WARNING_DELAY 20 //seconds between warnings. /obj/machinery/power/supermatter_shard name = "supermatter shard" desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure. You get headaches just from looking at it." @@ -35,15 +47,16 @@ var/safe_alert = "Crystalline hyperstructure returning to safe operating levels." var/warning_point = 50 var/warning_alert = "Danger! Crystal hyperstructure instability!" - var/emergency_point = 500 + var/emergency_point = 400 var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT." - var/explosion_point = 900 + var/explosion_point = 600 var/emergency_issued = 0 var/explosion_power = 8 var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning + var/last_zap = 0 // Time in 1/10th of seconds since the last tesla zap var/power = 0 var/oxygen = 0 // Moving this up here for easier debugging. @@ -51,38 +64,90 @@ //Temporary values so that we can optimize this //How much the bullets damage should be multiplied by when it is added to the internal variables var/config_bullet_energy = 2 - //How much of the power is left after processing is finished? -// var/config_power_reduction_per_tick = 0.5 //How much hallucination should it produce per unit of power? var/config_hallucination_power = 0.1 + var/debug = 0 + + var/disable_adminwarn = FALSE + + var/aw_normal = FALSE + var/aw_notify = FALSE + var/aw_warning = FALSE + var/aw_danger = FALSE + var/aw_emerg = FALSE + var/aw_delam = FALSE + var/obj/item/radio/radio //for logging var/has_been_powered = 0 var/has_reached_emergency = 0 +/obj/machinery/power/supermatter_shard/crystal + name = "supermatter crystal" + desc = "A strangely translucent and iridescent crystal." + base_icon_state = "darkmatter" + icon_state = "darkmatter" + anchored = TRUE + warning_point = 200 + emergency_point = 2000 + explosion_point = 3600 + gasefficency = 0.25 + explosion_power = 24 + + /obj/machinery/power/supermatter_shard/New() . = ..() poi_list |= src + //Added to the atmos_machine process as the SM is highly coupled with the atmospherics system. + //Having the SM run at a different rate then atmospherics causes odd behavior. + SSair.atmos_machinery += src radio = new(src) radio.listening = 0 investigate_log("has been created.", "supermatter") +/obj/machinery/power/supermatter_shard/proc/handle_admin_warnings() + if(disable_adminwarn) + return + + // Generic checks, similar to checks done by supermatter monitor program. + aw_normal = status_adminwarn_check(SUPERMATTER_NORMAL, aw_normal, "INFO: Supermatter crystal has been energised.(JMP).", FALSE) + aw_notify = status_adminwarn_check(SUPERMATTER_NOTIFY, aw_notify, "INFO: Supermatter crystal is approaching unsafe operating temperature.(JMP).", FALSE) + aw_warning = status_adminwarn_check(SUPERMATTER_WARNING, aw_warning, "WARN: Supermatter crystal is taking integrity damage!(JMP).", FALSE) + aw_danger = status_adminwarn_check(SUPERMATTER_DANGER, aw_danger, "WARN: Supermatter integrity is below 75%!(JMP).", TRUE) + aw_emerg = status_adminwarn_check(SUPERMATTER_EMERGENCY, aw_emerg, "CRIT: Supermatter integrity is below 50%!(JMP).", FALSE) + aw_delam = status_adminwarn_check(SUPERMATTER_DELAMINATING, aw_delam, "CRIT: Supermatter is delaminating!(JMP).", TRUE) + +/obj/machinery/power/supermatter_shard/proc/status_adminwarn_check(var/min_status, var/current_state, var/message, var/send_to_irc = FALSE) + var/status = get_status() + if(status >= min_status) + if(!current_state) + log_and_message_admins(message) + if(send_to_irc) + send2adminirc(message) + return TRUE + else + return FALSE + + /obj/machinery/power/supermatter_shard/Destroy() investigate_log("has been destroyed.", "supermatter") + if(damage > emergency_point) + emergency_lighting(0) QDEL_NULL(radio) poi_list.Remove(src) + SSair.atmos_machinery -= src return ..() /obj/machinery/power/supermatter_shard/proc/explode() investigate_log("has exploded.", "supermatter") - explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1) + explosion(get_turf(src), explosion_power, explosion_power * 1.2, explosion_power * 1.5, explosion_power * 2, 1, 1) qdel(src) return -/obj/machinery/power/supermatter_shard/process() +/obj/machinery/power/supermatter_shard/process_atmos() var/turf/L = loc if(isnull(L)) // We have a null turf...something is wrong, stop processing this entity. @@ -91,11 +156,10 @@ if(!istype(L)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now. return //Yeah just stop. - if(istype(L, /turf/space)) // Stop processing this stuff if we've been ejected. - return - if(damage > warning_point) // while the core is still damaged and it's still worth noting its status if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY) + alarm() + emergency_lighting(1) var/stability = num2text(round((damage / explosion_point) * 100)) if(damage > emergency_point) @@ -112,6 +176,7 @@ else // Phew, we're safe radio.autosay("[safe_alert]", src.name) + emergency_lighting(0) lastwarning = world.timeofday if(damage > explosion_point) @@ -128,6 +193,11 @@ mob.apply_effect(rads, IRRADIATE) explode() + emergency_lighting(0) + + if(damage > warning_point && world.timeofday > last_zap) + last_zap = world.timeofday + rand(80,200) + supermatter_zap() //Ok, get the air from the turf var/datum/gas_mixture/env = L.return_air() @@ -135,52 +205,57 @@ //Remove gas from surrounding area var/datum/gas_mixture/removed = env.remove(gasefficency * env.total_moles()) - if(!removed || !removed.total_moles()) - damage += max((power-1600)/10, 0) - power = min(power, 1600) - return 1 + //ensure that damage doesn't increase too quickly due to super high temperatures resulting from no coolant, for example. We dont want the SM exploding before anyone can react. + //We want the cap to scale linearly with power (and explosion_point). Let's aim for a cap of 5 at power = 300 (based on testing, equals roughly 5% per SM alert announcement). + var/damage_inc_limit = (power/300)*(explosion_point/1000)*DAMAGE_RATE_LIMIT + + if(!env || !removed || !removed.total_moles()) + damage += max((power - 15*POWER_FACTOR)/10, 0) + else + damage_archived = damage + + damage = max(0, damage + between(-DAMAGE_RATE_LIMIT, (removed.temperature - CRITICAL_TEMPERATURE) / 150, damage_inc_limit)) - damage_archived = damage - damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 ) - //Ok, 100% oxygen atmosphere = best reaction //Maxes out at 100% oxygen pressure - oxygen = max(min((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0) - - var/temp_factor = 50 + oxygen = Clamp((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / removed.total_moles(), 0, 1) + var/temp_factor + var/equilibrium_power if(oxygen > 0.8) - // with a perfect gas mix, make the power less based on heat + //If chain reacting at oxygen > 0.8, we want the power at 800 K to stabilize at a power level of 400 + equilibrium_power = 400 icon_state = "[base_icon_state]_glow" else - // in normal mode, base the produced energy around the heat - temp_factor = 30 + //Otherwise, we want the power at 800 K to stabilize at a power level of 250 + equilibrium_power = 250 icon_state = base_icon_state - power = max( (removed.temperature * temp_factor / T0C) * oxygen + power, 0) //Total laser power plus an overload - - //We've generated power, now let's transfer it to the collectors for storing/usage - transfer_energy() + temp_factor = ((equilibrium_power / DECAY_FACTOR) ** 3) / 800 + power = max((removed.temperature * temp_factor) * oxygen + power, 0) var/device_energy = power * REACTION_POWER_MODIFIER - //To figure out how much temperature to add each tick, consider that at one atmosphere's worth - //of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature - //that the device energy is around 2140. At that stage, we don't want too much heat to be put out - //Since the core is effectively "cold" + var/heat_capacity = removed.heat_capacity() - //Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock - //is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall. - removed.temperature += (device_energy / THERMAL_RELEASE_MODIFIER) - - removed.temperature = max(0, min(removed.temperature, 2500)) - - //Calculate how much gas to release removed.toxins += max(device_energy / PLASMA_RELEASE_MODIFIER, 0) removed.oxygen += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0) + var/thermal_power = THERMAL_RELEASE_MODIFIER * device_energy + if(debug) + var/heat_capacity_new = removed.heat_capacity() + visible_message("[src]: Releasing [round(thermal_power)] W.") + visible_message("[src]: Releasing additional [round((heat_capacity_new - heat_capacity)*removed.temperature)] W with exhaust gasses.") + + removed.temperature += (device_energy) + + removed.temperature = max(0, min(removed.temperature, 10000)) + env.merge(removed) + air_update_turf() + transfer_energy() + for(var/mob/living/carbon/human/l in view(src, min(7, round(sqrt(power/6))))) // If they can see it without mesons on. Bad on them. if(l.glasses && istype(l.glasses, /obj/item/clothing/glasses/meson)) @@ -196,7 +271,8 @@ var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src),1) ) l.apply_effect(rads, IRRADIATE) - power -= (power/500)**3 + power -= (power/DECAY_FACTOR)**3 + handle_admin_warnings() return 1 @@ -217,12 +293,13 @@ has_been_powered = 1 else damage += Proj.damage * config_bullet_energy + supermatter_zap() return 0 /obj/machinery/power/supermatter_shard/singularity_act() var/gain = 100 investigate_log("Supermatter shard consumed by singularity.","singulo") - message_admins("Singularity has consumed a supermatter shard and can now become stage six.") + message_admins("Singularity has consumed a supermatter shard and can now become stage six.(JMP).") visible_message("[src] is consumed by the singularity!") for(var/mob/M in mob_list) M << 'sound/effects/supermatter.ogg' //everyone gunna know bout this @@ -306,7 +383,6 @@ user.apply_effect(150, IRRADIATE) - /obj/machinery/power/supermatter_shard/Bumped(atom/AM as mob|obj) if(istype(AM, /mob/living)) AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [AM.p_their(TRUE)] body starts to glow and catch flame before flashing into ash.",\ @@ -335,6 +411,8 @@ qdel(AM) power += 200 + supermatter_zap() + //Some poor sod got eaten, go ahead and irradiate people nearby. for(var/mob/living/L in range(10)) @@ -346,3 +424,53 @@ "The unearthly ringing subsides and you notice you have new radiation burns.", 2) else L.show_message("You hear an uneartly ringing and notice your skin is covered in fresh radiation burns.", 2) + +#define CRITICAL_TEMPERATURE 10000 + +/obj/machinery/power/supermatter_shard/proc/get_status() + var/turf/T = get_turf(src) + if(!T) + return SUPERMATTER_ERROR + var/datum/gas_mixture/air = T.return_air() + if(!air) + return SUPERMATTER_ERROR + + if(get_integrity() < 25) + return SUPERMATTER_DELAMINATING + + if(get_integrity() < 50) + return SUPERMATTER_EMERGENCY + + if(get_integrity() < 75) + return SUPERMATTER_DANGER + + if((get_integrity() < 100) || (air.temperature > CRITICAL_TEMPERATURE)) + return SUPERMATTER_WARNING + + if(air.temperature > (CRITICAL_TEMPERATURE * 0.8)) + return SUPERMATTER_NOTIFY + + if(power > 5) + return SUPERMATTER_NORMAL + return SUPERMATTER_INACTIVE + +/obj/machinery/power/supermatter_shard/proc/alarm() + switch(get_status()) + if(SUPERMATTER_DELAMINATING) + playsound(src, 'sound/misc/bloblarm.ogg', 100) + if(SUPERMATTER_EMERGENCY) + playsound(src, 'sound/machines/engine_alert1.ogg', 100) + if(SUPERMATTER_DANGER) + playsound(src, 'sound/machines/engine_alert2.ogg', 100) + if(SUPERMATTER_WARNING) + playsound(src, 'sound/machines/terminal_alert.ogg', 75) + +/obj/machinery/power/supermatter_shard/proc/emergency_lighting(active) + if(active) + post_status("alert", "radiation") + else + post_status("shuttle") + +/obj/machinery/power/supermatter_shard/proc/supermatter_zap() + playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5) + tesla_zap(src, 10, max(1000,power * damage / explosion_point)) diff --git a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm index 11873b5acdf..3e43c5638d1 100644 --- a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm +++ b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm @@ -38,4 +38,4 @@ if(get_step(T,direction) in mother.map) continue return 1 - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 6ad60248a28..a7baacb9583 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -198,13 +198,6 @@ desc= "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets" ammo_type = /obj/item/ammo_casing/c10mm/ap -/obj/item/ammo_box/magazine/m10mm/empty //for maint drops - desc = "A gun magazine. Seems to be broken and can only hold one bullet. Pretty useless." - max_ammo = 1 - -/obj/item/ammo_box/magazine/m10mm/empty/update_icon() - icon_state = "[initial(icon_state)]-[stored_ammo.len ? "8" : "0"]" - /obj/item/ammo_box/magazine/m45 name = "handgun magazine (.45)" icon_state = "45" diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 51bf515ca1e..165e75f1875 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -153,10 +153,10 @@ process_fire(target,user,1,params) -/obj/item/gun/proc/can_trigger_gun(var/mob/living/user) +/obj/item/gun/proc/can_trigger_gun(mob/living/user) if(!user.can_use_guns(src)) return 0 - if(restricted_species && restricted_species.len && !(user.get_species() in restricted_species)) + if(restricted_species && restricted_species.len && !is_type_in_list(user.dna.species, restricted_species)) to_chat(user, "[src] is incompatible with your biology!") return 0 return 1 diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index 7093d587b3c..95e1a586469 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -11,7 +11,7 @@ can_suppress = 0 var/charge_tick = 0 var/charge_delay = 15 - restricted_species = list("Vox", "Vox Armalis") + restricted_species = list(/datum/species/vox) /obj/item/gun/projectile/automatic/spikethrower/New() ..() @@ -79,7 +79,7 @@ force = 10 ammo_type = list(/obj/item/ammo_casing/energy/sonic) cell_type = /obj/item/stock_parts/cell/super - restricted_species = list("Vox Armalis") + restricted_species = list(/datum/species/vox/armalis) /obj/item/gun/energy/noisecannon/update_icon() return diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index 103595d7242..7ac82f99d5c 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -26,12 +26,6 @@ mag_type = /obj/item/ammo_box/magazine/m45 can_suppress = 0 -/obj/item/gun/projectile/automatic/pistol/empty //empty stetchshit for maint spawns - -/obj/item/gun/projectile/automatic/pistol/empty/New() - magazine = new /obj/item/ammo_box/magazine/m10mm/empty(src) - ..() - /obj/item/gun/projectile/automatic/pistol/enforcer name = "Enforcer .45" desc = "A pistol of modern design." diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index e38a42ff88f..e19cd1165b5 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -83,7 +83,7 @@ var/blood_color = "#C80000" if(ishuman(target)) H = target - blood_color = H.species.blood_color + blood_color = H.dna.species.blood_color new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, blood_color) if(prob(33)) var/list/shift = list("x" = 0, "y" = 0) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 3fe2277ed3b..1df45dbe064 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -24,15 +24,15 @@ var/exp_flash = 3 var/exp_fire = 2 -/obj/item/projectile/magic/death/on_hit(var/mob/living/carbon/G) +/obj/item/projectile/magic/death/on_hit(mob/living/carbon/C) . = ..() - if(isliving(G)) - if(G.get_species() == "Machine") //speshul snowfleks deserv speshul treetment - G.adjustFireLoss(6969) //remember - slimes love fire + if(isliving(C)) + if(ismachine(C)) //speshul snowfleks deserv speshul treetment + C.adjustFireLoss(6969) //remember - slimes love fire else - G.death() + C.death() - visible_message("[G] topples backwards as the death bolt impacts [G.p_them()]!") + visible_message("[C] topples backwards as the death bolt impacts [C.p_them()]!") /obj/item/projectile/magic/fireball/Range() var/turf/T1 = get_step(src,turn(dir, -45)) @@ -225,20 +225,17 @@ proc/wabbajack(mob/living/M) else new_mob = new /mob/living/simple_animal/chick(M.loc) new_mob.universal_speak = 1 if("human") - new_mob = new /mob/living/carbon/human/human(M.loc) + new_mob = new /mob/living/carbon/human(M.loc) // Include standard, whitelisted, and monkey species... - var/list/new_species = list("Human","Tajaran","Skrell","Unathi","Diona","Vulpkanin") - new_species |= whitelisted_species - for(var/SN in all_species) - var/datum/species/S = all_species[SN] - if(S.greater_form) // Monkeys - new_species |= SN - new_species -= "Vox Armalis" // ... but not Armalis. They're not really designed to be playable - new_species |= "Golem" // Also, golems, sure, why not - var/picked_species = pick(new_species) + var/list/new_species = list() + for(var/datum/species/S in subtypesof(/datum/species)) + if(istype(S, /datum/species/vox/armalis)) + continue + new_species.Add(S) var/mob/living/carbon/human/H = new_mob - H.set_species(picked_species) - randomize = picked_species + var/datum/species/S = pick(new_species) + H.set_species(S) + randomize = initial(S.name) var/datum/preferences/A = new() //Randomize appearance for the human A.copy_to(new_mob) else diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 2c774b7f3dd..2003e78b780 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -133,7 +133,7 @@ var/mob/living/M = target if(ishuman(target)) var/mob/living/carbon/human/H = M - if(IS_PLANT in H.species.species_traits) + if(IS_PLANT in H.dna.species.species_traits) if(prob(15)) M.apply_effect((rand(30,80)),IRRADIATE) M.Weaken(5) @@ -166,7 +166,7 @@ var/mob/M = target if(ishuman(target)) //These rays make plantmen fat. var/mob/living/carbon/human/H = M - if(IS_PLANT in H.species.species_traits) + if(IS_PLANT in H.dna.species.species_traits) H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL) else if(iscarbon(target)) M.show_message("The radiation beam dissipates harmlessly through your body.") diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 83a000fa693..73a591f9ddb 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -209,17 +209,17 @@ var/const/INGEST = 2 //Check if this mob's species is set and can process this type of reagent var/can_process = 0 //If we somehow avoided getting a species or reagent_tag set, we'll assume we aren't meant to process ANY reagents (CODERS: SET YOUR SPECIES AND TAG!) - if(H.species && H.species.reagent_tag) - if((R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN + if(H.dna.species && H.dna.species.reagent_tag) + if((R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN can_process = 1 - if((R.process_flags & ORGANIC) && (H.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG + if((R.process_flags & ORGANIC) && (H.dna.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG can_process = 1 //Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater - if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_DUO)) + if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_DUO)) can_process = 1 //If handle_reagents returns 0, it's doing the reagent removal on its own - var/species_handled = !(H.species.handle_reagents(H, R)) + var/species_handled = !(H.dna.species.handle_reagents(H, R)) can_process = can_process && !species_handled //If the mob can't process it, remove the reagent at it's normal rate without doing any addictions, overdoses, or on_mob_life() for the reagent if(can_process == 0) @@ -481,13 +481,13 @@ var/const/INGEST = 2 if(ishuman(M)) var/mob/living/carbon/human/H = M //Check if this mob's species is set and can process this type of reagent - if(H.species && H.species.reagent_tag) - if((R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN + if(H.dna.species && H.dna.species.reagent_tag) + if((R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN can_process = 1 - if((R.process_flags & ORGANIC) && (H.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG + if((R.process_flags & ORGANIC) && (H.dna.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG can_process = 1 //Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater - if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_DUO)) + if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_DUO)) can_process = 1 //We'll assume that non-human mobs lack the ability to process synthetic-oriented reagents (adjust this if we need to change that assumption) else diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index bdabfd21956..7426844e292 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -31,7 +31,7 @@ if(H.can_eat(diet_flags)) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients if(prob(50)) M.adjustBruteLoss(-1) - if(!(NO_BLOOD in H.species.species_traits))//do not restore blood on things with no blood by nature. + if(!(NO_BLOOD in H.dna.species.species_traits))//do not restore blood on things with no blood by nature. if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 0.4 ..() @@ -66,7 +66,7 @@ M.satiety += 30 if(ishuman(M)) var/mob/living/carbon/human/H = M - if(!(NO_BLOOD in H.species.species_traits))//do not restore blood on things with no blood by nature. + if(!(NO_BLOOD in H.dna.species.species_traits))//do not restore blood on things with no blood by nature. if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 0.5 ..() diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index d1b44798b85..f603d5eb0d1 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -92,13 +92,14 @@ //Mitocholide is hard enough to get, it's probably fair to make this all internal organs for(var/obj/item/organ/internal/I in H.internal_organs) - I.receive_damage(-0.4) + I.heal_internal_damage(0.4) ..() /datum/reagent/medicine/mitocholide/reaction_obj(obj/O, volume) if(istype(O, /obj/item/organ)) var/obj/item/organ/Org = O - Org.rejuvenate() + if(!Org.is_robotic()) + Org.rejuvenate() /datum/reagent/medicine/cryoxadone name = "Cryoxadone" @@ -220,7 +221,7 @@ M.adjustFireLoss(-2*REAGENTS_EFFECT_MULTIPLIER) if(ishuman(M) && prob(33)) var/mob/living/carbon/human/H = M - if(!(NO_BLOOD in H.species.species_traits))//do not restore blood on things with no blood by nature. + if(!(NO_BLOOD in H.dna.species.species_traits))//do not restore blood on things with no blood by nature. if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 1 ..() @@ -520,7 +521,7 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) if(istype(E)) - E.receive_damage(-1) + E.heal_internal_damage(1) M.AdjustEyeBlurry(-1) M.AdjustEarDamage(-1) if(prob(50)) diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index a67fcd0f751..fdddea44bd2 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -155,7 +155,7 @@ /datum/reagent/iron/on_mob_life(mob/living/M) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(!H.species.exotic_blood && !(NO_BLOOD in H.species.species_traits)) + if(!H.dna.species.exotic_blood && !(NO_BLOOD in H.dna.species.species_traits)) if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 0.8 ..() @@ -313,8 +313,8 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/head/head_organ = H.get_organ("head") - head_organ.h_style = random_hair_style(H.gender, head_organ.species.name) - head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species.name) + head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.name) H.update_hair() H.update_fhair() ..() @@ -335,14 +335,14 @@ var/datum/sprite_accessory/tmp_hair_style = hair_styles_full_list["Very Long Hair"] var/datum/sprite_accessory/tmp_facial_hair_style = facial_hair_styles_list["Very Long Beard"] - if(head_organ.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. + if(head_organ.dna.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. head_organ.h_style = "Very Long Hair" else //Otherwise, give them a random hair style. - head_organ.h_style = random_hair_style(H.gender, head_organ.species.name) - if(head_organ.species.name in tmp_facial_hair_style.species_allowed) //If 'Very Long Beard' is a style the person's species can have, give it to them. + head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name) + if(head_organ.dna.species.name in tmp_facial_hair_style.species_allowed) //If 'Very Long Beard' is a style the person's species can have, give it to them. head_organ.f_style = "Very Long Beard" else //Otherwise, give them a random facial hair style. - head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species.name) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.name) H.update_hair() H.update_fhair() if(!H.wear_mask || H.wear_mask && !istype(H.wear_mask, /obj/item/clothing/mask/fakemoustache)) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm index b54444ee2d4..f2a5e8b9e24 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -221,7 +221,7 @@ /datum/reagent/pyrosium name = "Pyrosium" id = "pyrosium" - description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly cools all other reagents in the mob down to 0K." + description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly heats all other reagents." color = "#B20000" // rgb: 139, 166, 233 process_flags = ORGANIC | SYNTHETIC diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 7bff61218c6..a3fc113339e 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -61,12 +61,12 @@ /datum/reagent/slimetoxin/on_mob_life(mob/living/M) if(ishuman(M)) var/mob/living/carbon/human/human = M - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(M, "Your flesh rapidly mutates!") to_chat(M, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(M, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(M, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) ..() /datum/reagent/aslimetoxin @@ -217,7 +217,7 @@ if(method == TOUCH) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.get_species() == "Grey") + if(isgrey(H)) return if(volume > 25) @@ -246,7 +246,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.get_species() == "Grey") + if(isgrey(H)) return if(volume >=10 && volume <=25) @@ -961,7 +961,7 @@ C.adjustToxLoss(lethality) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(IS_PLANT in H.species.species_traits) //plantmen take a LOT of damage + if(IS_PLANT in H.dna.species.species_traits) //plantmen take a LOT of damage H.adjustToxLoss(50) ..() else if(istype(M, /mob/living/simple_animal/diona)) //plantmen monkeys (diona) take EVEN MORE damage @@ -995,7 +995,7 @@ C.adjustToxLoss(2) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.get_species() == "Kidan") //RIP + if(iskidan(H)) //RIP H.adjustToxLoss(20) /datum/reagent/capulettium diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index cd338cb048d..199edb72fb4 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -29,7 +29,7 @@ var/mob/living/carbon/human/H = M - if(H.get_species() != "Grey") //God this is so gross I hate it. + if(!isgrey(H)) //God this is so gross I hate it. return if(volume > 25) @@ -58,7 +58,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.get_species() != "Grey") + if(!isgrey(H)) return if(volume < 10) diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index c7acc705150..a5d37cb8b60 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -26,6 +26,33 @@ empulse(location, round(created_volume / 24), round(created_volume / 14), 1) holder.clear_reagents() +/datum/chemical_reaction/beesplosion + name = "Bee Explosion" + id = "beesplosion" + result = null + required_reagents = list("honey" = 1, "strange_reagent" = 1, "radium" = 1) + result_amount = 1 + +/datum/chemical_reaction/beesplosion/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + if(created_volume < 5) + playsound(location,'sound/effects/sparks1.ogg', 100, 1) + else + playsound(location,'sound/creatures/bee.ogg', 100, 1) + var/list/beeagents = list() + for(var/X in holder.reagent_list) + var/datum/reagent/R = X + if(R.id in required_reagents) + continue + if(!R.can_synth) + continue + beeagents += R + var/bee_amount = round(created_volume * 0.2) + for(var/i in 1 to bee_amount) + var/mob/living/simple_animal/hostile/poison/bees/new_bee = new(location) + if(LAZYLEN(beeagents)) + new_bee.assign_reagent(pick(beeagents)) + /datum/chemical_reaction/nitroglycerin name = "Nitroglycerin" id = "nitroglycerin" diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 28d8857efe1..e3e0daee333 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -61,10 +61,10 @@ /obj/item/reagent_containers/afterattack(obj/target, mob/user , flag) return -/obj/item/reagent_containers/proc/reagentlist(obj/item/reagent_containers/snack) //Attack logs for regents in pills +/obj/item/reagent_containers/proc/reagentlist() //Return reagents in a reagent_container, default to source var/data - if(snack && snack.reagents && snack.reagents.reagent_list && snack.reagents.reagent_list.len) //find a reagent list if there is and check if it has entries - for(var/datum/reagent/R in snack.reagents.reagent_list) //no reagents will be left behind + if(reagents && reagents.reagent_list && reagents.reagent_list.len) //find a reagent list if there is and check if it has entries + for(var/datum/reagent/R in reagents.reagent_list) //no reagents will be left behind data += "[R.id]([R.volume] units); " //Using IDs because SOME chemicals(I'm looking at you, chlorhydrate-beer) have the same names as other chemicals. return data else return "No reagents" diff --git a/code/modules/recycling/belt-placer.dm b/code/modules/recycling/belt-placer.dm new file mode 100644 index 00000000000..1b473bef814 --- /dev/null +++ b/code/modules/recycling/belt-placer.dm @@ -0,0 +1,46 @@ +/obj/item/storage/conveyor //Stores conveyor belts, click floor to make belt, use a conveyor switch on this to link all belts to that lever. + name = "conveyor belt placer" + desc = "This device facilitates the rapid deployment of conveyor belts." + icon_state = "belt_placer" + item_state = "belt_placer" + w_class = WEIGHT_CLASS_BULKY //Because belts are large things, you know? + can_hold = list(/obj/item/conveyor_construct) + flags = CONDUCT + max_w_class = WEIGHT_CLASS_BULKY + max_combined_w_class = 28 //7 belts + allow_quick_gather = TRUE + allow_quick_empty = TRUE + display_contents_with_number = TRUE + use_to_pickup = TRUE + origin_tech = "engineering=1" + +/obj/item/storage/conveyor/bluespace + name = "bluespace conveyor belt placer" + desc = "This device facilitates the rapid deployment of conveyor belts. It utilises bluespace in order to hold many more belts than its regular counterpart." + icon_state = "bluespace_belt_placer" + item_state = "bluespace_belt_placer" + w_class = WEIGHT_CLASS_NORMAL + storage_slots = 50 + max_combined_w_class = 200 //50 belts + origin_tech = "engineering=2;bluespace=1" + +/obj/item/storage/conveyor/attackby(obj/item/I, mob/user, params) //So we can link belts en masse + if(istype(I, /obj/item/conveyor_switch_construct)) + var/obj/item/conveyor_switch_construct/S = I + var/linked = FALSE //For nice message + for(var/obj/item/conveyor_construct/C in src) + C.id = S.id + linked = TRUE + if(linked) + to_chat(user, "All belts in [src] linked with [S].") + else + return ..() + +/obj/item/storage/conveyor/afterattack(atom/A, mob/user, proximity) + if(!proximity) + return + var/obj/item/conveyor_construct/C = locate() in src + if(!C) + to_chat(user, "There are no belts in [src].") + else + C.afterattack(A, user, proximity) diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 3658846a696..c7e276cae17 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -11,66 +11,57 @@ density = 0 pressure_resistance = 5*ONE_ATMOSPHERE level = 2 - var/ptype = 0 - // 0=straight, 1=bent, 2=junction-j1, 3=junction-j2, 4=junction-y, 5=trunk, 6=disposal bin, 7=outlet, 8=inlet - + var/ptype = PIPE_DISPOSALS_STRAIGHT //Use the defines + var/base_state var/dpdir = 0 // directions as disposalpipe - var/base_state = "pipe-s" + +/obj/structure/disposalconstruct/New(loc, pipe_type, direction) + ..() + if(pipe_type) + ptype = pipe_type + if(dir) + dir = direction + update() // update iconstate and dpdir due to dir and type /obj/structure/disposalconstruct/proc/update() + base_state = get_pipe_icon(ptype) + icon_state = "con[base_state]" var/flip = turn(dir, 180) var/left = turn(dir, 90) var/right = turn(dir, -90) - + name = get_pipe_name(ptype, PIPETYPE_DISPOSAL) switch(ptype) - if(0) - base_state = "pipe-s" + if(PIPE_DISPOSALS_STRAIGHT) dpdir = dir | flip - if(1) - base_state = "pipe-c" + if(PIPE_DISPOSALS_BENT) dpdir = dir | right - if(2) - base_state = "pipe-j1" + if(PIPE_DISPOSALS_JUNCTION_RIGHT) dpdir = dir | right | flip - if(3) - base_state = "pipe-j2" + if(PIPE_DISPOSALS_JUNCTION_LEFT) dpdir = dir | left | flip - if(4) - base_state = "pipe-y" + if(PIPE_DISPOSALS_Y_JUNCTION) dpdir = dir | left | right - if(5) - base_state = "pipe-t" + if(PIPE_DISPOSALS_TRUNK) dpdir = dir - // disposal bin has only one dir, thus we don't need to care about setting it - if(6) - if(anchored) - base_state = "disposal" - else - base_state = "condisposal" - - if(7) - base_state = "outlet" - dpdir = dir - - if(8) - base_state = "intake" - dpdir = dir - - if(9) - base_state = "pipe-j1s" + if(PIPE_DISPOSALS_SORT_RIGHT) dpdir = dir | right | flip - - if(10) - base_state = "pipe-j2s" + if(PIPE_DISPOSALS_SORT_LEFT) dpdir = dir | left | flip - - - if(ptype<6 || ptype>8) + // disposal bin has only one dir, thus we don't need to care about setting it + if(PIPE_DISPOSALS_BIN) + if(!anchored) + icon_state = "[base_state]-unanchored" + else + icon_state = base_state + if(PIPE_DISPOSALS_OUTLET) + dpdir = dir + icon_state = base_state + if(PIPE_DISPOSALS_CHUTE) + dpdir = dir + icon_state = base_state + if(!(ptype in list(PIPE_DISPOSALS_BIN, PIPE_DISPOSALS_OUTLET, PIPE_DISPOSALS_CHUTE))) icon_state = "con[base_state]" - else - icon_state = base_state - if(invisibility) // if invisible, fade icon icon -= rgb(0,0,0,128) @@ -116,33 +107,33 @@ dir = turn(dir, 180) switch(ptype) - if(2) - ptype = 3 - if(3) - ptype = 2 - if(9) - ptype = 10 - if(10) - ptype = 9 + if(PIPE_DISPOSALS_JUNCTION_RIGHT) + ptype = PIPE_DISPOSALS_JUNCTION_LEFT + if(PIPE_DISPOSALS_JUNCTION_LEFT) + ptype = PIPE_DISPOSALS_JUNCTION_RIGHT + if(PIPE_DISPOSALS_SORT_RIGHT) + ptype = PIPE_DISPOSALS_SORT_LEFT + if(PIPE_DISPOSALS_SORT_LEFT) + ptype = PIPE_DISPOSALS_SORT_RIGHT update() // returns the type path of disposalpipe corresponding to this item dtype /obj/structure/disposalconstruct/proc/dpipetype() switch(ptype) - if(0,1) + if(PIPE_DISPOSALS_STRAIGHT, PIPE_DISPOSALS_BENT) return /obj/structure/disposalpipe/segment - if(2,3,4) + if(PIPE_DISPOSALS_JUNCTION_RIGHT, PIPE_DISPOSALS_JUNCTION_LEFT, PIPE_DISPOSALS_Y_JUNCTION) return /obj/structure/disposalpipe/junction - if(5) + if(PIPE_DISPOSALS_TRUNK) return /obj/structure/disposalpipe/trunk - if(6) + if(PIPE_DISPOSALS_BIN) return /obj/machinery/disposal - if(7) + if(PIPE_DISPOSALS_OUTLET) return /obj/structure/disposaloutlet - if(8) + if(PIPE_DISPOSALS_CHUTE) return /obj/machinery/disposal/deliveryChute - if(9,10) + if(PIPE_DISPOSALS_SORT_RIGHT, PIPE_DISPOSALS_SORT_LEFT) return /obj/structure/disposalpipe/sortjunction return @@ -157,13 +148,13 @@ var/ispipe = 0 // Indicates if we should change the level of this pipe src.add_fingerprint(user) switch(ptype) - if(6) + if(PIPE_DISPOSALS_BIN) nicetype = "disposal bin" - if(7) + if(PIPE_DISPOSALS_OUTLET) nicetype = "disposal outlet" - if(8) + if(PIPE_DISPOSALS_CHUTE) nicetype = "delivery chute" - if(9, 10) + if(PIPE_DISPOSALS_SORT_RIGHT, PIPE_DISPOSALS_SORT_LEFT) nicetype = "sorting pipe" ispipe = 1 else @@ -197,7 +188,7 @@ return var/obj/structure/disposalpipe/CP = locate() in T - if(ptype>=6 && ptype <= 8) // Disposal or outlet + if(ptype in list(PIPE_DISPOSALS_BIN, PIPE_DISPOSALS_OUTLET, PIPE_DISPOSALS_CHUTE)) // Disposal or outlet if(CP) // There's something there if(!istype(CP,/obj/structure/disposalpipe/trunk)) to_chat(user, "The [nicetype] requires a trunk underneath it in order to work.") @@ -236,22 +227,22 @@ P.update_icon() //Needs some special treatment ;) - if(ptype==9 || ptype==10) + if(ptype == PIPE_DISPOSALS_SORT_RIGHT || ptype == PIPE_DISPOSALS_SORT_LEFT) var/obj/structure/disposalpipe/sortjunction/SortP = P SortP.updatedir() - else if(ptype==6) // Disposal bin + else if(ptype == PIPE_DISPOSALS_BIN) // Disposal bin var/obj/machinery/disposal/P = new /obj/machinery/disposal(src.loc) src.transfer_fingerprints_to(P) P.mode = 0 // start with pump off - else if(ptype==7) // Disposal outlet + else if(ptype == PIPE_DISPOSALS_OUTLET) // Disposal outlet var/obj/structure/disposaloutlet/P = new /obj/structure/disposaloutlet(src.loc) src.transfer_fingerprints_to(P) P.dir = dir - else if(ptype==8) // Disposal outlet + else if(ptype==PIPE_DISPOSALS_CHUTE) // Disposal outlet var/obj/machinery/disposal/deliveryChute/P = new /obj/machinery/disposal/deliveryChute(src.loc) src.transfer_fingerprints_to(P) @@ -265,3 +256,13 @@ else to_chat(user, "You need to attach it to the plating first!") return + +/obj/structure/disposalconstruct/rpd_act(mob/user, obj/item/rpd/our_rpd) + if(our_rpd.mode == RPD_ROTATE_MODE) + rotate() + else if(our_rpd.mode == RPD_FLIP_MODE) + flip() + else if(our_rpd.mode == RPD_DELETE_MODE) + our_rpd.delete_single_pipe(user, src) + else + ..() diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 00b3b06a3a5..476028b4532 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -97,7 +97,7 @@ to_chat(user, "You sliced the floorweld off the disposal unit.") var/obj/structure/disposalconstruct/C = new (src.loc) src.transfer_fingerprints_to(C) - C.ptype = 6 // 6 = disposal unit + C.ptype = PIPE_DISPOSALS_BIN C.anchored = 1 C.density = 1 C.update() @@ -889,21 +889,21 @@ var/obj/structure/disposalconstruct/C = new (src.loc) switch(base_icon_state) if("pipe-s") - C.ptype = 0 + C.ptype = PIPE_DISPOSALS_STRAIGHT if("pipe-c") - C.ptype = 1 + C.ptype = PIPE_DISPOSALS_BENT if("pipe-j1") - C.ptype = 2 + C.ptype = PIPE_DISPOSALS_JUNCTION_RIGHT if("pipe-j2") - C.ptype = 3 + C.ptype = PIPE_DISPOSALS_JUNCTION_LEFT if("pipe-y") - C.ptype = 4 + C.ptype = PIPE_DISPOSALS_Y_JUNCTION if("pipe-t") - C.ptype = 5 + C.ptype = PIPE_DISPOSALS_TRUNK if("pipe-j1s") - C.ptype = 9 + C.ptype = PIPE_DISPOSALS_SORT_RIGHT if("pipe-j2s") - C.ptype = 10 + C.ptype = PIPE_DISPOSALS_SORT_LEFT src.transfer_fingerprints_to(C) C.dir = dir C.density = 0 @@ -1339,7 +1339,7 @@ to_chat(user, "You sliced the floorweld off the disposal outlet.") var/obj/structure/disposalconstruct/C = new (src.loc) src.transfer_fingerprints_to(C) - C.ptype = 7 // 7 = outlet + C.ptype = PIPE_DISPOSALS_OUTLET C.update() C.anchored = 1 C.density = 1 diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index c40ed9fe73b..8b2f7c4197f 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -349,7 +349,7 @@ if(!src || !W.isOn()) return to_chat(user, "You sliced the floorweld off the delivery chute.") var/obj/structure/disposalconstruct/C = new (src.loc) - C.ptype = 8 // 8 = Delivery chute + C.ptype = PIPE_DISPOSALS_CHUTE C.update() C.anchored = 1 C.density = 1 diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index b7919662514..5cb51863851 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -800,6 +800,14 @@ build_path = /obj/item/conveyor_switch_construct category = list("initial", "Construction") +/datum/design/conveyor_belt_placer + name = "Conveyor Belt Placer" + id = "conveyor_belt_placer" + build_type = AUTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 1000) //This thing doesn't need to be very resource-intensive as the belts are already expensive + build_path = /obj/item/storage/conveyor + category = list("initial", "Construction") + /datum/design/laptop name = "Laptop Frame" id = "laptop" diff --git a/code/modules/research/designs/bluespace_designs.dm b/code/modules/research/designs/bluespace_designs.dm index 7f5377741e4..cf6e4b53882 100644 --- a/code/modules/research/designs/bluespace_designs.dm +++ b/code/modules/research/designs/bluespace_designs.dm @@ -51,6 +51,16 @@ build_path = /obj/item/storage/bag/ore/holding category = list("Bluespace") +/datum/design/bluespace_belt_holder + name = "Bluespace Conveyor Belt Placer" + desc = "This device facilitates the rapid deployment of conveyor belts. This one is powered by bluespace." + id = "bluespace_belt_holder" + req_tech = list("materials" = 1, "engineering" = 3, "bluespace" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_SILVER = 500) //Costs similar materials to the basic one, but this one needs silver + build_path = /obj/item/storage/conveyor/bluespace + category = list("Bluespace") + /datum/design/telepad_beacon name = "Telepad Beacon" desc = "Use to warp in a cargo telepad." diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 7fde20333c7..1589b78438b 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1120,6 +1120,15 @@ construction_time = 350 category = list("Misc") +/datum/design/integrated_robotic_chassis + name = "Integrated Robotic Chassis" + id = "integrated_robotic_chassis" + build_type = MECHFAB + build_path = /mob/living/carbon/human/machine/created + materials = list(MAT_METAL = 40000) + construction_time = 400 + category = list("Misc") + /datum/design/ipc_cell name = "IPC Microbattery" id = "ipc_cell" diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 49a1a7d0eba..a7fe42063ff 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -103,26 +103,26 @@ build_path = /obj/item/mass_spectrometer category = list("Medical") -/datum/design/posibrain - name = "Positronic Brain" - desc = "The latest in Artificial Intelligences." - id = "mmi_posi" +/datum/design/robotic_brain + name = "Robotic Brain" + desc = "The latest in non-sentient Artificial Intelligences." + id = "mmi_robotic" req_tech = list("programming" = 5, "biotech" = 4, "plasmatech" = 3) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 1700, MAT_GLASS = 1350, MAT_GOLD = 500) //Gold, because SWAG. construction_time = 75 - build_path = /obj/item/mmi/posibrain + build_path = /obj/item/mmi/robotic_brain category = list("Misc","Medical") -/datum/design/mmi_radio - name = "Radio-Enabled Man-Machine Interface" - desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio." - id = "mmi_radio" +/datum/design/mmi_radio_upgrade + name = "Man-Machine Interface Radio Upgrade" + desc = "Enables radio capability on MMIs when either installed directly on the MMI, or through a cyborg's chassis." + id = "mmi_radio_upgrade" req_tech = list("programming" = 3, "biotech" = 2, "engineering" = 2) build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 1200, MAT_GLASS = 500) - construction_time = 75 - build_path = /obj/item/mmi/radio_enabled + materials = list(MAT_METAL = 200) + construction_time = 50 + build_path = /obj/item/mmi_radio_upgrade category = list("Misc","Medical") /datum/design/nanopaste @@ -245,6 +245,36 @@ materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical") +/datum/design/alienbonegel + name = "Alien Bone Gel" + desc = "Advanced bone gel obtained through Abductor technology." + id = "alien_bonegel" + req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) + build_path = /obj/item/bonegel/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical") + +/datum/design/alienbonesetter + name = "Alien Bone Setter" + desc = "An advanced bone setter obtained through Abductor technology." + id = "alien_bonesetter" + req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) + build_path = /obj/item/bonesetter/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical") + +/datum/design/alienfixovein + name = "Alien FixOVein" + desc = "An advanced FixOVein obtained through Abductor technology." + id = "alien_fixovein" + req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) + build_path = /obj/item/FixOVein/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical") + ///////////////////////////////////////// //////////Cybernetic Implants//////////// ///////////////////////////////////////// @@ -446,3 +476,65 @@ materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/implantcase/track category = list("Medical") + +//Cybernetic organs + +/datum/design/cybernetic_eyes + name = "Cybernetic Eyes" + desc = "A cybernetic pair of eyes" + id = "cybernetic_eyes" + req_tech = list("biotech" = 4, "materials" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/organ/internal/eyes/cybernetic + category = list("Medical") + +/datum/design/cybernetic_liver + name = "Cybernetic Liver" + desc = "A cybernetic liver" + id = "cybernetic_liver" + req_tech = list("biotech" = 4, "materials" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/organ/internal/liver/cybernetic + category = list("Medical") + +/datum/design/cybernetic_kidneys + name = "Cybernetic Kidneys" + desc = "A cybernetic pair of kidneys" + id = "cybernetic_kidneys" + req_tech = list("biotech" = 4, "materials" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/organ/internal/kidneys/cybernetic + category = list("Medical") + +/datum/design/cybernetic_heart + name = "Cybernetic Heart" + desc = "A cybernetic heart" + id = "cybernetic_heart" + req_tech = list("biotech" = 4, "materials" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/organ/internal/heart/cybernetic + category = list("Medical") + +/datum/design/cybernetic_lungs + name = "Cybernetic Lungs" + desc = "A pair of cybernetic lungs." + id = "cybernetic_lungs" + req_tech = list("biotech" = 4, "materials" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/organ/internal/lungs/cybernetic + category = list("Medical") + +/datum/design/cybernetic_lungs_u + name = "Upgraded Cybernetic Lungs" + desc = "A pair of upgraded cybernetic lungs." + id = "cybernetic_lungs_u" + req_tech = list("biotech" = 5, "materials" = 5, "engineering" = 5) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500) + build_path = /obj/item/organ/internal/lungs/cybernetic/upgraded + category = list("Medical") \ No newline at end of file diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index a24a9522b38..0e9053bbb44 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -26,11 +26,11 @@ //temp /datum/TCS_Compiler - var/datum/n_scriptOptions/nS_Options/options - var/datum/n_Scanner/nS_Scanner/scanner - var/list/tokens - var/datum/n_Parser/nS_Parser/parser - var/datum/node/BlockDefinition/GlobalBlock/program + var/datum/n_scriptOptions/nS_Options/options + var/datum/n_Scanner/nS_Scanner/scanner + var/list/tokens + var/datum/n_Parser/nS_Parser/parser + var/datum/node/BlockDefinition/GlobalBlock/program /* -- Compile a raw block of text -- */ @@ -248,7 +248,7 @@ But I like HTML, so back to no sanitizing.*/ var/message = interpreter.GetVar("$content") - var/regex/bannedTags = new ("( 0) throw EXCEPTION("Init told to resume when z-level still dirty. Z level: '[zpos]'") @@ -140,23 +144,15 @@ log_debug("Beginning initialization!") var/list/our_atoms = init_list // OURS NOW!!! (Keeping this list to ourselves will prevent hijack) init_list = list() - var/list/late_maps = list() - var/list/pipes = list() - var/list/cables = list() var/watch = start_watch() - for(var/schmoo in our_atoms) - var/atom/movable/AM = schmoo - if(AM) // to catch stuff like the nuke disk that no longer exists - - // This can mess with our state - we leave these for last - if(istype(AM, /obj/effect/landmark/map_loader)) - late_maps.Add(AM) - continue - AM.Initialize(TRUE) - if(istype(AM, /obj/machinery/atmospherics)) - pipes.Add(AM) - else if(istype(AM, /obj/structure/cable)) - cables.Add(AM) + listclearnulls(our_atoms) + var/list/late_maps = typecache_filter_list(our_atoms, maploader_typecache) + var/list/pipes = typecache_filter_list(our_atoms, atmos_machine_typecache) + var/list/cables = typecache_filter_list(our_atoms, cable_typecache) + // If we don't carefully add dirt around the map templates, bad stuff happens + // so we separate them out here + our_atoms -= late_maps + SSatoms.InitializeAtoms(our_atoms, FALSE) log_debug("Primary initialization finished in [stop_watch(watch)]s.") our_atoms.Cut() if(pipes.len) @@ -168,13 +164,14 @@ /datum/space_level/proc/do_pipes(list/pipes) var/watch = start_watch() - log_debug("Building pipenets on z-level '[zpos]'!") - for(var/schmoo in pipes) - var/obj/machinery/atmospherics/machine = schmoo - if(machine) - machine.build_network() + log_debug("Initializing atmos machines on z-level '[zpos]'!") + var/init_count = SSair._setup_atmos_machinery(pipes) + log_debug("Initialized [init_count] machines, took [stop_watch(watch)]s") + watch = start_watch() + log_debug("Initializing pipe networks on z-level '[zpos]'!") + init_count = SSair._setup_pipenets(pipes) + log_debug("Initialized pipenets for [init_count] machines, took [stop_watch(watch)]s") pipes.Cut() - log_debug("Took [stop_watch(watch)]s") /datum/space_level/proc/do_cables(list/cables) var/watch = start_watch() @@ -187,10 +184,8 @@ var/watch = start_watch() log_debug("Loading map templates on z-level '[zpos]'!") space_manager.add_dirt(zpos) // Let's not repeatedly resume init for each template - for(var/schmoo in late_maps) - var/obj/effect/landmark/map_loader/ML = schmoo - if(ML) - ML.Initialize() + for(var/atom/movable/AM in late_maps) + AM.Initialize() late_maps.Cut() space_manager.remove_dirt(zpos) log_debug("Took [stop_watch(watch)]s") diff --git a/code/modules/spacepods/equipment.dm b/code/modules/spacepods/equipment.dm index b845404fa35..52273af71fe 100644 --- a/code/modules/spacepods/equipment.dm +++ b/code/modules/spacepods/equipment.dm @@ -2,6 +2,7 @@ if(my_atom.next_firetime > world.time) to_chat(usr, "Your weapons are recharging.") return + my_atom.next_firetime = world.time + fire_delay var/turf/firstloc var/turf/secondloc if(!my_atom.equipment_system || !my_atom.equipment_system.weapon_system) @@ -41,7 +42,6 @@ projone.dumbfire(my_atom.dir) projtwo.dumbfire(my_atom.dir) sleep(2) - my_atom.next_firetime = world.time + fire_delay /datum/spacepod/equipment var/obj/spacepod/my_atom diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index 97e34eee154..24123d52fc0 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -812,11 +812,18 @@ obj/spacepod/proc/add_equipment(mob/user, var/obj/item/spacepod_equipment/SPE, v if(!istype(user)) return - if(usr.incapacitated()) // unconscious and restrained people can't let themselves out + if(usr.stat != CONSCIOUS) // unconscious people can't let themselves out return occupant_sanity_check() + if(usr.restrained()) + to_chat(usr, "You attempt to stumble out of the [src]. This will take two minutes.") + if(pilot) + to_chat(pilot, "[usr] is trying to escape the [src].") + if(!do_after(usr, 1200, target = src)) + return + if(user == pilot) user.forceMove(get_turf(src)) pilot = null diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index a053b568dc7..fb45bddb9ba 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -19,7 +19,7 @@ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 if(affected.cannot_break) return 0 @@ -43,7 +43,7 @@ /datum/surgery_step/glue_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && !(affected.cannot_break) + return affected && !affected.is_robotic() && !(affected.cannot_break) /datum/surgery_step/glue_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -77,7 +77,7 @@ /datum/surgery_step/set_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) + return affected && !affected.is_robotic() /datum/surgery_step/set_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -116,7 +116,7 @@ /datum/surgery_step/mend_skull/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) && affected.limb_name == "head" + return affected && !affected.is_robotic() && affected.limb_name == "head" /datum/surgery_step/mend_skull/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) user.visible_message("[user] is beginning piece together [target]'s skull with \the [tool]." , \ @@ -153,7 +153,7 @@ /datum/surgery_step/finish_bone/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) - return affected && !(affected.status & ORGAN_ROBOT) + return affected && !affected.is_robotic() /datum/surgery_step/finish_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(target_zone) diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index 2ab2aca37c7..16d1b18dc1b 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -23,7 +23,7 @@ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 return 1 @@ -33,7 +33,7 @@ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) if(!affected) return 0 - return (affected.status & ORGAN_ROBOT) + return affected.is_robotic() /datum/surgery_step/cavity priority = 1 @@ -187,7 +187,7 @@ else user.visible_message(" [user] puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \ " You put \the [tool] inside [target]'s [get_cavity(affected)] cavity." ) - if((tool.w_class > get_max_wclass(affected)/2 && prob(50) && !(affected.status & ORGAN_ROBOT))) + if((tool.w_class > get_max_wclass(affected) / 2 && prob(50) && !affected.is_robotic())) to_chat(user, " You tear some vessels trying to fit the object in the cavity.") affected.internal_bleeding = TRUE affected.owner.custom_pain("You feel something rip in your [affected.name]!") diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm index b9a33fcecab..e1402083dbd 100644 --- a/code/modules/surgery/encased.dm +++ b/code/modules/surgery/encased.dm @@ -15,7 +15,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) if(!affected) return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 return 1 diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 1e1b3a10365..c66d95df899 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -12,7 +12,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) if(affected == null) return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 return 1 diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 986ce671860..1ae29143496 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -21,7 +21,7 @@ for(var/datum/surgery/S in all_surgeries) if(!S.possible_locs.Find(selected_zone)) continue - if(affecting && S.requires_organic_bodypart && affecting.status == ORGAN_ROBOT) + if(affecting && S.requires_organic_bodypart && affecting.is_robotic()) continue if(!S.can_start(user, M)) continue @@ -39,7 +39,7 @@ S = available_surgeries["Apply Robotic Prosthetic"] if(istype(I,/obj/item/organ/external)) var/obj/item/organ/external/E = I - if(E.robotic == 2) + if(E.is_robotic()) S = available_surgeries["Synthetic Limb Reattachment"] if(S) var/datum/surgery/procedure = new S.type @@ -84,7 +84,7 @@ /proc/get_pain_modifier(mob/living/carbon/human/M) //returns modfier to make surgery harder if patient is conscious and feels pain if(M.stat) //stat=0 if CONSCIOUS, 1=UNCONSCIOUS and 2=DEAD. Operating on dead people is easy, too. Just sleeping won't work, though. return 1 - if(NO_PAIN in M.species.species_traits)//if you don't feel pain, you can hold still + if(NO_PAIN in M.dna.species.species_traits)//if you don't feel pain, you can hold still return 1 if(M.reagents.has_reagent("hydrocodone"))//really good pain killer return 0.99 diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index c36df974ea3..435ce92b94e 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -19,7 +19,7 @@ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 return 1 @@ -29,7 +29,7 @@ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(!(affected.status & ORGAN_ROBOT)) + if(!affected.is_robotic()) return 0 return 1 diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 9674f4aec49..d2f11364cfe 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -1,7 +1,7 @@ /datum/surgery/limb_augmentation name = "Augment Limb" steps = list(/datum/surgery_step/generic/cut_open, /datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/augment) - possible_locs = list("chest","l_arm","r_arm","r_leg","l_leg") + possible_locs = list("head", "chest","l_arm","r_arm","r_leg","l_leg") /datum/surgery/limb_augmentation/can_start(mob/user, mob/living/carbon/target) if(ishuman(target)) @@ -11,7 +11,7 @@ return 0 if(affected.status & ORGAN_BROKEN) //The arm has to be in prime condition to augment it. return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 return 1 diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index d64d00c34bb..42db2e97da1 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -15,7 +15,7 @@ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 if(affected.cannot_amputate) return 0 @@ -32,7 +32,7 @@ if(ishuman(target)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if(target.get_species() == "Machine") + if(ismachine(target)) // RIP bi-centennial man return 0 if(!affected) @@ -76,7 +76,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) if(affected) return 0 - var/list/organ_data = target.species.has_limbs["[target_zone]"] + var/list/organ_data = target.dna.species.has_limbs["[target_zone]"] return !isnull(organ_data) /datum/surgery_step/limb/attach @@ -131,7 +131,7 @@ /datum/surgery_step/limb/attach/proc/is_correct_limb(obj/item/organ/external/E) - if(E.status & ORGAN_ROBOT) + if(E.is_robotic()) return 0 return 1 @@ -149,13 +149,13 @@ name = "attach robotic limb" /datum/surgery_step/limb/attach/robo/is_correct_limb(obj/item/organ/external/E) - if(!(E.status & ORGAN_ROBOT)) + if(!E.is_robotic()) return 0 return 1 /datum/surgery_step/limb/attach/robo/attach_limb(mob/living/user, mob/living/carbon/human/target, obj/item/organ/external/E) // Fixes fabricator IPC heads - if(!(E.dna) && E.robotic == 2 && target.dna) + if(!(E.dna) && E.is_robotic() && target.dna) E.set_dna(target.dna) ..() if(E.limb_name == "head") @@ -233,7 +233,7 @@ for(var/part_name in L.part) if(!isnull(target.get_organ(part_name))) continue - var/list/organ_data = target.species.has_limbs["[part_name]"] + var/list/organ_data = target.dna.species.has_limbs["[part_name]"] if(!organ_data) continue // This will break if there's more than one stump ever diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index 305bbb2c603..fe1adce42fb 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -33,7 +33,7 @@ var/mob/living/carbon/human/H = HA if(!istype(H)) H = owner - var/icon/cybereyes_icon = new /icon('icons/mob/human_face.dmi', H.species.eyes) + var/icon/cybereyes_icon = new /icon('icons/mob/human_face.dmi', H.dna.species.eyes) cybereyes_icon.Blend(eye_colour, ICON_ADD) // Eye implants override native DNA eye color return cybereyes_icon diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 64d62d3f6b4..f0b05ad0659 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -7,8 +7,6 @@ var/implant_color = "#FFFFFF" var/implant_overlay tough = TRUE // Immune to damage - sterile = TRUE // Doesn't accumulate germs - robotic = 2 // these are cybernetic after all /obj/item/organ/internal/cyberimp/New(var/mob/M = null) . = ..() diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index 9f732fdef4d..2a7057516f9 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -18,7 +18,7 @@ /mob/living/carbon/human/handle_blood() var/list/blood_data = get_blood_data(get_blood_id())//PROCCEPTION - if(NO_BLOOD in species.species_traits) + if(NO_BLOOD in dna.species.species_traits) bleed_rate = 0 return @@ -43,14 +43,14 @@ if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) if(prob(5)) to_chat(src, "You feel [word].") - apply_damage_type(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1), species.blood_damage_type) + apply_damage_type(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1), dna.species.blood_damage_type) if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - apply_damage_type(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1), species.blood_damage_type) + apply_damage_type(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1), dna.species.blood_damage_type) if(prob(5)) EyeBlurry(6) to_chat(src, "You feel very [word].") if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) - apply_damage_type(5, species.blood_damage_type) + apply_damage_type(5, dna.species.blood_damage_type) if(prob(15)) Paralyse(rand(1,3)) to_chat(src, "You feel extremely [word].") @@ -64,7 +64,7 @@ var/obj/item/organ/external/BP = X var/brutedamage = BP.brute_dam - if(BP.status & ORGAN_ROBOT) + if(BP.is_robotic()) continue //We want an accurate reading of .len @@ -99,9 +99,9 @@ add_splatter_floor(loc, 1) /mob/living/carbon/human/bleed(amt) - if(!(NO_BLOOD in species.species_traits)) + if(!(NO_BLOOD in dna.species.species_traits)) ..() - if(species.exotic_blood) + if(dna.species.exotic_blood) var/datum/reagent/R = chemical_reagents_list[get_blood_id()] if(istype(R) && isturf(loc)) R.reaction_turf(get_turf(src), amt) @@ -186,7 +186,7 @@ blood_data["blood_type"] = copytext(src.dna.b_type,1,0) blood_data["gender"] = gender blood_data["real_name"] = real_name - blood_data["blood_color"] = species.blood_color + blood_data["blood_color"] = dna.species.blood_color blood_data["factions"] = faction return blood_data @@ -199,9 +199,9 @@ return "blood" /mob/living/carbon/human/get_blood_id() - if(species.exotic_blood)//some races may bleed water..or kethcup.. - return species.exotic_blood - else if((NO_BLOOD in species.species_traits) || (NOCLONE in mutations)) + if(dna.species.exotic_blood)//some races may bleed water..or kethcup.. + return dna.species.exotic_blood + else if((NO_BLOOD in dna.species.species_traits) || (NOCLONE in mutations)) return return "blood" @@ -279,7 +279,7 @@ B.layer = BELOW_MOB_LAYER //So the blood lands ontop of things like posters, windows, etc. /mob/living/carbon/human/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) - if(!(NO_BLOOD in species.species_traits)) + if(!(NO_BLOOD in dna.species.species_traits)) ..() /mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm new file mode 100644 index 00000000000..51d73fc9873 --- /dev/null +++ b/code/modules/surgery/organs/eyes.dm @@ -0,0 +1,80 @@ +/obj/item/organ/internal/eyes + name = "eyeballs" + icon_state = "eyes" + gender = PLURAL + organ_tag = "eyes" + parent_organ = "head" + slot = "eyes" + var/eye_colour = "#000000" + var/list/colourmatrix = null + var/list/colourblind_matrix = MATRIX_GREYSCALE //Special colourblindness parameters. By default, it's black-and-white. + var/list/replace_colours = LIST_GREYSCALE_REPLACE + var/dependent_disabilities = null //Gets set by eye-dependent disabilities such as colourblindness so the eyes can transfer the disability during transplantation. + var/dark_view = 2 //Default dark_view for Humans. + var/weld_proof = null //If set, the eyes will not take damage during welding. eg. IPC optical sensors do not take damage when they weld things while all other eyes will. + +/obj/item/organ/internal/eyes/proc/update_colour() + dna.write_eyes_attributes(src) + +/obj/item/organ/internal/eyes/proc/generate_icon(var/mob/living/carbon/human/HA) + var/mob/living/carbon/human/H = HA + if(!istype(H)) + H = owner + var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', H.dna.species.eyes) + eyes_icon.Blend(eye_colour, ICON_ADD) + + return eyes_icon + +/obj/item/organ/internal/eyes/proc/get_colourmatrix() //Returns a special colour matrix if the eyes are organic and the mob is colourblind, otherwise it uses the current one. + if(!is_robotic() && owner.disabilities & COLOURBLIND) + return colourblind_matrix + else + return colourmatrix + +/obj/item/organ/internal/eyes/proc/get_dark_view() //Returns dark_view (if the eyes are organic) for see_invisible handling in species.dm to be autoprocessed by life(). + return dark_view + +/obj/item/organ/internal/eyes/proc/shine() + if(is_robotic() || (dark_view > EYE_SHINE_THRESHOLD)) + return TRUE + +/obj/item/organ/internal/eyes/insert(mob/living/carbon/human/M, special = 0) + ..() + if(istype(M) && eye_colour) + M.update_body() //Apply our eye colour to the target. + + if(!(M.disabilities & COLOURBLIND) && (dependent_disabilities & COLOURBLIND)) //If the eyes are colourblind and we're not, carry over the gene. + dependent_disabilities &= ~COLOURBLIND + M.dna.SetSEState(COLOURBLINDBLOCK,1) + genemutcheck(M,COLOURBLINDBLOCK,null,MUTCHK_FORCED) + else + M.update_client_colour() //If we're here, that means the mob acquired the colourblindness gene while they didn't have eyes. Better handle it. + +/obj/item/organ/internal/eyes/remove(mob/living/carbon/human/M, special = 0) + if(!special && (M.disabilities & COLOURBLIND)) //If special is set, that means these eyes are getting deleted (i.e. during set_species()) + if(!(dependent_disabilities & COLOURBLIND)) //We only want to change COLOURBLINDBLOCK and such it the eyes are being surgically removed. + dependent_disabilities |= COLOURBLIND + M.dna.SetSEState(COLOURBLINDBLOCK,0) + genemutcheck(M,COLOURBLINDBLOCK,null,MUTCHK_FORCED) + . = ..() + +/obj/item/organ/internal/eyes/surgeryize() + if(!owner) + return + owner.CureNearsighted() + owner.CureBlind() + owner.SetEyeBlurry(0) + owner.SetEyeBlind(0) + +/obj/item/organ/internal/eyes/robotize() + colourmatrix = null + ..() //Make sure the organ's got the robotic status indicators before updating the client colour. + if(owner) + owner.update_client_colour(0) //Since mechanical eyes give dark_view of 2 and full colour vision atm, just having this here is fine. + +/obj/item/organ/internal/eyes/cybernetic + name = "cybernetic eyes" + icon_state = "eyes-prosthetic" + desc = "An electronic device designed to mimic the functions of a pair of human eyes. It has no benefits over organic eyes, but is easy to produce." + origin_tech = "biotech=4" + status = ORGAN_ROBOT \ No newline at end of file diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm new file mode 100644 index 00000000000..bd7cca63779 --- /dev/null +++ b/code/modules/surgery/organs/heart.dm @@ -0,0 +1,150 @@ +/obj/item/organ/internal/heart + name = "heart" + icon_state = "heart-on" + organ_tag = "heart" + parent_organ = "chest" + slot = "heart" + origin_tech = "biotech=5" + var/beating = TRUE + dead_icon = "heart-off" + var/icon_base = "heart" + +/obj/item/organ/internal/heart/update_icon() + if(beating) + icon_state = "[icon_base]-on" + else + icon_state = "[icon_base]-off" + +/obj/item/organ/internal/heart/remove(mob/living/carbon/M, special = 0) + . = ..() + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.stat == DEAD) + Stop() + return + + spawn(120) + if(!owner) + Stop() + +/obj/item/organ/internal/heart/emp_act(intensity) + if(!is_robotic() || emp_proof) + return + Stop() + +/obj/item/organ/internal/heart/necrotize() + ..() + Stop() + +/obj/item/organ/internal/heart/attack_self(mob/user) + ..() + if(status & ORGAN_DEAD) + to_chat(user, "You can't restart a dead heart.") + return + if(!beating) + Restart() + spawn(80) + if(!owner) + Stop() + +/obj/item/organ/internal/heart/safe_replace(mob/living/carbon/human/target) + Restart() + ..() + +/obj/item/organ/internal/heart/proc/Stop() + beating = FALSE + update_icon() + return TRUE + +/obj/item/organ/internal/heart/proc/Restart() + beating = TRUE + update_icon() + return TRUE + +/obj/item/organ/internal/heart/prepare_eat() + var/obj/S = ..() + S.icon_state = dead_icon + return S + +/obj/item/organ/internal/heart/cursed + name = "cursed heart" + desc = "it needs to be pumped..." + icon_state = "cursedheart-off" + icon_base = "cursedheart" + origin_tech = "biotech=6" + actions_types = list(/datum/action/item_action/organ_action/cursed_heart) + var/last_pump = 0 + var/pump_delay = 30 //you can pump 1 second early, for lag, but no more (otherwise you could spam heal) + var/blood_loss = 100 //600 blood is human default, so 5 failures (below 122 blood is where humans die because reasons?) + + //How much to heal per pump, negative numbers would HURT the player + var/heal_brute = 0 + var/heal_burn = 0 + var/heal_oxy = 0 + + +/obj/item/organ/internal/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target) + if(H == user && istype(H)) + if(NO_BLOOD in H.dna.species.species_traits) + to_chat(H, "\The [src] is not compatible with your form!") + return + playsound(user,'sound/effects/singlebeat.ogg', 40, 1) + user.drop_item() + insert(user) + else + return ..() + +/obj/item/organ/internal/heart/cursed/on_life() + if(world.time > (last_pump + pump_delay)) + if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects. + var/mob/living/carbon/human/H = owner + if(!(NO_BLOOD in H.dna.species.species_traits)) + H.blood_volume = max(H.blood_volume - blood_loss, 0) + to_chat(H, "You have to keep pumping your blood!") + if(H.client) + H.client.color = "red" //bloody screen so real + else + last_pump = world.time //lets be extra fair *sigh* + +/obj/item/organ/internal/heart/cursed/insert(mob/living/carbon/M, special = 0) + ..() + if(owner) + to_chat(owner, "Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!") + + +/datum/action/item_action/organ_action/cursed_heart + name = "pump your blood" + +//You are now brea- pumping blood manually +/datum/action/item_action/organ_action/cursed_heart/Trigger() + . = ..() + if(. && istype(target,/obj/item/organ/internal/heart/cursed)) + var/obj/item/organ/internal/heart/cursed/cursed_heart = target + + if(world.time < (cursed_heart.last_pump + (cursed_heart.pump_delay-10))) //no spam + to_chat(owner, "Too soon!") + return + + cursed_heart.last_pump = world.time + playsound(owner,'sound/effects/singlebeat.ogg',40,1) + to_chat(owner, "Your heart beats.") + + var/mob/living/carbon/human/H = owner + if(istype(H)) + if(!(NO_BLOOD in H.dna.species.species_traits)) + H.blood_volume = min(H.blood_volume + cursed_heart.blood_loss*0.5, BLOOD_VOLUME_NORMAL) + if(owner.client) + owner.client.color = "" + + H.adjustBruteLoss(-cursed_heart.heal_brute) + H.adjustFireLoss(-cursed_heart.heal_burn) + H.adjustOxyLoss(-cursed_heart.heal_oxy) + +/obj/item/organ/internal/heart/cybernetic + name = "cybernetic heart" + desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make." + icon_state = "heart-c-on" + icon_base = "heart-c" + dead_icon = "heart-c-off" + origin_tech = "biotech=5" + status = ORGAN_ROBOT \ No newline at end of file diff --git a/code/modules/surgery/organs/kidneys.dm b/code/modules/surgery/organs/kidneys.dm new file mode 100644 index 00000000000..26b59191a7c --- /dev/null +++ b/code/modules/surgery/organs/kidneys.dm @@ -0,0 +1,25 @@ +/obj/item/organ/internal/kidneys + name = "kidneys" + icon_state = "kidneys" + gender = PLURAL + organ_tag = "kidneys" + parent_organ = "groin" + slot = "kidneys" + +/obj/item/organ/internal/kidneys/on_life() + // Coffee is really bad for you with busted kidneys. + // This should probably be expanded in some way, but fucked if I know + // what else kidneys can process in our reagent list. + var/datum/reagent/coffee = locate(/datum/reagent/consumable/drink/coffee) in owner.reagents.reagent_list + if(coffee) + if(is_bruised()) + owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) + else if(is_broken()) + owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + +/obj/item/organ/internal/kidneys/cybernetic + name = "cybernetic kidneys" + icon_state = "kidneys-c" + desc = "An electronic device designed to mimic the functions of human kidneys. It has no benefits over a pair of organic kidneys, but is easy to produce." + origin_tech = "biotech=4" + status = ORGAN_ROBOT \ No newline at end of file diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm new file mode 100644 index 00000000000..bf6f085275b --- /dev/null +++ b/code/modules/surgery/organs/liver.dm @@ -0,0 +1,58 @@ +/obj/item/organ/internal/liver + name = "liver" + icon_state = "liver" + organ_tag = "liver" + parent_organ = "groin" + slot = "liver" + var/alcohol_intensity = 1 + +/obj/item/organ/internal/liver/on_life() + if(germ_level > INFECTION_LEVEL_ONE) + if(prob(1)) + to_chat(owner, " Your skin itches.") + if(germ_level > INFECTION_LEVEL_TWO) + if(prob(1)) + owner.vomit() + + if(owner.life_tick % PROCESS_ACCURACY == 0) + + //High toxins levels are dangerous + if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("charcoal")) + //Healthy liver suffers on its own + if(damage < min_broken_damage) + receive_damage(0.2 * PROCESS_ACCURACY) + //Damaged one shares the fun + else + var/obj/item/organ/internal/O = pick(owner.internal_organs) + if(O) + O.receive_damage(0.2 * PROCESS_ACCURACY) + + //Detox can heal small amounts of damage + if(damage && damage < min_bruised_damage && owner.reagents.has_reagent("charcoal")) + receive_damage(-0.2 * PROCESS_ACCURACY) + + // Get the effectiveness of the liver. + var/filter_effect = 3 + if(is_bruised()) + filter_effect -= 1 + if(is_broken()) + filter_effect -= 2 + + // Damaged liver means some chemicals are very dangerous + if(damage >= min_bruised_damage) + for(var/datum/reagent/R in owner.reagents.reagent_list) + // Ethanol and all drinks are bad + if(istype(R, /datum/reagent/consumable/ethanol)) + owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) + + // Can't cope with toxins at all + for(var/toxin in list("toxin", "plasma", "sacid", "facid", "cyanide", "amanitin", "carpotoxin")) + if(owner.reagents.has_reagent(toxin)) + owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) + +/obj/item/organ/internal/liver/cybernetic + name = "cybernetic liver" + icon_state = "liver-c" + desc = "An electronic device designed to mimic the functions of a human liver. It has no benefits over an organic liver, but is easy to produce." + origin_tech = "biotech=4" + status = ORGAN_ROBOT \ No newline at end of file diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 39c79865b62..3c2b7e1cbd1 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -51,6 +51,12 @@ var/heat_level_3_damage = HEAT_GAS_DAMAGE_LEVEL_3 var/heat_damage_types = list(BURN = 1) +/obj/item/organ/internal/lungs/emp_act() + if(!is_robotic() || emp_proof) + return + if(owner) + owner.LoseBreath(20) + /obj/item/organ/internal/lungs/insert(mob/living/carbon/M, special = 0, dont_remove_slot = 0) ..() for(var/thing in list("oxy", "tox", "co2", "nitro")) @@ -148,12 +154,12 @@ if(safe_nitro_min) if(N2_pp < safe_nitro_min) gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.nitrogen) - H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro) + H.throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro) else H.failed_last_breath = FALSE H.adjustOxyLoss(-5) gas_breathed = breath.nitrogen - H.clear_alert("nitro") + H.clear_alert("not_enough_nitro") //Exhale breath.nitrogen -= gas_breathed @@ -265,11 +271,11 @@ var/breath_temperature = breath.temperature var/species_traits = list() - if(H && H.species && H.species.species_traits) - species_traits = H.species.species_traits + if(H && H.dna.species && H.dna.species.species_traits) + species_traits = H.dna.species.species_traits if(!(COLDRES in H.mutations) && !(RESISTCOLD in species_traits)) // COLD DAMAGE - var/CM = abs(H.species.coldmod) + var/CM = abs(H.dna.species.coldmod) var/TC = 0 if(breath_temperature < cold_level_3_threshold) TC = cold_level_3_damage @@ -285,7 +291,7 @@ to_chat(H, "You feel [cold_message] in your [name]!") if(!(HEATRES in H.mutations) && !(RESISTHOT in species_traits)) // HEAT DAMAGE - var/HM = abs(H.species.heatmod) + var/HM = abs(H.dna.species.heatmod) var/TH = 0 if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold) TH = heat_level_1_damage @@ -309,7 +315,6 @@ name = "plasma filter" desc = "A spongy rib-shaped mass for filtering plasma from the air." icon_state = "lungs-plasma" - species = "Plasmaman" safe_oxygen_min = 0 //We don't breath this safe_toxins_min = 16 //We breathe THIS! @@ -318,7 +323,6 @@ /obj/item/organ/internal/lungs/vox name = "Vox lungs" desc = "They're filled with dust....wow." - species = "Vox" safe_oxygen_min = 0 //We don't breathe this safe_oxygen_max = 1 //This is toxic to us @@ -327,11 +331,30 @@ /obj/item/organ/internal/lungs/drask icon = 'icons/obj/surgery_drask.dmi' - species = "Drask" cold_message = "an invigorating coldness" cold_level_3_threshold = 60 cold_level_1_damage = -COLD_GAS_DAMAGE_LEVEL_1 //They heal when the air is cold cold_level_2_damage = -COLD_GAS_DAMAGE_LEVEL_2 cold_level_3_damage = -COLD_GAS_DAMAGE_LEVEL_3 - cold_damage_types = list(BRUTE = 1, BURN = 0.5) \ No newline at end of file + cold_damage_types = list(BRUTE = 1, BURN = 0.5) + +/obj/item/organ/internal/lungs/cybernetic + name = "cybernetic lungs" + desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement." + icon_state = "lungs-c" + origin_tech = "biotech=4" + status = ORGAN_ROBOT + +/obj/item/organ/internal/lungs/cybernetic/upgraded + name = "upgraded cybernetic lungs" + desc = "A more advanced version of the stock cybernetic lungs. They are capable of filtering out lower levels of toxins and carbon dioxide." + icon_state = "lungs-c-u" + origin_tech = "biotech=5" + + safe_toxins_max = 20 + safe_co2_max = 20 + + cold_level_1_threshold = 200 + cold_level_2_threshold = 140 + cold_level_3_threshold = 100 \ No newline at end of file diff --git a/code/modules/surgery/organs/mmi_holder.dm b/code/modules/surgery/organs/mmi_holder.dm new file mode 100644 index 00000000000..d4228fb9625 --- /dev/null +++ b/code/modules/surgery/organs/mmi_holder.dm @@ -0,0 +1,36 @@ +// Used for an MMI or robotic brain being installed into a human. +/obj/item/organ/internal/brain/mmi_holder + name = "Man-Machine Interface" + parent_organ = "chest" + status = ORGAN_ROBOT + var/obj/item/mmi/stored_mmi + +/obj/item/organ/internal/brain/mmi_holder/Destroy() + QDEL_NULL(stored_mmi) + return ..() + +/obj/item/organ/internal/brain/mmi_holder/insert(mob/living/target, special = 0) + ..() + // To supersede the over-writing of the MMI's name from `insert` + update_from_mmi() + +/obj/item/organ/internal/brain/mmi_holder/remove(mob/living/user, special = 0) + if(!special) + if(stored_mmi) + . = stored_mmi + if(owner.mind) + owner.mind.transfer_to(stored_mmi.brainmob) + stored_mmi.forceMove(get_turf(owner)) + stored_mmi = null + ..() + if(!QDELETED(src)) + qdel(src) + +/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi() + if(!stored_mmi) + return + name = initial(stored_mmi.name) + desc = stored_mmi.desc + icon = stored_mmi.icon + icon_state = stored_mmi.icon_state + set_dna(stored_mmi.brainmob.dna) \ No newline at end of file diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index 5837fab5925..991a5d252ce 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -4,7 +4,7 @@ var/dead_icon var/mob/living/carbon/human/owner = null var/status = 0 - var/vital //Lose a vital limb, die immediately. + var/vital = FALSE //Lose a vital limb, die immediately. var/damage = 0 // amount of damage to the organ var/min_bruised_damage = 10 @@ -13,14 +13,12 @@ var/organ_tag = "organ" var/parent_organ = "chest" - var/robotic = 0 //For being a robot var/list/datum/autopsy_data/autopsy_data = list() var/list/trace_chemicals = list() // traces of chemicals in the organ, // links chemical IDs to number of ticks for which they'll stay in the blood germ_level = 0 var/datum/dna/dna - var/datum/species/species = "Human" // Stuff for tracking if this is on a tile with an open freezer or not var/last_freezer_update_time = 0 @@ -31,6 +29,7 @@ var/tough = FALSE //can organ be easily damaged? var/emp_proof = FALSE //is the organ immune to EMPs? var/hidden_pain = FALSE //will it skip pain messages? + var/requires_robotic_bodypart = FALSE /obj/item/organ/Destroy() @@ -44,15 +43,13 @@ /obj/item/organ/proc/update_health() return -/obj/item/organ/New(var/mob/living/carbon/holder) +/obj/item/organ/New(mob/living/carbon/holder, datum/species/species_override = null) ..(holder) if(!max_damage) max_damage = min_broken_damage * 2 if(istype(holder)) - species = all_species["Human"] if(holder.dna) dna = holder.dna.Clone() - species = all_species[dna.species] else log_runtime(EXCEPTION("[holder] spawned without a proper DNA."), holder) var/mob/living/carbon/human/H = holder @@ -62,8 +59,9 @@ blood_DNA = list() blood_DNA[dna.unique_enzymes] = dna.b_type else - if(istext(species)) - species = all_species[species] + dna = new /datum/dna(null) + if(species_override) + dna.species = new species_override /obj/item/organ/proc/set_dna(var/datum/dna/new_dna) if(new_dna) @@ -74,13 +72,11 @@ blood_DNA = list() blood_DNA[dna.unique_enzymes] = dna.b_type -/obj/item/organ/proc/necrotize(update_sprite=TRUE) - if(status & ORGAN_ROBOT) - return +/obj/item/organ/proc/necrotize(update_sprite = TRUE) damage = max_damage status |= ORGAN_DEAD processing_objects -= src - if(dead_icon) + if(dead_icon && !is_robotic()) icon_state = dead_icon if(owner && vital) owner.death() @@ -95,7 +91,7 @@ return //Process infections - if((status & ORGAN_ROBOT) || sterile || (owner && (IS_PLANT in owner.species.species_traits))) + if(is_robotic() || sterile || (owner && (IS_PLANT in owner.dna.species.species_traits))) germ_level = 0 return @@ -157,7 +153,7 @@ germ_level++ if(germ_level >= INFECTION_LEVEL_ONE) - var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature + var/fever_temperature = (owner.dna.species.heat_level_1 - owner.dna.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.dna.species.body_temperature owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature) if(germ_level >= INFECTION_LEVEL_TWO) @@ -175,10 +171,8 @@ /obj/item/organ/proc/rejuvenate() damage = 0 germ_level = 0 - if(status & ORGAN_ROBOT) //Robotic organs stay robotic. + if(is_robotic()) //Robotic organs stay robotic. status = ORGAN_ROBOT - else if(status & ORGAN_ASSISTED) //Assisted organs stay assisted. - status = ORGAN_ASSISTED else status = 0 if(!owner) @@ -224,37 +218,30 @@ /obj/item/organ/proc/receive_damage(amount, silent = 0) if(tough) return - if(status & ORGAN_ROBOT) - damage = between(0, damage + (amount * 0.8), max_damage) - else - damage = between(0, damage + amount, max_damage) + damage = between(0, damage + amount, max_damage) - //only show this if the organ is not robotic - if(owner && parent_organ && amount > 0) - var/obj/item/organ/external/parent = owner.get_organ(parent_organ) - if(parent && !silent) - owner.custom_pain("Something inside your [parent.name] hurts a lot.") + //only show this if the organ is not robotic + if(owner && parent_organ && amount > 0) + var/obj/item/organ/external/parent = owner.get_organ(parent_organ) + if(parent && !silent) + owner.custom_pain("Something inside your [parent.name] hurts a lot.") //check if we've hit max_damage if(damage >= max_damage) necrotize() +/obj/item/organ/proc/heal_internal_damage(amount, robo_repair = FALSE) + if(is_robotic() && !robo_repair) + return + damage = max(damage - amount, 0) + /obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc - robotic = 2 status &= ~ORGAN_BROKEN status &= ~ORGAN_SPLINTED status |= ORGAN_ROBOT -/obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc - robotize(1) //Skip the icon/name setting that occurs in robotize to avoid having to reset the icon file. - status &= ~ORGAN_ROBOT - status |= ORGAN_ASSISTED - robotic = 1 - min_bruised_damage = 15 - min_broken_damage = 35 - /obj/item/organ/external/emp_act(severity) - if(!(status & ORGAN_ROBOT) || emp_proof) + if(!is_robotic() || emp_proof) return if(tough) switch(severity) @@ -274,25 +261,13 @@ receive_damage(0, 7) /obj/item/organ/internal/emp_act(severity) - if(!robotic || emp_proof) + if(!is_robotic() || emp_proof) return - if(robotic == 2) - switch(severity) - if(1.0) - receive_damage(20, 1) - if(2.0) - receive_damage(7, 1) - else if(robotic == 1) - receive_damage(11, 1) - -/obj/item/organ/internal/heart/emp_act(intensity) - if(emp_proof) - return - if(owner && robotic == 2) - Stop() // In the name of looooove~! - owner.visible_message("[owner] clutches [owner.p_their()] chest and gasps!","You clutch your chest in pain!") - else if(owner && robotic == 1) - receive_damage(11,1) + switch(severity) + if(1) + receive_damage(20, 1) + if(2) + receive_damage(7, 1) /obj/item/organ/proc/remove(var/mob/living/user,special = 0) if(!istype(owner)) @@ -335,20 +310,15 @@ I use this so that this can be made better once the organ overhaul rolls out -- return 0 return src == O.get_int_organ(organ_tag) -/obj/item/organ/proc/is_robotic(var/purist = FALSE) - if(purist && (robotic > 1 || status & (ORGAN_ROBOT))) //Only the robotiest. +/obj/item/organ/proc/is_robotic() + if(status & ORGAN_ROBOT) return TRUE - if(robotic || status & (ORGAN_ROBOT|ORGAN_ASSISTED)) //Any tech will do. - return TRUE - return FALSE /obj/item/organ/serialize() var/data = ..() if(status != 0) data["status"] = status - if(robotic > 0) - data["robotic"] = robotic // Save the DNA datum if: The owner doesn't exist, or the dna doesn't match // the owner @@ -356,15 +326,10 @@ I use this so that this can be made better once the organ overhaul rolls out -- data["dna"] = dna.serialize() return data -/obj/item/organ/deserialize(var/data) - switch(data["robotic"]) - if(1) - mechassist() - if(2) - robotize() - else - // Nothing +/obj/item/organ/deserialize(data) if(isnum(data["status"])) + if(data["status"] & ORGAN_ROBOT) + robotize() status = data["status"] if(islist(data["dna"])) // The only thing the official proc does is diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 960ce7c0da1..04ce880d5f5 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -105,13 +105,12 @@ /obj/item/organ/external/New(var/mob/living/carbon/holder) ..() var/mob/living/carbon/human/H = holder - icobase = species.icobase - deform = species.deform + icobase = dna.species.icobase + deform = dna.species.deform if(istype(H)) replaced(H) sync_colour_to_human(H) - spawn(1) - get_icon() + get_icon() /obj/item/organ/external/replaced(var/mob/living/carbon/human/target) owner = target @@ -241,7 +240,7 @@ #undef LIMB_DMG_PROB /obj/item/organ/external/proc/heal_damage(brute, burn, internal = 0, robo_repair = 0) - if(status & ORGAN_ROBOT && !robo_repair) + if(is_robotic() && !robo_repair) return brute_dam = max(brute_dam - brute, 0) @@ -260,10 +259,8 @@ This function completely restores a damaged organ to perfect condition. */ /obj/item/organ/external/rejuvenate() damage_state = "00" - if(status & ORGAN_ROBOT) //Robotic organs stay robotic. + if(is_robotic()) //Robotic organs stay robotic. status = ORGAN_ROBOT - else if(status & ORGAN_ASSISTED) //Assisted organs stay assisted. - status = ORGAN_ASSISTED else status = 0 germ_level = 0 @@ -281,7 +278,8 @@ This function completely restores a damaged organ to perfect condition. for(var/obj/item/organ/external/EO in contents) EO.rejuvenate() - owner.updatehealth() + if(owner) + owner.updatehealth() update_icon() if(!owner) processing_objects |= src @@ -330,7 +328,7 @@ Note that amputating the affected organ does in fact remove the infection from t */ /obj/item/organ/external/proc/update_germs() - if((status & ORGAN_ROBOT) || (IS_PLANT in owner.species.species_traits)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. + if(is_robotic() || (IS_PLANT in owner.dna.species.species_traits)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. germ_level = 0 return @@ -381,12 +379,12 @@ Note that amputating the affected organ does in fact remove the infection from t //spread the infection to child and parent organs if(children) for(var/obj/item/organ/external/child in children) - if(child.germ_level < germ_level && !(child.status & ORGAN_ROBOT)) + if(child.germ_level < germ_level && !child.is_robotic()) if(child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) child.germ_level++ if(parent) - if(parent.germ_level < germ_level && !(parent.status & ORGAN_ROBOT)) + if(parent.germ_level < germ_level && !parent.is_robotic()) if(parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) parent.germ_level++ @@ -398,14 +396,14 @@ Note that amputating the affected organ does in fact remove the infection from t //Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status. /obj/item/organ/external/proc/check_fracture() - if(config.bones_can_break && brute_dam > min_broken_damage && !(status & ORGAN_ROBOT)) + if(config.bones_can_break && brute_dam > min_broken_damage && !is_robotic()) fracture() /obj/item/organ/external/proc/check_for_internal_bleeding(damage) - if(NO_BLOOD in owner.species.species_traits) + if(NO_BLOOD in owner.dna.species.species_traits) return var/local_damage = brute_dam + damage - if(damage > 15 && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT)) + if(damage > 15 && local_damage > 30 && prob(damage) && !is_robotic()) internal_bleeding = TRUE owner.custom_pain("You feel something rip in your [name]!") @@ -451,7 +449,7 @@ Note that amputating the affected organ does in fact remove the infection from t ****************************************************/ //Handles dismemberment -/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children, var/nodamage) +/obj/item/organ/external/proc/droplimb(clean, disintegrate, ignore_children, nodamage) if(cannot_amputate || !owner) return @@ -462,20 +460,20 @@ Note that amputating the affected organ does in fact remove the infection from t switch(disintegrate) if(DROPLIMB_SHARP) if(!clean) - var/gore_sound = "[(status & ORGAN_ROBOT) ? "tortured metal" : "ripping tendons and flesh"]" + var/gore_sound = "[is_robotic() ? "tortured metal" : "ripping tendons and flesh"]" owner.visible_message( "\The [owner]'s [src.name] flies off in an arc!",\ "Your [src.name] goes flying off!",\ "You hear a terrible sound of [gore_sound].") if(DROPLIMB_BURN) - var/gore = "[(status & ORGAN_ROBOT) ? "": " of burning flesh"]" + var/gore = "[is_robotic() ? "" : " of burning flesh"]" owner.visible_message( "\The [owner]'s [src.name] flashes away into ashes!",\ "Your [src.name] flashes away into ashes!",\ "You hear a crackling sound[gore].") if(DROPLIMB_BLUNT) - var/gore = "[(status & ORGAN_ROBOT) ? "": " in shower of gore"]" - var/gore_sound = "[(status & ORGAN_ROBOT) ? "rending sound of tortured metal" : "sickening splatter of gore"]" + var/gore = "[is_robotic() ? "": " in shower of gore"]" + var/gore_sound = "[is_robotic() ? "rending sound of tortured metal" : "sickening splatter of gore"]" owner.visible_message( "\The [owner]'s [src.name] explodes[gore]!",\ "Your [src.name] explodes[gore]!",\ @@ -496,16 +494,17 @@ Note that amputating the affected organ does in fact remove the infection from t parent.receive_damage(total_brute, total_burn, ignore_resists = TRUE) //Transfer the full damage to the parent, bypass limb damage reduction. parent = null - spawn(1) - if(victim) - victim.updatehealth() - victim.UpdateDamageIcon() - victim.regenerate_icons() dir = 2 + + if(victim) + victim.updatehealth() + victim.UpdateDamageIcon() + victim.regenerate_icons() + switch(disintegrate) if(DROPLIMB_SHARP) compile_icon() - add_blood(victim.blood_DNA, victim.species.blood_color) + add_blood(victim.blood_DNA, victim.dna.species.blood_color) var/matrix/M = matrix() M.Turn(rand(180)) src.transform = M @@ -515,7 +514,7 @@ Note that amputating the affected organ does in fact remove the infection from t dropped_part.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) dir = 2 brute_dam = 0 - burn_dam = 0 //Reset the damage on the limb; the damage should have transferred to the parent; we don't want extra damage being re-applie when then limb is re-attached + burn_dam = 0 //Reset the damage on the limb; the damage should have transferred to the parent; we don't want extra damage being re-applied when then limb is re-attached return dropped_part else qdel(src) // If you flashed away to ashes, YOU FLASHED AWAY TO ASHES @@ -573,7 +572,7 @@ Note that amputating the affected organ does in fact remove the infection from t //empties the bodypart from its organs and other things inside it /obj/item/organ/external/proc/drop_organs(mob/user) var/turf/T = get_turf(src) - if(status != ORGAN_ROBOT) + if(!is_robotic()) playsound(T, 'sound/effects/splat.ogg', 25, 1) for(var/obj/item/I in src) I.forceMove(T) @@ -598,7 +597,7 @@ Note that amputating the affected organ does in fact remove the infection from t holder.unEquip(holder.legcuffed) /obj/item/organ/external/proc/fracture() - if(status & ORGAN_ROBOT) + if(is_robotic()) return //ORGAN_BROKEN doesn't have the same meaning for robot limbs if((status & ORGAN_BROKEN) || cannot_break) @@ -608,7 +607,7 @@ Note that amputating the affected organ does in fact remove the infection from t "You hear a loud cracking sound coming from \the [owner].",\ "Something feels like it shattered in your [name]!",\ "You hear a sickening crack.") - if(owner.species && !(NO_PAIN in owner.species.species_traits)) + if(owner.dna.species && !(NO_PAIN in owner.dna.species.species_traits)) owner.emote("scream") status |= ORGAN_BROKEN @@ -620,7 +619,7 @@ Note that amputating the affected organ does in fact remove the infection from t release_restraints() /obj/item/organ/external/proc/mend_fracture() - if(status & ORGAN_ROBOT) + if(is_robotic()) return 0 //ORGAN_BROKEN doesn't have the same meaning for robot limbs if(brute_dam > min_broken_damage) return 0 //will just immediately fracture again @@ -679,12 +678,12 @@ Note that amputating the affected organ does in fact remove the infection from t return FALSE /obj/item/organ/external/proc/is_usable() - if(((status & ORGAN_ROBOT) && get_damage() >= max_damage) && !tough) //robot limbs just become inoperable at max damage + if((is_robotic() && get_damage() >= max_damage) && !tough) //robot limbs just become inoperable at max damage return return !(status & (ORGAN_MUTATED|ORGAN_DEAD)) /obj/item/organ/external/proc/is_malfunctioning() - return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam) && !tough) + return (is_robotic() && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam) && !tough) /obj/item/organ/external/remove(var/mob/living/user, var/ignore_children) @@ -766,7 +765,7 @@ Note that amputating the affected organ does in fact remove the infection from t /obj/item/organ/external/serialize() var/list/data = ..() - if(robotic == 2) + if(is_robotic()) data["company"] = model // If we wanted to store wound information, here is where it would go return data diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index e1be25758b5..43d699c0408 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -16,7 +16,7 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/proc/change_organ_icobase(var/new_icobase, var/new_deform, var/owner_sensitive) //Change the icobase/deform of this organ. If owner_sensitive is set, that means the proc won't mess with frankenstein limbs. if(owner_sensitive) //This and the below statements mean that the icobase/deform will only get updated if the limb is the same species as and is owned by the mob it's attached to. - if(species && owner.species && species.name != owner.species.name) + if(dna.species && owner.dna.species && dna.species.name != owner.dna.species.name) return if(dna.unique_enzymes != owner.dna.unique_enzymes) // This isn't MY arm return @@ -25,31 +25,31 @@ var/global/list/limb_icon_cache = list() deform = new_deform ? new_deform : deform /obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/H) - if(status & ORGAN_ROBOT && !(species && species.name == "Machine")) //machine people get skin color + if(is_robotic() && !istype(dna.species, /datum/species/machine)) //machine people get skin color return - if(species && H.species && species.name != H.species.name) + if(dna.species && H.dna.species && dna.species.name != H.dna.species.name) return if(dna.unique_enzymes != H.dna.unique_enzymes) // This isn't MY arm - if(!(H.species.bodyflags & HAS_ICON_SKIN_TONE)) + if(!(H.dna.species.bodyflags & HAS_ICON_SKIN_TONE)) sync_colour_to_dna() return - if(!isnull(H.s_tone) && ((H.species.bodyflags & HAS_SKIN_TONE) || (H.species.bodyflags & HAS_ICON_SKIN_TONE))) + if(!isnull(H.s_tone) && ((H.dna.species.bodyflags & HAS_SKIN_TONE) || (H.dna.species.bodyflags & HAS_ICON_SKIN_TONE))) s_col = null s_tone = H.s_tone - if(H.species.bodyflags & HAS_SKIN_COLOR) + if(H.dna.species.bodyflags & HAS_SKIN_COLOR) s_tone = null s_col = H.skin_colour - if(H.species.bodyflags & HAS_ICON_SKIN_TONE) + if(H.dna.species.bodyflags & HAS_ICON_SKIN_TONE) var/obj/item/organ/external/chest/C = H.get_organ("chest") change_organ_icobase(C.icobase, C.deform) /obj/item/organ/external/proc/sync_colour_to_dna() - if(status & ORGAN_ROBOT) + if(is_robotic()) return - if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && ((species.bodyflags & HAS_SKIN_TONE) || (species.bodyflags & HAS_ICON_SKIN_TONE))) + if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && ((dna.species.bodyflags & HAS_SKIN_TONE) || (dna.species.bodyflags & HAS_ICON_SKIN_TONE))) s_col = null s_tone = dna.GetUIValue(DNA_UI_SKIN_TONE) - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) s_tone = null s_col = rgb(dna.GetUIValue(DNA_UI_SKIN_R), dna.GetUIValue(DNA_UI_SKIN_G), dna.GetUIValue(DNA_UI_SKIN_B)) @@ -64,11 +64,9 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/proc/get_icon(skeletal, fat) // Kasparrov, you monster - if(istext(species)) - species = all_species[species] if(force_icon) mob_icon = new /icon(force_icon, "[icon_name]") - if(species && species.name == "Machine") //snowflake for IPC's, sorry. + if(istype(dna.species, /datum/species/machine)) //snowflake for IPC's, sorry. if(s_col) mob_icon.Blend(s_col, ICON_ADD) else @@ -76,7 +74,7 @@ var/global/list/limb_icon_cache = list() var/icon_file = new_icons[1] var/new_icon_state = new_icons[2] mob_icon = new /icon(icon_file, new_icon_state) - if(!skeletal && !(status & ORGAN_ROBOT)) + if(!skeletal && !is_robotic()) if(status & ORGAN_DEAD) mob_icon.ColorTone(rgb(10,50,0)) mob_icon.SetIntensity(0.7) @@ -101,13 +99,13 @@ var/global/list/limb_icon_cache = list() if(!owner) return - if(species.has_organ["eyes"]) + if(dna.species.has_organ["eyes"]) var/icon/eyes_icon = owner.get_eyecon() if(eyes_icon) mob_icon.Blend(eyes_icon, ICON_OVERLAY) overlays |= eyes_icon - if(owner.lip_style && (LIPS in species.species_traits)) + if(owner.lip_style && (LIPS in dna.species.species_traits)) var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") overlays |= lip_icon mob_icon.Blend(lip_icon, ICON_OVERLAY) @@ -115,7 +113,7 @@ var/global/list/limb_icon_cache = list() var/head_marking = owner.m_styles["head"] if(head_marking && head_marking != "None") var/datum/sprite_accessory/head_marking_style = marking_styles_list[head_marking] - if(head_marking_style && head_marking_style.species_allowed && (species.name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") + if(head_marking_style && head_marking_style.species_allowed && (dna.species.name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(owner.m_colours["head"], ICON_ADD) @@ -123,7 +121,7 @@ var/global/list/limb_icon_cache = list() if(ha_style) var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[ha_style] - if(head_accessory_style && head_accessory_style.species_allowed && (species.name in head_accessory_style.species_allowed)) + if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) head_accessory_s.Blend(headacc_colour, ICON_ADD) @@ -131,9 +129,9 @@ var/global/list/limb_icon_cache = list() if(f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (species.name in facial_hair_style.species_allowed)) || (src.species.bodyflags & ALL_RPARTS))) + if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(species.name == "Slime People") // I am el worstos + if(istype(dna.species, /datum/species/slime)) // I am el worstos facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. else if(facial_hair_style.do_colouration) facial_s.Blend(facial_colour, ICON_ADD) @@ -141,9 +139,9 @@ var/global/list/limb_icon_cache = list() if(h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) var/datum/sprite_accessory/hair_style = hair_styles_full_list[h_style] - if(hair_style && ((species.name in hair_style.species_allowed) || (src.species.bodyflags & ALL_RPARTS))) + if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(species.name == "Slime People") // I am el worstos + if(istype(dna.species, /datum/species/slime)) // I am el worstos hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. else if(hair_style.do_colouration) hair_s.Blend(hair_colour, ICON_ADD) @@ -172,7 +170,7 @@ var/global/list/limb_icon_cache = list() if(skeletal) icon_file = 'icons/mob/human_races/r_skeleton.dmi' - else if(status & ORGAN_ROBOT) + else if(is_robotic()) icon_file = 'icons/mob/human_races/robotic.dmi' else if(status & ORGAN_MUTATED) @@ -184,7 +182,7 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/chest/get_icon_state(skeletal) var/result = ..() - if(fat && !skeletal && !(status & ORGAN_ROBOT) && (CAN_BE_FAT in species.species_traits)) + if(fat && !skeletal && !is_robotic() && (CAN_BE_FAT in dna.species.species_traits)) result[2] += "_fat" return result diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 42d2c98a66d..4858435cc5f 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -1,5 +1,3 @@ -#define PROCESS_ACCURACY 10 - /obj/item/organ/internal origin_tech = "biotech=3" force = 1 @@ -7,7 +5,6 @@ throwforce = 0 var/slot // DO NOT add slots with matching names to different zones - it will break internal_organs_slot list! - vital = 0 var/non_primary = 0 var/unremovable = FALSE //Whether it shows up as an option to remove during surgery. @@ -90,7 +87,7 @@ return /obj/item/organ/internal/proc/prepare_eat() - if(status == ORGAN_ROBOT) + if(is_robotic()) return //no eating cybernetic implants! var/obj/item/reagent_containers/food/snacks/organ/S = new S.name = name @@ -137,310 +134,21 @@ // Brain is defined in brain_item.dm. -/obj/item/organ/internal/heart - name = "heart" - icon_state = "heart-on" - organ_tag = "heart" - parent_organ = "chest" - slot = "heart" - origin_tech = "biotech=5" - var/beating = 1 - dead_icon = "heart-off" - var/icon_base = "heart" - -/obj/item/organ/internal/heart/update_icon() - if(beating) - icon_state = "[icon_base]-on" - else - icon_state = "[icon_base]-off" - -/obj/item/organ/internal/heart/remove(mob/living/carbon/M, special = 0) - . = ..() - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.stat == DEAD) - Stop() - return - - spawn(120) - if(!owner) - Stop() - -/obj/item/organ/internal/heart/attack_self(mob/user) - ..() - if(!beating) - Restart() - spawn(80) - if(!owner) - Stop() - -/obj/item/organ/internal/heart/safe_replace(mob/living/carbon/human/target) - Restart() - ..() - -/obj/item/organ/internal/heart/proc/Stop() - beating = 0 - update_icon() - return 1 - -/obj/item/organ/internal/heart/proc/Restart() - beating = 1 - update_icon() - return 1 - -/obj/item/organ/internal/heart/prepare_eat() - var/obj/S = ..() - S.icon_state = dead_icon - return S - -/obj/item/organ/internal/heart/cursed - name = "cursed heart" - desc = "it needs to be pumped..." - icon_state = "cursedheart-off" - icon_base = "cursedheart" - origin_tech = "biotech=6" - actions_types = list(/datum/action/item_action/organ_action/cursed_heart) - var/last_pump = 0 - var/pump_delay = 30 //you can pump 1 second early, for lag, but no more (otherwise you could spam heal) - var/blood_loss = 100 //600 blood is human default, so 5 failures (below 122 blood is where humans die because reasons?) - - //How much to heal per pump, negative numbers would HURT the player - var/heal_brute = 0 - var/heal_burn = 0 - var/heal_oxy = 0 - - -/obj/item/organ/internal/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target) - if(H == user && istype(H)) - if(NO_BLOOD in H.species.species_traits) - to_chat(H, "\The [src] is not compatible with your form!") - return - playsound(user,'sound/effects/singlebeat.ogg', 40, 1) - user.drop_item() - insert(user) - else - return ..() - -/obj/item/organ/internal/heart/cursed/on_life() - if(world.time > (last_pump + pump_delay)) - if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects. - var/mob/living/carbon/human/H = owner - if(!(NO_BLOOD in H.species.species_traits)) - H.blood_volume = max(H.blood_volume - blood_loss, 0) - to_chat(H, "You have to keep pumping your blood!") - if(H.client) - H.client.color = "red" //bloody screen so real - else - last_pump = world.time //lets be extra fair *sigh* - -/obj/item/organ/internal/heart/cursed/insert(mob/living/carbon/M, special = 0) - ..() - if(owner) - to_chat(owner, "Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!") - - -/datum/action/item_action/organ_action/cursed_heart - name = "pump your blood" - -//You are now brea- pumping blood manually -/datum/action/item_action/organ_action/cursed_heart/Trigger() - . = ..() - if(. && istype(target,/obj/item/organ/internal/heart/cursed)) - var/obj/item/organ/internal/heart/cursed/cursed_heart = target - - if(world.time < (cursed_heart.last_pump + (cursed_heart.pump_delay-10))) //no spam - to_chat(owner, "Too soon!") - return - - cursed_heart.last_pump = world.time - playsound(owner,'sound/effects/singlebeat.ogg',40,1) - to_chat(owner, "Your heart beats.") - - var/mob/living/carbon/human/H = owner - if(istype(H)) - if(!(NO_BLOOD in H.species.species_traits)) - H.blood_volume = min(H.blood_volume + cursed_heart.blood_loss*0.5, BLOOD_VOLUME_NORMAL) - if(owner.client) - owner.client.color = "" - - H.adjustBruteLoss(-cursed_heart.heal_brute) - H.adjustFireLoss(-cursed_heart.heal_burn) - H.adjustOxyLoss(-cursed_heart.heal_oxy) - -/obj/item/organ/internal/kidneys - name = "kidneys" - icon_state = "kidneys" - gender = PLURAL - organ_tag = "kidneys" - parent_organ = "groin" - slot = "kidneys" - -/obj/item/organ/internal/kidneys/on_life() - // Coffee is really bad for you with busted kidneys. - // This should probably be expanded in some way, but fucked if I know - // what else kidneys can process in our reagent list. - var/datum/reagent/coffee = locate(/datum/reagent/consumable/drink/coffee) in owner.reagents.reagent_list - if(coffee) - if(is_bruised()) - owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) - else if(is_broken()) - owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) - - -/obj/item/organ/internal/eyes - name = "eyeballs" - icon_state = "eyes" - gender = PLURAL - organ_tag = "eyes" - parent_organ = "head" - slot = "eyes" - var/eye_colour = "#000000" - var/list/colourmatrix = null - var/list/colourblind_matrix = MATRIX_GREYSCALE //Special colourblindness parameters. By default, it's black-and-white. - var/list/replace_colours = LIST_GREYSCALE_REPLACE - var/dependent_disabilities = null //Gets set by eye-dependent disabilities such as colourblindness so the eyes can transfer the disability during transplantation. - var/dark_view = 2 //Default dark_view for Humans. - var/weld_proof = null //If set, the eyes will not take damage during welding. eg. IPC optical sensors do not take damage when they weld things while all other eyes will. - -/obj/item/organ/internal/eyes/proc/update_colour() - dna.write_eyes_attributes(src) - -/obj/item/organ/internal/eyes/proc/generate_icon(var/mob/living/carbon/human/HA) - var/mob/living/carbon/human/H = HA - if(!istype(H)) - H = owner - var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', H.species.eyes) - eyes_icon.Blend(eye_colour, ICON_ADD) - - return eyes_icon - -/obj/item/organ/internal/eyes/proc/get_colourmatrix() //Returns a special colour matrix if the eyes are organic and the mob is colourblind, otherwise it uses the current one. - if(!robotic && owner.disabilities & COLOURBLIND) - return colourblind_matrix - else - return colourmatrix - -/obj/item/organ/internal/eyes/proc/get_dark_view() //Returns dark_view (if the eyes are organic) for see_invisible handling in species.dm to be autoprocessed by life(). - return dark_view - -/obj/item/organ/internal/eyes/proc/shine() - if(is_robotic() || (dark_view > EYE_SHINE_THRESHOLD)) - return TRUE - -/obj/item/organ/internal/eyes/insert(mob/living/carbon/human/M, special = 0) - ..() - if(istype(M) && eye_colour) - M.update_body() //Apply our eye colour to the target. - - if(!(M.disabilities & COLOURBLIND) && (dependent_disabilities & COLOURBLIND)) //If the eyes are colourblind and we're not, carry over the gene. - dependent_disabilities &= ~COLOURBLIND - M.dna.SetSEState(COLOURBLINDBLOCK,1) - genemutcheck(M,COLOURBLINDBLOCK,null,MUTCHK_FORCED) - else - M.update_client_colour() //If we're here, that means the mob acquired the colourblindness gene while they didn't have eyes. Better handle it. - -/obj/item/organ/internal/eyes/remove(mob/living/carbon/human/M, special = 0) - if(!special && (M.disabilities & COLOURBLIND)) //If special is set, that means these eyes are getting deleted (i.e. during set_species()) - if(!(dependent_disabilities & COLOURBLIND)) //We only want to change COLOURBLINDBLOCK and such it the eyes are being surgically removed. - dependent_disabilities |= COLOURBLIND - M.dna.SetSEState(COLOURBLINDBLOCK,0) - genemutcheck(M,COLOURBLINDBLOCK,null,MUTCHK_FORCED) - . = ..() - -/obj/item/organ/internal/eyes/surgeryize() - if(!owner) - return - owner.CureNearsighted() - owner.CureBlind() - owner.SetEyeBlurry(0) - owner.SetEyeBlind(0) - -/obj/item/organ/internal/robotize(var/icon_bypass) //If icon bypass isn't null, skip the processing here and go straight to the parent call. - if(!icon_bypass && !(status & ORGAN_ROBOT)) //Don't override the icons for the already-mechanical IPC organs. +/obj/item/organ/internal/robotize() + if(!is_robotic()) var/list/states = icon_states('icons/obj/surgery.dmi') //Insensitive to specially-defined icon files for species like the Drask or whomever else. Everyone gets the same robotic heart. - if(slot == "heart" && ("[slot]-prosthetic-on" in states) && ("[slot]-prosthetic-off" in states)) //Give the robotic heart its robotic heart icons if they exist. + if(slot == "heart" && ("[slot]-c-on" in states) && ("[slot]-c-off" in states)) //Give the robotic heart its robotic heart icons if they exist. var/obj/item/organ/internal/heart/H = src H.icon = icon('icons/obj/surgery.dmi') - H.icon_base = "[slot]-prosthetic" - H.dead_icon = "[slot]-prosthetic-off" + H.icon_base = "[slot]-c" + H.dead_icon = "[slot]-c-off" H.update_icon() - else if("[slot]-prosthetic" in states) //Give the robotic organ its robotic organ icons if they exist. + else if("[slot]-c" in states) //Give the robotic organ its robotic organ icons if they exist. icon = icon('icons/obj/surgery.dmi') - icon_state = "[slot]-prosthetic" - name = "mechanical [slot]" + icon_state = "[slot]-c" + name = "cybernetic [slot]" ..() //Go apply all the organ flags/robotic statuses. -/obj/item/organ/internal/eyes/robotize() - colourmatrix = null - dark_view = 2 - ..() //Make sure the organ's got the robotic status indicators before updating the client colour. - if(owner) - owner.update_client_colour(0) //Since both mechassisted and mechanical eyes give dark_view of 2 and full colour vision atm, just having this here is fine as mechassist() will call it anyway. - -/obj/item/organ/internal/mechassist() - ..() //Go back, call robotize(), adjust the robotic status indicators and the organ damage parameters. - var/list/states = icon_states(icon) //Sensitive to specially-defined icon files since the organs are not fully synthetic. - if(slot == "heart" && ("[organ_tag]-assisted-on" in states) && ("[organ_tag]-assisted-off" in states)) //Give the mechassisted heart its mechassisted heart icons if they exist. - var/obj/item/organ/internal/heart/H = src - H.icon_base = "[organ_tag]-assisted" - H.dead_icon = "[organ_tag]-assisted-off" - H.update_icon() - else if("[organ_tag]-assisted" in states) //Give the mechassisted organ its mechassisted organ icons if they exist. - icon_state = "[organ_tag]-assisted" - name = "mechanically assisted [initial(name)]" //Avoid setting the organ's name to something like "mechanically assisted mechanical eyes". - -/obj/item/organ/internal/liver - name = "liver" - icon_state = "liver" - organ_tag = "liver" - parent_organ = "groin" - slot = "liver" - var/alcohol_intensity = 1 - -/obj/item/organ/internal/liver/on_life() - if(germ_level > INFECTION_LEVEL_ONE) - if(prob(1)) - to_chat(owner, " Your skin itches.") - if(germ_level > INFECTION_LEVEL_TWO) - if(prob(1)) - spawn owner.vomit() - - if(owner.life_tick % PROCESS_ACCURACY == 0) - - //High toxins levels are dangerous - if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("charcoal")) - //Healthy liver suffers on its own - if(damage < min_broken_damage) - receive_damage(0.2 * PROCESS_ACCURACY) - //Damaged one shares the fun - else - var/obj/item/organ/internal/O = pick(owner.internal_organs) - if(O) - O.receive_damage(0.2 * PROCESS_ACCURACY) - - //Detox can heal small amounts of damage - if(damage && damage < min_bruised_damage && owner.reagents.has_reagent("charcoal")) - receive_damage(-0.2 * PROCESS_ACCURACY) - - // Get the effectiveness of the liver. - var/filter_effect = 3 - if(is_bruised()) - filter_effect -= 1 - if(is_broken()) - filter_effect -= 2 - - // Damaged liver means some chemicals are very dangerous - if(damage >= min_bruised_damage) - for(var/datum/reagent/R in owner.reagents.reagent_list) - // Ethanol and all drinks are bad - if(istype(R, /datum/reagent/consumable/ethanol)) - owner.adjustToxLoss(0.1 * PROCESS_ACCURACY) - - // Can't cope with toxins at all - for(var/toxin in list("toxin", "plasma", "sacid", "facid", "cyanide", "amanitin", "carpotoxin")) - if(owner.reagents.has_reagent(toxin)) - owner.adjustToxLoss(0.3 * PROCESS_ACCURACY) - /obj/item/organ/internal/appendix name = "appendix" icon_state = "appendix" diff --git a/code/modules/surgery/organs/pain.dm b/code/modules/surgery/organs/pain.dm index e3386aef1b3..4863bd63901 100644 --- a/code/modules/surgery/organs/pain.dm +++ b/code/modules/surgery/organs/pain.dm @@ -34,7 +34,7 @@ mob/living/carbon/human/proc/custom_pain(message) if(stat >= UNCONSCIOUS) return - if(NO_PAIN in species.species_traits) + if(NO_PAIN in dna.species.species_traits) return if(reagents.has_reagent("morphine")) return @@ -54,7 +54,7 @@ mob/living/carbon/human/proc/handle_pain() if(stat >= UNCONSCIOUS) return - if(NO_PAIN in species.species_traits) + if(NO_PAIN in dna.species.species_traits) return if(reagents.has_reagent("morphine")) return diff --git a/code/modules/surgery/organs/parasites.dm b/code/modules/surgery/organs/parasites.dm index 900e60d9806..bea8d37ae38 100644 --- a/code/modules/surgery/organs/parasites.dm +++ b/code/modules/surgery/organs/parasites.dm @@ -35,7 +35,8 @@ /obj/item/organ/internal/body_egg/spider_eggs/remove(var/mob/living/carbon/M, var/special = 0) ..() M.reagents.del_reagent("spidereggs") //purge all remaining spider eggs reagent if caught, in time. - qdel(src) //We don't want people re-implanting these for near instant gibbings. + if(!QDELETED(src)) + qdel(src) // prevent people re-implanting them into others return null @@ -114,5 +115,6 @@ /obj/item/organ/internal/body_egg/terror_eggs/remove(var/mob/living/carbon/M, var/special = 0) ..() - qdel(src) // prevent people re-implanting them into others + if(!QDELETED(src)) + qdel(src) // prevent people re-implanting them into others return null diff --git a/code/modules/surgery/organs/subtypes/abductor.dm b/code/modules/surgery/organs/subtypes/abductor.dm index 6fd234bc501..58efd0094ed 100644 --- a/code/modules/surgery/organs/subtypes/abductor.dm +++ b/code/modules/surgery/organs/subtypes/abductor.dm @@ -1,4 +1,3 @@ /obj/item/organ/internal/eyes/abductor name = "abductor eyeballs" - dark_view = 3 - species = "Abductor" + dark_view = 3 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/diona.dm b/code/modules/surgery/organs/subtypes/diona.dm index 951ca862317..be05b2917c3 100644 --- a/code/modules/surgery/organs/subtypes/diona.dm +++ b/code/modules/surgery/organs/subtypes/diona.dm @@ -6,7 +6,6 @@ amputation_point = "trunk" encased = null gendered_icon = 0 - species = "Diona" /obj/item/organ/external/groin/diona name = "fork" @@ -14,7 +13,6 @@ cannot_break = 1 amputation_point = "lower trunk" gendered_icon = 0 - species = "Diona" /obj/item/organ/external/arm/diona name = "left upper tendril" @@ -22,7 +20,6 @@ min_broken_damage = 20 cannot_break = 1 amputation_point = "upper left trunk" - species = "Diona" /obj/item/organ/external/arm/right/diona name = "right upper tendril" @@ -30,7 +27,6 @@ min_broken_damage = 20 cannot_break = 1 amputation_point = "upper right trunk" - species = "Diona" /obj/item/organ/external/leg/diona name = "left lower tendril" @@ -38,7 +34,6 @@ min_broken_damage = 20 cannot_break = 1 amputation_point = "lower left fork" - species = "Diona" /obj/item/organ/external/leg/right/diona name = "right lower tendril" @@ -46,7 +41,6 @@ min_broken_damage = 20 cannot_break = 1 amputation_point = "lower right fork" - species = "Diona" /obj/item/organ/external/foot/diona name = "left foot" @@ -54,7 +48,6 @@ min_broken_damage = 10 cannot_break = 1 amputation_point = "branch" - species = "Diona" /obj/item/organ/external/foot/right/diona name = "right foot" @@ -62,19 +55,16 @@ min_broken_damage = 10 cannot_break = 1 amputation_point = "branch" - species = "Diona" /obj/item/organ/external/hand/diona name = "left grasper" cannot_break = 1 amputation_point = "branch" - species = "Diona" /obj/item/organ/external/hand/right/diona name = "right grasper" cannot_break = 1 amputation_point = "branch" - species = "Diona" /obj/item/organ/external/head/diona max_damage = 50 @@ -83,16 +73,6 @@ encased = null amputation_point = "upper trunk" gendered_icon = 0 - species = "Diona" - -//DIONA ORGANS. -/* /obj/item/organ/external/diona/removed() - var/mob/living/carbon/human/H = owner - ..() - if(!istype(H) || !H.bodyparts || !H.bodyparts.len) - H.death() - if(prob(50) && spawn_diona_nymph_from_organ(src)) - qdel(src) */ /obj/item/organ/diona/process() return @@ -101,31 +81,26 @@ name = "neural strata" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - species = "Diona" /obj/item/organ/internal/brain/diona // Turns into a nymph instantly, no transplanting possible. name = "gas bladder" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - species = "Diona" /obj/item/organ/internal/kidneys/diona // Turns into a nymph instantly, no transplanting possible. name = "polyp segment" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - species = "Diona" /obj/item/organ/internal/appendix/diona // Turns into a nymph instantly, no transplanting possible. name = "anchoring ligament" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - species = "Diona" /obj/item/organ/internal/eyes/diona // Turns into a nymph instantly, no transplanting possible. name = "receptor node" icon = 'icons/mob/alien.dmi' icon_state = "claw" - species = "Diona" //TODO:Make absorb rads on insert @@ -133,15 +108,4 @@ name = "nutrient vessel" icon = 'icons/mob/alien.dmi' icon_state = "claw" - alcohol_intensity = 0.5 - species = "Diona" - -//TODO:Make absorb light on insert. - -/*/obj/item/organ/diona/removed(var/mob/living/user) - var/mob/living/carbon/human/H = owner - ..() - if(!istype(H) || !H.bodyparts || !H.bodyparts.len) - H.death() - if(prob(50) && spawn_diona_nymph_from_organ(src)) - qdel(src) */ + alcohol_intensity = 0.5 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/drask.dm b/code/modules/surgery/organs/subtypes/drask.dm index 8560d2408ec..6e11cf2993e 100644 --- a/code/modules/surgery/organs/subtypes/drask.dm +++ b/code/modules/surgery/organs/subtypes/drask.dm @@ -4,31 +4,26 @@ icon = 'icons/obj/surgery_drask.dmi' icon_state = "innards" desc = "A greenish, slightly translucent organ. It is extremely cold." - species = "Drask" /obj/item/organ/internal/heart/drask name = "drask heart" icon = 'icons/obj/surgery_drask.dmi' parent_organ = "head" - species = "Drask" /obj/item/organ/internal/liver/drask name = "metabolic strainer" icon = 'icons/obj/surgery_drask.dmi' icon_state = "kidneys" alcohol_intensity = 0.8 - species = "Drask" /obj/item/organ/internal/brain/drask icon = 'icons/obj/surgery_drask.dmi' icon_state = "brain2" mmi_icon = 'icons/obj/surgery_drask.dmi' mmi_icon_state = "mmi_full" - species = "Drask" /obj/item/organ/internal/eyes/drask name = "drask eyeballs" icon = 'icons/obj/surgery_drask.dmi' desc = "Drask eyes. They look even stranger disembodied" - dark_view = 5 - species = "Drask" + dark_view = 5 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/grey.dm b/code/modules/surgery/organs/subtypes/grey.dm index 6c06da373b7..177e4ae5be1 100644 --- a/code/modules/surgery/organs/subtypes/grey.dm +++ b/code/modules/surgery/organs/subtypes/grey.dm @@ -1,11 +1,9 @@ /obj/item/organ/internal/liver/grey alcohol_intensity = 1.6 - species = "Grey" /obj/item/organ/internal/brain/grey icon_state = "brain-x" mmi_icon_state = "mmi_alien" - species = "Grey" /obj/item/organ/internal/brain/grey/insert(var/mob/living/carbon/M, var/special = 0) ..() @@ -17,5 +15,4 @@ /obj/item/organ/internal/eyes/grey name = "grey eyeballs" - dark_view = 5 - species = "Grey" + dark_view = 5 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/kidan.dm b/code/modules/surgery/organs/subtypes/kidan.dm index 37fd74a6d2a..d8fc67cc542 100644 --- a/code/modules/surgery/organs/subtypes/kidan.dm +++ b/code/modules/surgery/organs/subtypes/kidan.dm @@ -1,6 +1,5 @@ /obj/item/organ/internal/liver/kidan alcohol_intensity = 0.5 - species = "Kidan" #define KIDAN_LANTERN_HUNGERCOST 0.5 #define KIDAN_LANTERN_MINHUNGER 150 diff --git a/code/modules/surgery/organs/subtypes/machine.dm b/code/modules/surgery/organs/subtypes/machine.dm index 2be14a91f14..b66d13612a3 100644 --- a/code/modules/surgery/organs/subtypes/machine.dm +++ b/code/modules/surgery/organs/subtypes/machine.dm @@ -1,105 +1,94 @@ // IPC limbs. /obj/item/organ/external/head/ipc can_intake_reagents = 0 - vital = 0 max_damage = 50 //made same as arm, since it is not vital min_broken_damage = 30 encased = null status = ORGAN_ROBOT - species = "Machine" -/obj/item/organ/external/head/ipc/New() +/obj/item/organ/external/head/ipc/New(mob/living/carbon/holder, datum/species/species_override = null) + ..(holder, /datum/species/machine) // IPC heads need to be explicitly set to this since you can print them robotize("Morpheus Cyberkinetics") - ..() /obj/item/organ/external/chest/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/chest/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/groin/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/groin/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/arm/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/arm/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/arm/right/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/arm/right/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") + /obj/item/organ/external/leg/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/leg/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/leg/right/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/leg/right/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/foot/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/foot/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/foot/right/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/foot/right/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/hand/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/hand/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/hand/right/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/hand/right/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/internal/cell name = "microbattery" @@ -109,86 +98,39 @@ organ_tag = "heart" parent_organ = "chest" slot = "heart" - vital = 1 + vital = TRUE status = ORGAN_ROBOT - species = "Machine" - -/obj/item/organ/internal/cell/New() - robotize() - ..() /obj/item/organ/internal/eyes/optical_sensor name = "optical sensor" icon = 'icons/obj/robot_component.dmi' icon_state = "camera" status = ORGAN_ROBOT - species = "Machine" // dead_icon = "camera_broken" weld_proof = 1 -/obj/item/organ/internal/eyes/optical_sensor/New() - robotize() - ..() - - /obj/item/organ/internal/eyes/optical_sensor/remove(var/mob/living/user,special = 0) if(!special) to_chat(owner, "Error 404:Optical Sensors not found.") . = ..() -// Used for an MMI or posibrain being installed into a human. -/obj/item/organ/internal/brain/mmi_holder - name = "brain" - organ_tag = "brain" - parent_organ = "chest" - vital = 1 - max_damage = 200 - slot = "brain" - status = ORGAN_ROBOT - species = "Machine" - var/obj/item/mmi/stored_mmi - -/obj/item/organ/internal/brain/mmi_holder/Destroy() - QDEL_NULL(stored_mmi) - return ..() - -/obj/item/organ/internal/brain/mmi_holder/insert(var/mob/living/target,special = 0) - ..() - // To supersede the over-writing of the MMI's name from `insert` - update_from_mmi() - -/obj/item/organ/internal/brain/mmi_holder/remove(var/mob/living/user,special = 0) - if(!special) - if(stored_mmi) - . = stored_mmi - if(owner.mind) - owner.mind.transfer_to(stored_mmi.brainmob) - stored_mmi.forceMove(get_turf(owner)) - stored_mmi = null - ..() - qdel(src) - -/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi() - if(!stored_mmi) - return - name = stored_mmi.name - desc = stored_mmi.desc - icon = stored_mmi.icon - icon_state = stored_mmi.icon_state - set_dna(stored_mmi.brainmob.dna) +/obj/item/organ/internal/brain/mmi_holder/posibrain + name = "positronic brain" /obj/item/organ/internal/brain/mmi_holder/posibrain/New() - robotize() - stored_mmi = new /obj/item/mmi/posibrain/ipc(src) ..() - spawn(1) - if(owner) - stored_mmi.name = "positronic brain ([owner.real_name])" - stored_mmi.brainmob.real_name = owner.real_name - stored_mmi.brainmob.name = stored_mmi.brainmob.real_name - stored_mmi.icon_state = "posibrain-occupied" - update_from_mmi() - else - stored_mmi.loc = get_turf(src) - qdel(src) + stored_mmi = new /obj/item/mmi/robotic_brain/positronic(src) + if(!owner) + stored_mmi.forceMove(get_turf(src)) + qdel(src) + +/obj/item/organ/internal/brain/mmi_holder/posibrain/remove(mob/living/user, special = 0) + if(stored_mmi && dna) + stored_mmi.name = "[initial(name)] ([dna.real_name])" + stored_mmi.brainmob.real_name = dna.real_name + stored_mmi.brainmob.name = stored_mmi.brainmob.real_name + stored_mmi.icon_state = "posibrain-occupied" + if(!stored_mmi.brainmob.dna) + stored_mmi.brainmob.dna = dna.Clone() + . = ..() \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/nucleation.dm b/code/modules/surgery/organs/subtypes/nucleation.dm index 4223834501d..3be564fc800 100644 --- a/code/modules/surgery/organs/subtypes/nucleation.dm +++ b/code/modules/surgery/organs/subtypes/nucleation.dm @@ -3,7 +3,6 @@ name = "nucleation organ" icon = 'icons/obj/surgery.dmi' desc = "A crystalized human organ. /red It has a strangely iridescent glow." - species = "Nucleation" /obj/item/organ/internal/nucleation/resonant_crystal name = "resonant crystal" @@ -11,7 +10,6 @@ organ_tag = "resonant crystal" parent_organ = "head" slot = "res_crystal" - species = "Nucleation" /obj/item/organ/internal/nucleation/strange_crystal name = "strange crystal" @@ -19,14 +17,12 @@ organ_tag = "strange crystal" parent_organ = "chest" slot = "heart" - species = "Nucleation" /obj/item/organ/internal/eyes/luminescent_crystal name = "luminescent eyes" icon_state = "crystal-eyes" organ_tag = "luminescent eyes" light_color = "#1C1C00" - species = "Nucleation" /obj/item/organ/internal/eyes/luminescent_crystal/New() set_light(2) @@ -35,5 +31,4 @@ /obj/item/organ/internal/brain/crystal name = "crystallized brain" icon_state = "crystal-brain" - organ_tag = "crystallized brain" - species = "Nucleation" + organ_tag = "crystallized brain" \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/shadow.dm b/code/modules/surgery/organs/subtypes/shadow.dm index f81fc54bfb1..26a0bc50577 100644 --- a/code/modules/surgery/organs/subtypes/shadow.dm +++ b/code/modules/surgery/organs/subtypes/shadow.dm @@ -1,4 +1,3 @@ /obj/item/organ/internal/eyes/shadow name = "dark orbs" - dark_view = 8 - species = "Shadow" + dark_view = 8 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/skrell.dm b/code/modules/surgery/organs/subtypes/skrell.dm index cb87d1c11c1..fd8a02f18d3 100644 --- a/code/modules/surgery/organs/subtypes/skrell.dm +++ b/code/modules/surgery/organs/subtypes/skrell.dm @@ -1,6 +1,5 @@ /obj/item/organ/internal/liver/skrell alcohol_intensity = 4 - species = "Skrell" /obj/item/organ/internal/headpocket name = "headpocket" @@ -10,7 +9,6 @@ w_class = WEIGHT_CLASS_TINY parent_organ = "head" slot = "headpocket" - species = "Skrell" actions_types = list(/datum/action/item_action/organ_action/toggle) var/obj/item/storage/internal/pocket diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index 30c4e173cdc..e04c27284ae 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -10,7 +10,7 @@ min_broken_damage = 35 w_class = WEIGHT_CLASS_HUGE body_part = UPPER_TORSO - vital = 1 + vital = TRUE amputation_point = "spine" gendered_icon = 1 parent_organ = null @@ -44,7 +44,7 @@ min_broken_damage = 35 w_class = WEIGHT_CLASS_BULKY // if you know what I mean ;) body_part = LOWER_TORSO - vital = 1 + vital = TRUE parent_organ = "chest" amputation_point = "lumbar" gendered_icon = 1 @@ -136,9 +136,9 @@ if(owner.gloves) owner.unEquip(owner.gloves) if(owner.l_hand) - owner.unEquip(owner.l_hand,1) + owner.unEquip(owner.l_hand, TRUE) if(owner.r_hand) - owner.unEquip(owner.r_hand,1) + owner.unEquip(owner.r_hand, TRUE) . = ..() @@ -158,7 +158,6 @@ min_broken_damage = 35 w_class = WEIGHT_CLASS_NORMAL body_part = HEAD - vital = 1 parent_organ = "chest" amputation_point = "neck" gendered_icon = 1 @@ -195,17 +194,14 @@ owner.unEquip(owner.r_ear) if(owner.wear_mask) owner.unEquip(owner.wear_mask) - spawn(1) - if(owner)//runtimer no runtiming - owner.update_hair() - owner.update_fhair() - owner.update_head_accessory() - owner.update_markings() + owner.update_hair() + owner.update_fhair() + owner.update_head_accessory() + owner.update_markings() . = ..() /obj/item/organ/external/head/replaced() name = limb_name - ..() /obj/item/organ/external/head/receive_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list(), ignore_resists = FALSE) @@ -225,6 +221,11 @@ alt_head = initial(alt_head) icon_name = initial(icon_name) +/obj/item/organ/external/head/robotize(company, make_tough = 0, convert_all = 1) //Undoes alt_head business to avoid getting in the way of robotization. Make sure we pass all args down the line... + alt_head = initial(alt_head) + icon_name = initial(icon_name) + ..() + /obj/item/organ/external/head/set_dna(datum/dna/new_dna) ..() new_dna.write_head_attributes(src) diff --git a/code/modules/surgery/organs/subtypes/tajaran.dm b/code/modules/surgery/organs/subtypes/tajaran.dm index a1313934037..1857fc5e45a 100644 --- a/code/modules/surgery/organs/subtypes/tajaran.dm +++ b/code/modules/surgery/organs/subtypes/tajaran.dm @@ -1,17 +1,14 @@ /obj/item/organ/internal/liver/tajaran alcohol_intensity = 1.4 - species = "Tajaran" /obj/item/organ/internal/eyes/tajaran name = "tajaran eyeballs" - species = "Tajaran" colourblind_matrix = MATRIX_TAJ_CBLIND //The colour matrix and darksight parameters that the mob will recieve when they get the disability. replace_colours = LIST_TAJ_REPLACE dark_view = 8 /obj/item/organ/internal/eyes/tajaran/farwa //Being the lesser form of Tajara, Farwas have an utterly incurable version of their colourblindness. name = "farwa eyeballs" - species = "Farwa" colourmatrix = MATRIX_TAJ_CBLIND dark_view = 8 replace_colours = LIST_TAJ_REPLACE diff --git a/code/modules/surgery/organs/subtypes/unathi.dm b/code/modules/surgery/organs/subtypes/unathi.dm index 0fb45319ce5..219ef0447e6 100644 --- a/code/modules/surgery/organs/subtypes/unathi.dm +++ b/code/modules/surgery/organs/subtypes/unathi.dm @@ -1,8 +1,6 @@ /obj/item/organ/internal/liver/unathi alcohol_intensity = 0.8 - species = "Unathi" /obj/item/organ/internal/eyes/unathi name = "unathi eyeballs" - dark_view = 3 - species = "Unathi" + dark_view = 3 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/vox.dm b/code/modules/surgery/organs/subtypes/vox.dm index bb56c41030d..960acf920a8 100644 --- a/code/modules/surgery/organs/subtypes/vox.dm +++ b/code/modules/surgery/organs/subtypes/vox.dm @@ -1,16 +1,12 @@ /obj/item/organ/internal/liver/vox alcohol_intensity = 1.6 - species = "Vox" /obj/item/organ/internal/stack - name = "cortical stack" + name = "vox cortical stack" icon_state = "brain-prosthetic" parent_organ = "head" organ_tag = "stack" slot = "vox_stack" - robotic = 2 - vital = 1 - -/obj/item/organ/internal/stack/vox - name = "vox cortical stack" \ No newline at end of file + status = ORGAN_ROBOT + vital = TRUE \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/vulpkanin.dm b/code/modules/surgery/organs/subtypes/vulpkanin.dm index be851c43486..959fbcc926c 100644 --- a/code/modules/surgery/organs/subtypes/vulpkanin.dm +++ b/code/modules/surgery/organs/subtypes/vulpkanin.dm @@ -1,18 +1,14 @@ /obj/item/organ/internal/liver/vulpkanin alcohol_intensity = 1.4 - species = "Vulpkanin" - /obj/item/organ/internal/eyes/vulpkanin name = "vulpkanin eyeballs" - species = "Vulpkanin" colourblind_matrix = MATRIX_VULP_CBLIND //The colour matrix and darksight parameters that the mob will recieve when they get the disability. replace_colours = LIST_VULP_REPLACE dark_view = 8 /obj/item/organ/internal/eyes/vulpkanin/wolpin //Being the lesser form of Vulpkanin, Wolpins have an utterly incurable version of their colourblindness. name = "wolpin eyeballs" - species = "Wolpin" colourmatrix = MATRIX_VULP_CBLIND dark_view = 8 - replace_colours = LIST_VULP_REPLACE + replace_colours = LIST_VULP_REPLACE \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/wryn.dm b/code/modules/surgery/organs/subtypes/wryn.dm index ee1a12fd1ab..ab30c16f61f 100644 --- a/code/modules/surgery/organs/subtypes/wryn.dm +++ b/code/modules/surgery/organs/subtypes/wryn.dm @@ -6,8 +6,6 @@ icon_state = "antennae" parent_organ = "head" slot = "hivenode" - species = "Wryn" /obj/item/organ/internal/eyes/wryn - dark_view = 3 - species = "Wryn" + dark_view = 3 \ No newline at end of file diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 4c0094592e9..32270c329c2 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -32,7 +32,7 @@ if(!affected) // I'd like to see you do surgery on LITERALLY NOTHING return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 if(!affected.encased) //no bone, problem. return 0 @@ -43,7 +43,7 @@ var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if(affected && (affected.status & ORGAN_ROBOT)) + if(affected && affected.is_robotic()) return 0//no operating on robotic limbs in an organic surgery if(!affected) // I'd like to see you do surgery on LITERALLY NOTHING @@ -101,6 +101,9 @@ if(is_int_organ(tool)) current_type = "insert" I = tool + if(I.requires_robotic_bodypart) + to_chat(user, "[I] is an organ that requires a robotic interface[target].") + return -1 if(target_zone != I.parent_organ || target.get_organ_slot(I.slot)) to_chat(user, "There is no room for [I] in [target]'s [parse_zone(target_zone)]!") return -1 @@ -208,12 +211,12 @@ for(var/obj/item/organ/internal/I in affected.internal_organs) if(I && I.damage) - if(I.robotic < 2 && !istype (tool, /obj/item/stack/nanopaste)) + if(!I.is_robotic() && !istype (tool, /obj/item/stack/nanopaste)) if(!(I.sterile)) spread_germs_to_organ(I, user, tool) user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ "You start treating damage to [target]'s [I.name] with [tool_name]." ) - else if(I.robotic >= 2 && istype(tool, /obj/item/stack/nanopaste)) + else if(I.is_robotic() && istype(tool, /obj/item/stack/nanopaste)) user.visible_message("[user] starts treating damage to [target]'s [I.name] with [tool_name].", \ "You start treating damage to [target]'s [I.name] with [tool_name]." ) @@ -246,23 +249,25 @@ if(I) I.surgeryize() if(I && I.damage) - if(I.robotic < 2 && !istype (tool, /obj/item/stack/nanopaste)) + if(!I.is_robotic() && !istype (tool, /obj/item/stack/nanopaste)) user.visible_message(" [user] treats damage to [target]'s [I.name] with [tool_name].", \ " You treat damage to [target]'s [I.name] with [tool_name]." ) I.damage = 0 - else if(I.robotic >= 2 && istype (tool, /obj/item/stack/nanopaste)) + else if(I.is_robotic() && istype (tool, /obj/item/stack/nanopaste)) user.visible_message(" [user] treats damage to [target]'s [I.name] with [tool_name].", \ " You treat damage to [target]'s [I.name] with [tool_name]." ) I.damage = 0 else if(current_type == "insert") I = tool - user.drop_item() - I.insert(target) - spread_germs_to_organ(I, user, tool) - if(!user.canUnEquip(I, 0)) + if(I.requires_robotic_bodypart) + to_chat(user, "[I] is an organ that requires a robotic interface[target].") + return FALSE + if(!user.drop_item()) to_chat(user, "[I] is stuck to your hand, you can't put it in [target]!") return 0 + I.insert(target) + spread_germs_to_organ(I, user, tool) if(affected) user.visible_message(" [user] has transplanted [tool] into [target]'s [affected.name].", diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 455a6a8de04..bcb5151d359 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -24,7 +24,7 @@ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 return 1 return 0 @@ -260,7 +260,7 @@ if(!B) // No brain to remove the tumor from return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 if(!(B in affected.internal_organs)) return 0 @@ -276,7 +276,7 @@ if(!B) // No brain to remove the tumor from return 0 - if(!(affected.status & ORGAN_ROBOT)) + if(!affected.is_robotic()) return 0 if(!(B in affected.internal_organs)) return 0 @@ -303,7 +303,7 @@ ..() /datum/surgery_step/internal/dethrall/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(target.get_species() == "Lesser Shadowling") //Empowered thralls cannot be deconverted + if(isshadowlinglesser(target)) //Empowered thralls cannot be deconverted to_chat(target, "NOT LIKE THIS!") user.visible_message("[target] suddenly slams upward and knocks down [user]!", \ "[target] suddenly bolts up and slams you with tremendous force!") diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm index 4d14d2e8a79..9483818d153 100644 --- a/code/modules/surgery/plastic_surgery.dm +++ b/code/modules/surgery/plastic_surgery.dm @@ -9,7 +9,7 @@ var/obj/item/organ/external/head/head = H.get_organ(user.zone_sel.selecting) if(!head) return FALSE - if(head.status & ORGAN_ROBOT) + if(head.is_robotic()) return FALSE return TRUE @@ -24,7 +24,7 @@ /datum/surgery_step/reshape_face/end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) var/obj/item/organ/external/head/head = target.get_organ(target_zone) - var/species_names = target.get_species() + var/species_names = target.dna.species.name if(head.disfigured) head.disfigured = FALSE user.visible_message("[user] successfully restores [target]'s appearance!", "You successfully restore [target]'s appearance.") diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index 56162dcabc8..3dde9ce1a09 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -13,7 +13,7 @@ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(affected.status & ORGAN_ROBOT) + if(affected.is_robotic()) return 0 return 1 @@ -23,7 +23,7 @@ var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(!(affected.status & ORGAN_ROBOT)) + if(!affected.is_robotic()) return 0 return 1 diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index ed82328c47d..f9fb2ac20c2 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -28,7 +28,7 @@ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(!(affected.status & ORGAN_ROBOT)) + if(!affected.is_robotic()) return 0 return 1 @@ -38,7 +38,7 @@ var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) if(!affected) return 0 - if(!(affected.status & ORGAN_ROBOT)) + if(!affected.is_robotic()) return 0 if(affected.cannot_amputate) return 0 @@ -64,7 +64,7 @@ if(!..()) return 0 var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!(affected.status & ORGAN_ROBOT)) + if(!affected.is_robotic()) return 0 return 1 @@ -305,7 +305,7 @@ current_type = "insert" var/obj/item/organ/internal/I = tool - if(I.status != ORGAN_ROBOT || I.robotic != 2) + if(!I.is_robotic()) to_chat(user, "You can only implant cybernetic organs.") if(target_zone != I.parent_organ || target.get_organ_slot(I.slot)) @@ -343,16 +343,16 @@ to_chat(user, "That brain is not usable.") return -1 - if(!(affected.status & ORGAN_ROBOT)) + if(!affected.is_robotic()) to_chat(user, "You cannot install a computer brain into a meat enclosure.") return -1 - if(!target.species) + if(!target.dna.species) to_chat(user, "You have no idea what species this person is. Report this on the bug tracker.") return -1 - if(!target.species.has_organ["brain"]) - to_chat(user, "You're pretty sure [target.species.name_plural] don't normally have a brain.") + if(!target.dna.species.has_organ["brain"]) + to_chat(user, "You're pretty sure [target.dna.species.name_plural] don't normally have a brain.") return -1 if(target.get_int_organ(/obj/item/organ/internal/brain/)) @@ -365,7 +365,7 @@ else if(implement_type in implements_extract) current_type = "extract" var/list/organs = target.get_organs_zone(target_zone) - if(!(affected && (affected.status & ORGAN_ROBOT))) + if(!(affected && affected.is_robotic())) return -1 if(!organs.len) to_chat(user, "There is no removeable organs in [target]'s [parse_zone(target_zone)]!") @@ -395,7 +395,7 @@ var/found_damaged_organ = FALSE for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I && I.damage && I.robotic >= 2) + if(I && I.damage && I.is_robotic()) user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ "You start mending the damage to [target]'s [I.name]'s mechanisms.") found_damaged_organ = TRUE @@ -421,7 +421,7 @@ return for(var/obj/item/organ/internal/I in affected.internal_organs) if(I && I.damage) - if(I.robotic >= 2) + if(I.is_robotic()) user.visible_message(" [user] repairs [target]'s [I.name] with [tool].", \ " You repair [target]'s [I.name] with [tool]." ) I.damage = 0 @@ -541,3 +541,60 @@ user.visible_message(" [user]'s hand slips!", \ " Your hand slips!") return 0 + +/datum/surgery/cybernetic_customization + name = "Cybernetic Appearance Customization" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch, /datum/surgery_step/robotics/external/customize_appearance) + possible_locs = list("head", "chest", "l_arm", "r_arm", "r_leg", "l_leg") + requires_organic_bodypart = FALSE + +/datum/surgery/cybernetic_customization/can_start(mob/user, mob/living/carbon/human/target) + if(ishuman(target)) + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return FALSE + if(!(affected.status & ORGAN_ROBOT)) + return FALSE + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance + name = "reprogram limb" + allowed_tools = list(/obj/item/multitool = 100) + time = 48 + +/datum/surgery_step/robotics/external/customize_appearance/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) + return FALSE + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to reprogram the appearance of [target]'s [affected.name] with [tool]." , \ + "You begin to reprogram the appearance of [target]'s [affected.name] with [tool].") + ..() + +/datum/surgery_step/robotics/external/customize_appearance/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/chosen_appearance = input(user, "Select the company appearance for this limb.", "Limb Company Selection") as null|anything in selectable_robolimbs + if(!chosen_appearance) + return FALSE + var/obj/item/organ/external/affected = target.get_organ(target_zone) + affected.robotize(chosen_appearance, convert_all = FALSE) + if(istype(affected, /obj/item/organ/external/head)) + var/obj/item/organ/external/head/head = affected + head.h_style = "Bald" // nearly all the appearance changes for heads are non-monitors; we want to get rid of a floating screen + target.update_hair() + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + user.visible_message(" [user] reprograms the appearance of [target]'s [affected.name] with [tool].", \ + " You reprogram the appearance of [target]'s [affected.name] with [tool].") + affected.open = 0 + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s [tool.name] slips, failing to reprogram [target]'s [affected.name].", + " Your [tool.name] slips, failing to reprogram [target]'s [affected.name].") + return FALSE \ No newline at end of file diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 56da8f031e3..72bf70c7e81 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -67,10 +67,6 @@ //How much blood this step can get on surgeon. 1 - hands, 2 - full body. var/blood_level = 0 - var/list/allowed_mob = list() - var/list/disallowed_mob = list() - - /datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) var/success = 0 if(accept_hand) @@ -146,19 +142,8 @@ // Checks if this step applies to the user mob at all /datum/surgery_step/proc/is_valid_target(mob/living/carbon/human/target) if(!hasorgans(target)) - return 0 - - if(allowed_mob)//can i just remove this and/or change it? - for(var/species in allowed_mob) - if(target.get_species() == species) - return 1 - - if(disallowed_mob) - for(var/species in disallowed_mob) - if(target.get_species() == species) - return 0 - - return 1 + return FALSE + return TRUE // checks whether this step can be applied with the given user and target /datum/surgery_step/proc/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -187,7 +172,7 @@ return null /proc/spread_germs_to_organ(obj/item/organ/E, mob/living/carbon/human/user, obj/item/tool) - if(!istype(user) || !istype(E) || !(E.status & ORGAN_ROBOT) || E.sterile) + if(!istype(user) || !istype(E) || E.is_robotic() || E.sterile) return var/germ_level = user.germ_level @@ -195,7 +180,7 @@ //germ spread from surgeon touching the patient if(user.gloves) germ_level = user.gloves.germ_level - E.germ_level += germ_level + E.germ_level = max(germ_level, E.germ_level) spread_germs_by_incision(E, tool) //germ spread from environement to patient /proc/spread_germs_by_incision(obj/item/organ/external/E,obj/item/tool) @@ -206,7 +191,7 @@ for(var/mob/living/carbon/human/H in view(2, E.loc))//germs from people if(AStar(E.loc, H.loc, /turf/proc/Distance, 2, simulated_only = 0)) - if((!(BREATHLESS in H.mutations) || !(NO_BREATHE in H.species.species_traits)) && !H.wear_mask) //wearing a mask helps preventing people from breathing cooties into open incisions + if((!(BREATHLESS in H.mutations) || !(NO_BREATHE in H.dna.species.species_traits)) && !H.wear_mask) //wearing a mask helps preventing people from breathing cooties into open incisions germs += H.germ_level * 0.25 for(var/obj/effect/decal/cleanable/M in view(2, E.loc))//germs from messes @@ -220,7 +205,7 @@ if(E.internal_organs.len) germs = germs / (E.internal_organs.len + 1) // +1 for the external limb this eventually applies to; let's not multiply germs now. for(var/obj/item/organ/internal/O in E.internal_organs) - if(!(O.status & ORGAN_ROBOT)) + if(!O.is_robotic()) O.germ_level += germs E.germ_level += germs diff --git a/code/modules/vr/vr_controller.dm b/code/modules/vr/vr_controller.dm index 45bf2a6cc74..564291b2999 100644 --- a/code/modules/vr/vr_controller.dm +++ b/code/modules/vr/vr_controller.dm @@ -31,12 +31,12 @@ proc/build_virtual_avatar(mob/living/carbon/human/H, location, datum/map_templat var/mob/living/carbon/human/virtual_reality/vr_avatar location = get_turf(location) vr_avatar = new /mob/living/carbon/human/virtual_reality(location) - vr_avatar.set_species(H.species.name) if(istype(H, /mob/living/carbon/human/virtual_reality)) var/mob/living/carbon/human/virtual_reality/V = H vr_avatar.real_me = V.real_me else vr_avatar.real_me = H + vr_avatar.set_species(H.dna.species.type) vr_avatar.dna = H.dna.Clone() vr_avatar.name = H.name vr_avatar.real_name = H.real_name diff --git a/config/example/config.txt b/config/example/config.txt index 46d03c48aaa..84e67d5f127 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -37,6 +37,9 @@ LOG_SAY ## log admin actions LOG_ADMIN +## log admin chat +LOG_ADMINCHAT + ## log client access (logon/logoff) LOG_ACCESS diff --git a/config/names/diona.txt b/config/names/diona.txt deleted file mode 100644 index 3eb4b5f4498..00000000000 --- a/config/names/diona.txt +++ /dev/null @@ -1,13 +0,0 @@ -Blade of Grass Bent Before Wind -Glimmer Of The Stars -The Ripple Of the Waves -Colors Of Dusk -The Still Of Night -Silence Of The Wind -Gentle Breeze of the Summer Wind -Glistening Water under the Blazing Sun -Child of the Scorching Sun -Blessed Plant-ling of Eternal Fields -Grass-walker of the Soothing Plains -Element of the Undying Fiona -Spawn of Mother Nature's Busum \ No newline at end of file diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index f3fe28315f6..234c5ac2274 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -342,7 +342,8 @@ h1.alert, h2.alert {color: #000000;} .clown {color: #ff0000;} .shadowling {color: #3b2769;} .vulpkanin {color: #B97A57;} -.abductor {color: #800080;} +.abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} .rough {font-family: 'Trebuchet MS', cursive, sans-serif;} .say_quote {font-family: Georgia, Verdana, sans-serif;} .cult {color: #800080; font-weight: bold; font-style: italic;} diff --git a/html/changelog.html b/html/changelog.html index 7f3d57e8808..43b82bb7b82 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,272 @@ -->
    +

    30 July 2018

    +

    Tails2091 updated:

    +
      +
    • Changed wannabe for loop to a real for loop.
    • +
    + +

    28 July 2018

    +

    KasparoVy updated:

    +
      +
    • You can now safely augment the heads of pointy-snooted Unathi, although your mileage may vary.
    • +
    + +

    27 July 2018

    +

    AffectedArc07 updated:

    +
      +
    • You can no longer use embeds in NTSL
    • +
    +

    Crazylemon64 updated:

    +
      +
    • Space hotel is back in business
    • +
    • Non-hotel SNPCs work again
    • +
    +

    Fox McCloud updated:

    +
      +
    • Extract posibrains should have the correct names now
    • +
    • Abductors can now purchase a mind device to speak into crewmembers minds or give directives to abductees
    • +
    • Abductors now have their own versions of the FixOVein, Bonesetter, and Bonegel. Credit to Triiodine for the sprites
    • +
    • Adds a new electric shock and chemical gland for abductors
    • +
    • viral gland generates random viruses and egg laying gland eggs now have random reagents in them
    • +
    +

    variableundefined updated:

    +
      +
    • Cyborg Analyzer no longer rounds off the damage number it displays.
    • +
    + +

    25 July 2018

    +

    variableundefined updated:

    +
      +
    • Fixes runtime error from medical kit change
    • +
    + +

    24 July 2018

    +

    Kyep updated:

    +
      +
    • Number of roundstart atmos suits in atmos increased from 2 to 4.
    • +
    + +

    22 July 2018

    +

    Fox McCloud updated:

    +
      +
    • Fixes monkeys not having their own HUD
    • +
    • Fixes monkey to human transformations missing their HUD
    • +
    • Fixes changing species unequipping items
    • +
    • Fixes organs not being rejuvinated properly by mitocholide
    • +
    • Fixes shadowlings not being forced to hatch
    • +
    • Having a robotic head will allow you to use buzz, ping, beep, and the likes
    • +
    • Claw sharpening now works
    • +
    • Abductors have their own headset instead of a syndicate one
    • +
    • Can put monkeys in the gibber
    • +
    • gibbing some species will now generate different types of hides (monkeys give monkey hides, unathi give lizard hides, the likes)
    • +
    • fixes Vox name generation based on the wrong syllables
    • +
    • consolidates diona name lists; you'll no longer be asked to rename your Diona when you start the shift
    • +
    • botany grown diona can no longer rename themselves (as is consistent with ghost roles)
    • +
    • Fixes DNA scrambler so it gives a proper randomized species name
    • +
    • Fixed an edge case were Vox would have a permanent nitrogen alert
    • +
    • Fixes operatives being bald most of the time
    • +
    • Adds beesplosion chemical reaction
    • +
    +

    and taukausanake updated:

    +
      +
    • Swarmers can no longer destroy active clone pods.
    • +
    + +

    17 July 2018

    +

    Citinited updated:

    +
      +
    • volume pumps can be dispensed by the RPD again
    • +
    +

    datlo updated:

    +
      +
    • Provided abductors with an infection free surgery table.
    • +
    + +

    16 July 2018

    +

    Citinited updated:

    +
      +
    • RPD behaviour has been slightly tweaked - for example you can now rotate / flip / delete individual pipes by clicking on them without affecting other pipes on that tile.
    • +
    +

    Fox McCloud updated:

    +
      +
    • Fixes hand labelers not being able to label storage objects
    • +
    • Cameras can now be destroyed with weapons that have a force of 12 or greater
    • +
    • Cameras have 2 wires as opposed to 6; camera focus and power wires still remain
    • +
    • You can use hand labelers on reagent containers now
    • +
    + +

    14 July 2018

    +

    Anasari updated:

    +
      +
    • Assuming there is heal left, bandages and ointments used on limbs now heal both the limb and the hand / foot. Bandages and ointments used on the torso now heal head, arms, and lower body. The one on lower body heals the legs too.
    • +
    +

    Aurorablade updated:

    +
      +
    • Adds Spess Koi and related event.
    • +
    +

    Citinited updated:

    +
      +
    • The tachyon-doppler array now has a logging interface, and can print off stored explosive logs. Brag to your friends about your bomb-making skills!
    • +
    +

    Fox McCloud updated:

    +
      +
    • Robotic brains have their own unique sprite and full flavortext's now
    • +
    • Fixed a bug where IRC's would have IPC names
    • +
    + +

    11 July 2018

    +

    Alffd updated:

    +
      +
    • Updates SM engine to modern standards
    • +
    • Ports SM monitoring system from Bay and TG
    • +
    • Adds station wide radiation alarm when crystal/shard goes critical
    • +
    • Tesla zapping
    • +
    +

    Citinited updated:

    +
      +
    • Fortune cookies now drop random fortunes if cooked with a blank piece of paper.
    • +
    +

    Fox McCloud updated:

    +
      +
    • Adds constructable Integrated Robotic Chassis
    • +
    • Adds surgery to customize existing robotic limb appearances
    • +
    • Positronic brains renamed to robotic brains
    • +
    +

    FreeStylaLT updated:

    +
      +
    • Added a Harmonica to Perma Brig
    • +
    +

    datlo updated:

    +
      +
    • Replaced instances of "Human" in ion laws by "Crew".
    • +
    • Fixed the ability of Service Borgs to spawn items on floors. Dosh!
    • +
    + +

    10 July 2018

    +

    Fox McCloud updated:

    +
      +
    • Can no longer take assisted organs at round-start (mechanical organs are still a go, but renamed to cybernetic organs)
    • +
    • Can now start the round with cybernetic lungs, liver, and kidneys
    • +
    • Can produce cybernetic eyes at R&D and mechfabs
    • +
    • Cybernetic internal organs no longer take reduced damage (this does not apply to augments)
    • +
    • Cybernetic internal organs can be rendered inoperable (this does not apply to augments)
    • +
    • Fixes mitocholide/oculine healing damage on cybernetic organs
    • +
    • Fixes being able to restart a dead heart in your hands or with a defib
    • +
    + +

    09 July 2018

    +

    Fox McCloud updated:

    +
      +
    • Enabled augmentation of the head
    • +
    • Adds cybernetic heart, lungs, liver, and kidneys to R&D and Robotics; also adds cybernetic upgraded lungs
    • +
    • Heads are no longer vital organs, but brains still are
    • +
    + +

    07 July 2018

    +

    Fox McCloud updated:

    +
      +
    • Stechkin pistols in maintenance no longer spawn with a broken magazine
    • +
    +

    Kyep updated:

    +
      +
    • Removed PDA chatrooms. NTNet Relay Chatrooms, part of modular computers, still exist.
    • +
    + +

    06 July 2018

    +

    Fox McCloud updated:

    +
      +
    • removes explosive lances
    • +
    +

    datlo updated:

    +
      +
    • Replaced duplicate labor shuttle console on the bridge by a mining shuttle console.
    • +
    + +

    04 July 2018

    +

    Citinited updated:

    +
      +
    • Spelling error in agent IDs
    • +
    + +

    03 July 2018

    +

    MINIMAN10000 updated:

    +
      +
    • Restrained spacepod passanger can now exit pending a 2 minute wait time without moving.
    • +
    + +

    02 July 2018

    +

    Citinited updated:

    +
      +
    • Canisters obey melee cooldown now
    • +
    +

    Crazylemon64 updated:

    +
      +
    • All MMI variants can now install an "MMI radio upgrade" in order to acquire radio capability when outside of any other chassis. It can be installed either directly on the MMI, or through an opened cyborg chassis. This radio can later be removed if desired by using a screwdriver on the MMI.
    • +
    • MMIs can now pull up the direct interface of the radio instead of a single-toggle verb
    • +
    • MMI radio control is now done via action button instead of via verb
    • +
    • The radio MMI no longer exists as a distinct item
    • +
    + +

    01 July 2018

    +

    Anasari updated:

    +
      +
    • Shuttle can be called at 30:00 instead of 25:00 during War Ops.
    • +
    +

    Citinited updated:

    +
      +
    • The chef can now process spaghetti into macaroni, and can make several derivative foodstuffs.
    • +
    +

    datlo updated:

    +
      +
    • Syndicate clowns can now purchase Clown Magboots. Keep honking through slips and atmos!
    • +
    +

    monster860 updated:

    +
      +
    • Adds the mining podbay (again)
    • +
    + +

    30 June 2018

    +

    Citinited updated:

    +
      +
    • Adds the conveyor belt placer and bluespace conveyor belt placer, allowing you to much more easily create conveyor belts. The former can be gotten at any autolathe, the latter must be researched first.
    • +
    • Use a conveyor belt lever on aforementioned item to link all belts inside the placer with that lever.
    • +
    + +

    27 June 2018

    +

    MINIMAN10000 updated:

    +
      +
    • Containment emitters
    • +
    • deferred processing of SMES
    • +
    + +

    26 June 2018

    +

    Alffd updated:

    +
      +
    • Additional logic to atmos throwing.
    • +
    + +

    23 June 2018

    +

    matt81093 updated:

    +
      +
    • death squid hitbox position
    • +
    + +

    19 June 2018

    +

    Anasari updated:

    +
      +
    • Gloves of the north star is now categorized under highly visible and dangerous weapon instead of pointless badassery. (Because it's actually good)
    • +
    +

    Fox McCloud updated:

    +
      +
    • Can cast spells on CentComm z-level during ragin' mages
    • +
    +

    MINIMAN10000 updated:

    +
      +
    • Cardboard drop counts
    • +
    +

    17 June 2018

    Fox McCloud updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 15d5824d09f..018eeee7a53 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -6520,3 +6520,190 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: It no longer snows on away missions variableundefined: - tweak: Nuclear challenge time limit now depends on round start time. +2018-06-19: + Anasari: + - tweak: Gloves of the north star is now categorized under highly visible and dangerous + weapon instead of pointless badassery. (Because it's actually good) + Fox McCloud: + - tweak: Can cast spells on CentComm z-level during ragin' mages + MINIMAN10000: + - bugfix: Cardboard drop counts +2018-06-23: + matt81093: + - bugfix: death squid hitbox position +2018-06-26: + Alffd: + - rscadd: Additional logic to atmos throwing. +2018-06-27: + MINIMAN10000: + - bugfix: Containment emitters + - rscadd: deferred processing of SMES +2018-06-30: + Citinited: + - rscadd: Adds the conveyor belt placer and bluespace conveyor belt placer, allowing + you to much more easily create conveyor belts. The former can be gotten at any + autolathe, the latter must be researched first. + - rscadd: Use a conveyor belt lever on aforementioned item to link all belts inside + the placer with that lever. +2018-07-01: + Anasari: + - tweak: Shuttle can be called at 30:00 instead of 25:00 during War Ops. + Citinited: + - rscadd: The chef can now process spaghetti into macaroni, and can make several + derivative foodstuffs. + datlo: + - rscadd: Syndicate clowns can now purchase Clown Magboots. Keep honking through + slips and atmos! + monster860: + - rscadd: Adds the mining podbay (again) +2018-07-02: + Citinited: + - tweak: Canisters obey melee cooldown now + Crazylemon64: + - rscadd: All MMI variants can now install an "MMI radio upgrade" in order to acquire + radio capability when outside of any other chassis. It can be installed either + directly on the MMI, or through an opened cyborg chassis. This radio can later + be removed if desired by using a screwdriver on the MMI. + - rscadd: MMIs can now pull up the direct interface of the radio instead of a single-toggle + verb + - rscadd: MMI radio control is now done via action button instead of via verb + - rscdel: The radio MMI no longer exists as a distinct item +2018-07-03: + MINIMAN10000: + - tweak: Restrained spacepod passanger can now exit pending a 2 minute wait time + without moving. +2018-07-04: + Citinited: + - bugfix: Spelling error in agent IDs +2018-07-06: + Fox McCloud: + - rscdel: removes explosive lances + datlo: + - bugfix: Replaced duplicate labor shuttle console on the bridge by a mining shuttle + console. +2018-07-07: + Fox McCloud: + - tweak: Stechkin pistols in maintenance no longer spawn with a broken magazine + Kyep: + - rscdel: Removed PDA chatrooms. NTNet Relay Chatrooms, part of modular computers, + still exist. +2018-07-09: + Fox McCloud: + - tweak: Enabled augmentation of the head + - rscadd: Adds cybernetic heart, lungs, liver, and kidneys to R&D and Robotics; + also adds cybernetic upgraded lungs + - tweak: Heads are no longer vital organs, but brains still are +2018-07-10: + Fox McCloud: + - rscdel: Can no longer take assisted organs at round-start (mechanical organs are + still a go, but renamed to cybernetic organs) + - rscadd: Can now start the round with cybernetic lungs, liver, and kidneys + - rscadd: Can produce cybernetic eyes at R&D and mechfabs + - tweak: Cybernetic internal organs no longer take reduced damage (this does not + apply to augments) + - tweak: Cybernetic internal organs can be rendered inoperable (this does not apply + to augments) + - bugfix: Fixes mitocholide/oculine healing damage on cybernetic organs + - bugfix: Fixes being able to restart a dead heart in your hands or with a defib +2018-07-11: + Alffd: + - bugfix: Updates SM engine to modern standards + - rscadd: Ports SM monitoring system from Bay and TG + - rscadd: Adds station wide radiation alarm when crystal/shard goes critical + - rscadd: Tesla zapping + Citinited: + - rscadd: Fortune cookies now drop random fortunes if cooked with a blank piece + of paper. + Fox McCloud: + - rscadd: Adds constructable Integrated Robotic Chassis + - rscadd: Adds surgery to customize existing robotic limb appearances + - tweak: Positronic brains renamed to robotic brains + FreeStylaLT: + - rscadd: Added a Harmonica to Perma Brig + datlo: + - bugfix: Replaced instances of "Human" in ion laws by "Crew". + - bugfix: Fixed the ability of Service Borgs to spawn items on floors. Dosh! +2018-07-14: + Anasari: + - tweak: Assuming there is heal left, bandages and ointments used on limbs now heal + both the limb and the hand / foot. Bandages and ointments used on the torso + now heal head, arms, and lower body. The one on lower body heals the legs too. + Aurorablade: + - rscadd: Adds Spess Koi and related event. + Citinited: + - tweak: The tachyon-doppler array now has a logging interface, and can print off + stored explosive logs. Brag to your friends about your bomb-making skills! + Fox McCloud: + - tweak: Robotic brains have their own unique sprite and full flavortext's now + - bugfix: Fixed a bug where IRC's would have IPC names +2018-07-16: + Citinited: + - tweak: RPD behaviour has been slightly tweaked - for example you can now rotate + / flip / delete individual pipes by clicking on them without affecting other + pipes on that tile. + Fox McCloud: + - bugfix: Fixes hand labelers not being able to label storage objects + - rscadd: Cameras can now be destroyed with weapons that have a force of 12 or greater + - tweak: Cameras have 2 wires as opposed to 6; camera focus and power wires still + remain + - tweak: You can use hand labelers on reagent containers now +2018-07-17: + Citinited: + - bugfix: volume pumps can be dispensed by the RPD again + datlo: + - rscadd: Provided abductors with an infection free surgery table. +2018-07-22: + Fox McCloud: + - bugfix: Fixes monkeys not having their own HUD + - bugfix: Fixes monkey to human transformations missing their HUD + - bugfix: Fixes changing species unequipping items + - bugfix: Fixes organs not being rejuvinated properly by mitocholide + - bugfix: Fixes shadowlings not being forced to hatch + - rscadd: Having a robotic head will allow you to use buzz, ping, beep, and the + likes + - tweak: Claw sharpening now works + - rscadd: Abductors have their own headset instead of a syndicate one + - tweak: Can put monkeys in the gibber + - rscadd: gibbing some species will now generate different types of hides (monkeys + give monkey hides, unathi give lizard hides, the likes) + - bugfix: fixes Vox name generation based on the wrong syllables + - tweak: consolidates diona name lists; you'll no longer be asked to rename your + Diona when you start the shift + - rscdel: botany grown diona can no longer rename themselves (as is consistent with + ghost roles) + - bugfix: Fixes DNA scrambler so it gives a proper randomized species name + - bugfix: Fixed an edge case were Vox would have a permanent nitrogen alert + - bugfix: Fixes operatives being bald most of the time + - rscadd: Adds beesplosion chemical reaction + and taukausanake: + - tweak: Swarmers can no longer destroy active clone pods. +2018-07-24: + Kyep: + - tweak: Number of roundstart atmos suits in atmos increased from 2 to 4. +2018-07-25: + variableundefined: + - bugfix: Fixes runtime error from medical kit change +2018-07-27: + AffectedArc07: + - bugfix: You can no longer use embeds in NTSL + Crazylemon64: + - rscadd: Space hotel is back in business + - bugfix: Non-hotel SNPCs work again + Fox McCloud: + - bugfix: Extract posibrains should have the correct names now + - rscadd: Abductors can now purchase a mind device to speak into crewmembers minds + or give directives to abductees + - rscadd: Abductors now have their own versions of the FixOVein, Bonesetter, and + Bonegel. Credit to Triiodine for the sprites + - rscadd: Adds a new electric shock and chemical gland for abductors + - tweak: viral gland generates random viruses and egg laying gland eggs now have + random reagents in them + variableundefined: + - tweak: Cyborg Analyzer no longer rounds off the damage number it displays. +2018-07-28: + KasparoVy: + - bugfix: You can now safely augment the heads of pointy-snooted Unathi, although + your mileage may vary. +2018-07-30: + Tails2091: + - bugfix: Changed wannabe for loop to a real for loop. diff --git a/icons/mob/ears.dmi b/icons/mob/ears.dmi index 13d5981c458..597029a456c 100644 Binary files a/icons/mob/ears.dmi and b/icons/mob/ears.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index 7fc4aa0a9ba..b1a26763fbd 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 760e82458d8..b4dea0cfa36 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index bc282c185d8..1455fa9ab0e 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 8b41a0ec07d..e9d610d754d 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index 7bcd0607116..f556369cf69 100644 Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 720fafd8847..8593012e528 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index c3942e015de..7143a55ab59 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/ties_overlay.dmi b/icons/obj/clothing/ties_overlay.dmi index a17fed4818c..37bbfbf5d25 100644 Binary files a/icons/obj/clothing/ties_overlay.dmi and b/icons/obj/clothing/ties_overlay.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 8296c4ceb7d..c27c19ac3aa 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/fish_items.dmi b/icons/obj/fish_items.dmi index fd8eea36540..76a9486fee6 100644 Binary files a/icons/obj/fish_items.dmi and b/icons/obj/fish_items.dmi differ diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi index 6825f6c652d..ff25b77ab45 100644 Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ diff --git a/icons/obj/food/custom.dmi b/icons/obj/food/custom.dmi new file mode 100644 index 00000000000..42d28790790 Binary files /dev/null and b/icons/obj/food/custom.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 3395b112947..487b36d3e97 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/food/pasta.dmi b/icons/obj/food/pasta.dmi new file mode 100644 index 00000000000..0179c3f5cc7 Binary files /dev/null and b/icons/obj/food/pasta.dmi differ diff --git a/icons/obj/food/pizza.dmi b/icons/obj/food/pizza.dmi new file mode 100644 index 00000000000..c26e792f2a0 Binary files /dev/null and b/icons/obj/food/pizza.dmi differ diff --git a/icons/obj/modular_console.dmi b/icons/obj/modular_console.dmi index 85d6026617f..fba8ad59431 100644 Binary files a/icons/obj/modular_console.dmi and b/icons/obj/modular_console.dmi differ diff --git a/icons/obj/modular_laptop.dmi b/icons/obj/modular_laptop.dmi index 2daeee0c7a4..d04e68c2041 100644 Binary files a/icons/obj/modular_laptop.dmi and b/icons/obj/modular_laptop.dmi differ diff --git a/icons/obj/modular_tablet.dmi b/icons/obj/modular_tablet.dmi index 2438f375f65..a6e3223a8d0 100644 Binary files a/icons/obj/modular_tablet.dmi and b/icons/obj/modular_tablet.dmi differ diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index 0a269e0d8b7..ab76789a0f0 100644 Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ diff --git a/icons/obj/pipes/disposal.dmi b/icons/obj/pipes/disposal.dmi index 707a064dd94..83440fc1b52 100644 Binary files a/icons/obj/pipes/disposal.dmi and b/icons/obj/pipes/disposal.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 39df3590359..f388b9384fb 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index a47c56cba87..b3723f9a53d 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/program_icons/smmon_0.gif b/icons/program_icons/smmon_0.gif new file mode 100644 index 00000000000..7b716c4e1c5 Binary files /dev/null and b/icons/program_icons/smmon_0.gif differ diff --git a/icons/program_icons/smmon_1.gif b/icons/program_icons/smmon_1.gif new file mode 100644 index 00000000000..bbe319b820f Binary files /dev/null and b/icons/program_icons/smmon_1.gif differ diff --git a/icons/program_icons/smmon_2.gif b/icons/program_icons/smmon_2.gif new file mode 100644 index 00000000000..9c58edd340e Binary files /dev/null and b/icons/program_icons/smmon_2.gif differ diff --git a/icons/program_icons/smmon_3.gif b/icons/program_icons/smmon_3.gif new file mode 100644 index 00000000000..dc7c8734eed Binary files /dev/null and b/icons/program_icons/smmon_3.gif differ diff --git a/icons/program_icons/smmon_4.gif b/icons/program_icons/smmon_4.gif new file mode 100644 index 00000000000..8a75e6e1184 Binary files /dev/null and b/icons/program_icons/smmon_4.gif differ diff --git a/icons/program_icons/smmon_5.gif b/icons/program_icons/smmon_5.gif new file mode 100644 index 00000000000..59356beda0a Binary files /dev/null and b/icons/program_icons/smmon_5.gif differ diff --git a/icons/program_icons/smmon_6.gif b/icons/program_icons/smmon_6.gif new file mode 100644 index 00000000000..aea2f87921d Binary files /dev/null and b/icons/program_icons/smmon_6.gif differ diff --git a/nano/templates/doppler_array.tmpl b/nano/templates/doppler_array.tmpl new file mode 100644 index 00000000000..d3bb40744b2 --- /dev/null +++ b/nano/templates/doppler_array.tmpl @@ -0,0 +1,25 @@ +

      Logged explosions:

      +{{if data.explosion_data == 0}} +

      No explosions logged this shift.

      +{{else}} +
      + Time logged + Epicenter + Actual size + Theoretical size +
      +
      + {{for data.explosion_data}} +
      + + {{:value.logged_time}} + {{:value.epicenter}} + {{:value.actual_size_message}} + {{:value.theoretical_size_message}} + {{:helper.link("Delete", "trash", {"log_to_delete": value.unique_datum_id})}} + +
      + {{/for}} +
      + {{:helper.link("Print all logs", "print", {"print_logs": 'yes'}, data.printing ? 'disabled' : null)}} +{{/if}} diff --git a/nano/templates/pda_chatroom.tmpl b/nano/templates/pda_chatroom.tmpl deleted file mode 100644 index ae0d8e7f35b..00000000000 --- a/nano/templates/pda_chatroom.tmpl +++ /dev/null @@ -1,85 +0,0 @@ - -
      -
      - Chat Functions: -
      -
      - {{:helper.link(data.silent == 1 ? 'Ringer: Off' : 'Ringer: On', data.silent == 1 ? 'volume-off' : 'volume-up', {'choice' : "Toggle Ringer"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link(data.toff == 1 ? 'Notifications: Off' : 'Notifications: On',data.toff == 1 ? 'close' : 'check', {'choice' : "Toggle Chatroom"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link('Set Ringtone', 'bell-o', {'choice' : "Ringtone"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link('New Room', 'plus', {'choice' : "New Room"}, null, 'pdalink fixedLeftWide')}} -
      -
      - -
      - {{if data.no_server}} -

      ERROR: Messaging server is not responding.

      - {{:helper.link('Reconnect', 'refresh', {'choice' : "Reconnect"}, null, 'pdalink fixedLeftWidest')}} - {{else data.room}} - {{if data.inviting}} -

      Invite whom to #{{:data.room}}?

      - {{for data.people}} - {{:helper.link(value.name, 'user-plus', {'choice': "Invite PDA", 'user': value.ref}, null, 'pdalink fixedLeftWidest')}} - {{empty}} - No other people found. - {{/for}} - {{else}} -

      #{{:data.room}} – {{:data.topic}}

      -
      -
      - Room Functions: -
      -
      - {{:helper.link('Invite', 'user-plus', {'choice' : "Invite"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link('Change Topic', 'tag', {'choice' : "Topic"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link('Leave Channel', 'user-times', {'choice' : "Leave"}, null, 'pdalink fixedLeftWide')}} - {{:helper.link(data.auto_scroll ? 'Autoscroll: On' : 'Autoscroll: Off', 'level-down', {'choice' : "Autoscroll"}, null, 'pdalink fixedLeftWide')}} -
      -
      -
      -
      - {{var prevName = "";}} - {{for data.history}} -
      -
      {{:value.username!=prevName ? value.username : " "}}
      -
      - {{:value.message}} -
      -
      - {{prevName = value.username;}} - {{/for}} -
      -
      - {{:helper.link('Post', 'comment', {'choice' : "Post"}, null, 'pdalink fixedLeftWidest')}} -
      -
      -
      - {{for data.users}} -
      -
      {{:value}}
      -
      - {{/for}} -
      - - {{/if}} - {{else}} -

      Rooms

      - {{for data.rooms}} -
      - {{:helper.link(value.name, 'arrow-circle-down', {'choice' : "Join", 'room' : value.ref}, null, 'pdalink fixedLeftWidest')}} -
      - {{empty}} - No rooms located. - {{/for}} - {{/if}} -
      \ No newline at end of file diff --git a/nano/templates/rpd.tmpl b/nano/templates/rpd.tmpl index bd92b91c979..6a9c2ccb517 100644 --- a/nano/templates/rpd.tmpl +++ b/nano/templates/rpd.tmpl @@ -4,101 +4,104 @@ Used In File(s): /code/game/objects/items/weapons/rpd.dm

      Mode:

      {{for data.mainmenu}} - {{:helper.link(String(value.category), String(value.icon), {"mode": Number(value.mode)}, data.mode == Number(value.mode) ? "linkOn" : null)}} + {{:helper.link(value.category, value.icon, {mode: value.mode}, data.mode == value.mode ? "linkOn" : null)}} {{/for}}
      {{if data.mode == 1}}

      Pipe type:

      {{for data.pipemenu}} - {{:helper.link(String(value.pipecategory), null, {"pipetype": Number(value.pipemode)}, data.pipetype == Number(value.pipemode) ? "linkOn" : null)}} + {{:helper.link(value.category, null, {pipe_category: value.pipemode}, data.pipe_category == value.pipemode ? "linkOn" : null)}} {{/for}}

      Available pipes:

      {{for data.pipelist}} - {{if value.category == data.pipetype}} -
      {{:helper.link(String(value.pipename), "arrow-right", {"whatpipe": Number(value.id)}, data.whatpipe == Number(value.id) ? "linkOn" : null)}}
      + {{if value.pipe_type == 1 && value.pipe_category == data.pipe_category}} +
      {{:helper.link(value.pipe_name, "arrow-right", {whatpipe: value.pipe_id}, data.whatpipe == value.pipe_id ? "linkOn" : null)}}
      {{/if}} {{/for}}
      {{for data.pipelist}} + {{if value.pipe_type != 1 || value.pipe_id != data.whatpipe || value.orientations == 1}} + {{continue;}} + {{/if}}
      - {{if value.id == data.whatpipe && value.orientations != 1}} -
      - {{:helper.link("Orient automatically", null, {"iconrotation": 0}, data.iconrotation == 0 ? "linkOn" : null)}} -
      - {{/if}} - {{if value.id == data.whatpipe && value.orientations != 1 && value.bendy != 1}} +
      + {{:helper.link("Orient automatically", null, {iconrotation: 0}, data.iconrotation == 0 ? "linkOn" : null)}} +
      + {{if value.bendy}}
      - {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 1}, data.iconrotation == 1 ? "linkOn" : null)}} +
      - {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} - -
      - {{/if}} - {{if value.id == data.whatpipe && value.orientations == 4 && value.bendy != 1}} -
      - {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 4}, data.iconrotation == 4 ? "linkOn" : null)}} +
      - {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} - -
      - {{/if}} - {{if value.id == data.whatpipe && value.bendy == 1}} -
      - {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 2}, data.iconrotation == 2 ? "linkOn" : null)}} +
      - {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 8}, data.iconrotation == 8 ? "linkOn" : null)}} + +
      + {{else}} +
      + {{:helper.link("", "arrow-right", {iconrotation: 1}, data.iconrotation == 1 ? "linkOn" : null)}} +
      - {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} - -
      -
      - {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 4}, data.iconrotation == 4 ? "linkOn" : null)}} +
      + {{if value.orientations == 4}} +
      + {{:helper.link("", "arrow-right", {iconrotation: 2}, data.iconrotation == 2 ? "linkOn" : null)}} + +
      +
      + {{:helper.link("", "arrow-right", {iconrotation: 8}, data.iconrotation == 8 ? "linkOn" : null)}} + +
      + {{/if}} {{/if}}
      {{/for}} {{else data.mode == 2}}

      Available pipes:

      - {{for data.dpipelist}} -
      {{:helper.link(String(value.pipename), "arrow-right", {"whatdpipe": Number(value.id)}, data.whatdpipe == Number(value.id) ? "linkOn" : null)}}
      + {{for data.pipelist}} + {{if value.pipe_type == 2}} +
      {{:helper.link(value.pipe_name, "arrow-right", {whatdpipe: value.pipe_id}, data.whatdpipe == value.pipe_id ? "linkOn" : null)}}
      + {{/if}} {{/for}}
      - {{for data.dpipelist}} + {{for data.pipelist}} + {{if value.pipe_type != 2 || value.pipe_id != data.whatdpipe || value.orientations == 1}} + {{continue;}} + {{/if}}
      - {{if value.id == data.whatdpipe && value.orientations != 1}} -
      - {{:helper.link("Orient automatically", null, {"iconrotation": 0}, data.iconrotation == 0 ? "linkOn" : null)}} +
      + {{:helper.link("Orient automatically", null, {iconrotation: 0}, data.iconrotation == 0 ? "linkOn" : null)}} +
      +
      + {{:helper.link("", "arrow-right", {iconrotation: 1}, data.iconrotation == 1 ? "linkOn" : null)}} + +
      +
      + {{:helper.link("", "arrow-right", {iconrotation: 4}, data.iconrotation == 4 ? "linkOn" : null)}} + +
      + {{if value.orientations == 4}} +
      + {{:helper.link("", "arrow-right", {iconrotation: 2}, data.iconrotation == 2 ? "linkOn" : null)}} +
      - {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} - -
      -
      - {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} - -
      - {{/if}} - {{if value.id == data.whatdpipe && value.orientations == 4}} -
      - {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} - -
      -
      - {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 8}, data.iconrotation == 8 ? "linkOn" : null)}} +
      {{/if}}
      @@ -109,4 +112,4 @@ Used In File(s): /code/game/objects/items/weapons/rpd.dm

      Device ready to flip loose pipes...

      {{else data.mode == 5}}

      Device ready to eat loose pipes...

      -{{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/supermatter_monitor.tmpl b/nano/templates/supermatter_monitor.tmpl new file mode 100644 index 00000000000..3bc87984d79 --- /dev/null +++ b/nano/templates/supermatter_monitor.tmpl @@ -0,0 +1,111 @@ +{{if data.active}} + {{:helper.link('Back to Menu', null, {'clear' : 1})}}
      +
      +
      + Core Integrity: +
      +
      + {{:helper.displayBar(data.SM_integrity, 0, 100, (data.SM_integrity == 100) ? 'good' : (data.SM_integrity >= 50) ? 'average' : 'bad')}} {{:data.SM_integrity}}% +
      +
      + Relative EER: +
      +
      + {{if data.SM_power > 300}} + {{:data.SM_power}} MeV/cm3 + {{else data.SM_power > 150}} + {{:data.SM_power}} MeV/cm3 + {{else}} + {{:data.SM_power}} MeV/cm3 + {{/if}} +
      +
      + Temperature: +
      +
      + {{if data.SM_ambienttemp > 5000}} + {{:data.SM_ambienttemp}} K + {{else data.SM_ambienttemp > 4000}} + {{:data.SM_ambienttemp}} K + {{else}} + {{:data.SM_ambienttemp}} K + {{/if}} +
      +
      + Pressure: +
      +
      + {{if data.SM_ambientpressure > 10000}} + {{:data.SM_ambientpressure}} kPa + {{else data.SM_ambientpressure > 5000}} + {{:data.SM_ambientpressure}} kPa + {{else}} + {{:data.SM_ambientpressure}} kPa + {{/if}} +
      +
      +

      +
      + Gas Composition: +
      +
      +
      +
      + O2: +
      +
      + {{:data.SM_gas_O2}} % +
      +
      + CO2: +
      +
      + {{:data.SM_gas_CO2}} % +
      +
      + N2: +
      +
      + {{:data.SM_gas_N2}} % +
      +
      + PL: +
      +
      + {{:data.SM_gas_PL}} % +
      +
      + OTHER: +
      +
      + {{:data.SM_gas_OTHER}} % +
      +
      +
      +
      +{{else}} + {{:helper.link('Refresh', null, {'refresh' : 1})}}
      + {{for data.supermatters}} +
      +
      + Area: +
      +
      + {{:value.area_name}} +
      +
      + Integrity: +
      +
      + {{:value.integrity}} % +
      +
      + Options: +
      +
      + {{:helper.link('View Details', null, {'set' : value.uid})}} +
      +
      + {{/for}} +{{/if}} diff --git a/paradise.dme b/paradise.dme index 095e5ad2a78..96675812fdb 100644 --- a/paradise.dme +++ b/paradise.dme @@ -45,6 +45,7 @@ #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\mobs.dm" #include "code\__DEFINES\pda.dm" +#include "code\__DEFINES\pipes.dm" #include "code\__DEFINES\preferences.dm" #include "code\__DEFINES\process_scheduler.dm" #include "code\__DEFINES\qdel.dm" @@ -101,6 +102,7 @@ #include "code\_globalvars\station.dm" #include "code\_globalvars\unused.dm" #include "code\_globalvars\lists\flavor_misc.dm" +#include "code\_globalvars\lists\fortunes.dm" #include "code\_globalvars\lists\misc.dm" #include "code\_globalvars\lists\mobs.dm" #include "code\_globalvars\lists\names.dm" @@ -230,6 +232,7 @@ #include "code\datums\mixed.dm" #include "code\datums\mutable_appearance.dm" #include "code\datums\periodic_news.dm" +#include "code\datums\pipe_datums.dm" #include "code\datums\progressbar.dm" #include "code\datums\recipe.dm" #include "code\datums\ruins.dm" @@ -469,8 +472,10 @@ #include "code\game\gamemodes\malfunction\Malf_Modules.dm" #include "code\game\gamemodes\meteor\meteor.dm" #include "code\game\gamemodes\meteor\meteors.dm" +#include "code\game\gamemodes\miniantags\abduction\abductee_objectives.dm" #include "code\game\gamemodes\miniantags\abduction\abduction.dm" #include "code\game\gamemodes\miniantags\abduction\abduction_gear.dm" +#include "code\game\gamemodes\miniantags\abduction\abduction_outfits.dm" #include "code\game\gamemodes\miniantags\abduction\abduction_surgery.dm" #include "code\game\gamemodes\miniantags\abduction\gland.dm" #include "code\game\gamemodes\miniantags\abduction\machinery\camera.dm" @@ -1345,6 +1350,7 @@ #include "code\modules\events\immovable_rod.dm" #include "code\modules\events\infestation.dm" #include "code\modules\events\ion_storm.dm" +#include "code\modules\events\koi_mirgration.dm" #include "code\modules\events\mass_hallucination.dm" #include "code\modules\events\meaty_gore.dm" #include "code\modules\events\meaty_ops.dm" @@ -1396,12 +1402,24 @@ #include "code\modules\food_and_drinks\drinks\drinks\drinkingglass.dm" #include "code\modules\food_and_drinks\drinks\drinks\mugs.dm" #include "code\modules\food_and_drinks\drinks\drinks\shotglass.dm" -#include "code\modules\food_and_drinks\food\candy.dm" #include "code\modules\food_and_drinks\food\condiment.dm" #include "code\modules\food_and_drinks\food\customizables.dm" -#include "code\modules\food_and_drinks\food\meat.dm" -#include "code\modules\food_and_drinks\food\seafood.dm" #include "code\modules\food_and_drinks\food\snacks.dm" +#include "code\modules\food_and_drinks\food\foods\baked_goods.dm" +#include "code\modules\food_and_drinks\food\foods\bread.dm" +#include "code\modules\food_and_drinks\food\foods\candy.dm" +#include "code\modules\food_and_drinks\food\foods\desserts.dm" +#include "code\modules\food_and_drinks\food\foods\ethnic.dm" +#include "code\modules\food_and_drinks\food\foods\ingredients.dm" +#include "code\modules\food_and_drinks\food\foods\junkfood.dm" +#include "code\modules\food_and_drinks\food\foods\meat.dm" +#include "code\modules\food_and_drinks\food\foods\misc.dm" +#include "code\modules\food_and_drinks\food\foods\pasta.dm" +#include "code\modules\food_and_drinks\food\foods\pizza.dm" +#include "code\modules\food_and_drinks\food\foods\sandwiches.dm" +#include "code\modules\food_and_drinks\food\foods\seafood.dm" +#include "code\modules\food_and_drinks\food\foods\side_dishes.dm" +#include "code\modules\food_and_drinks\food\foods\soups.dm" #include "code\modules\food_and_drinks\kitchen_machinery\candy_maker.dm" #include "code\modules\food_and_drinks\kitchen_machinery\cereal_maker.dm" #include "code\modules\food_and_drinks\kitchen_machinery\cooker.dm" @@ -1619,7 +1637,8 @@ #include "code\modules\mob\living\carbon\brain\life.dm" #include "code\modules\mob\living\carbon\brain\login.dm" #include "code\modules\mob\living\carbon\brain\MMI.dm" -#include "code\modules\mob\living\carbon\brain\posibrain.dm" +#include "code\modules\mob\living\carbon\brain\MMI_radio.dm" +#include "code\modules\mob\living\carbon\brain\robotic_brain.dm" #include "code\modules\mob\living\carbon\brain\say.dm" #include "code\modules\mob\living\carbon\brain\update_status.dm" #include "code\modules\mob\living\carbon\human\appearance.dm" @@ -1645,15 +1664,28 @@ #include "code\modules\mob\living\carbon\human\interactive\functions.dm" #include "code\modules\mob\living\carbon\human\interactive\interactive.dm" #include "code\modules\mob\living\carbon\human\interactive\prefabs.dm" +#include "code\modules\mob\living\carbon\human\species\_species.dm" #include "code\modules\mob\living\carbon\human\species\abductor.dm" -#include "code\modules\mob\living\carbon\human\species\apollo.dm" +#include "code\modules\mob\living\carbon\human\species\diona.dm" +#include "code\modules\mob\living\carbon\human\species\drask.dm" #include "code\modules\mob\living\carbon\human\species\golem.dm" +#include "code\modules\mob\living\carbon\human\species\grey.dm" +#include "code\modules\mob\living\carbon\human\species\human.dm" +#include "code\modules\mob\living\carbon\human\species\kidan.dm" +#include "code\modules\mob\living\carbon\human\species\machine.dm" #include "code\modules\mob\living\carbon\human\species\monkey.dm" +#include "code\modules\mob\living\carbon\human\species\nucleation.dm" #include "code\modules\mob\living\carbon\human\species\plasmaman.dm" #include "code\modules\mob\living\carbon\human\species\shadow.dm" +#include "code\modules\mob\living\carbon\human\species\shadowling.dm" #include "code\modules\mob\living\carbon\human\species\skeleton.dm" -#include "code\modules\mob\living\carbon\human\species\species.dm" -#include "code\modules\mob\living\carbon\human\species\station.dm" +#include "code\modules\mob\living\carbon\human\species\skrell.dm" +#include "code\modules\mob\living\carbon\human\species\slime.dm" +#include "code\modules\mob\living\carbon\human\species\tajaran.dm" +#include "code\modules\mob\living\carbon\human\species\unathi.dm" +#include "code\modules\mob\living\carbon\human\species\vox.dm" +#include "code\modules\mob\living\carbon\human\species\vulpkanin.dm" +#include "code\modules\mob\living\carbon\human\species\wryn.dm" #include "code\modules\mob\living\carbon\slime\death.dm" #include "code\modules\mob\living\carbon\slime\emote.dm" #include "code\modules\mob\living\carbon\slime\examine.dm" @@ -1852,6 +1884,7 @@ #include "code\modules\modular_computers\file_system\programs\command\comms.dm" #include "code\modules\modular_computers\file_system\programs\engineering\alarm.dm" #include "code\modules\modular_computers\file_system\programs\engineering\power_monitor.dm" +#include "code\modules\modular_computers\file_system\programs\engineering\sm_monitor.dm" #include "code\modules\modular_computers\file_system\programs\generic\configurator.dm" #include "code\modules\modular_computers\file_system\programs\generic\file_browser.dm" #include "code\modules\modular_computers\file_system\programs\generic\ntdownloader.dm" @@ -1923,7 +1956,6 @@ #include "code\modules\pda\app.dm" #include "code\modules\pda\cart.dm" #include "code\modules\pda\cart_apps.dm" -#include "code\modules\pda\chatroom.dm" #include "code\modules\pda\core_apps.dm" #include "code\modules\pda\messenger.dm" #include "code\modules\pda\messenger_plugins.dm" @@ -2073,6 +2105,7 @@ #include "code\modules\reagents\reagent_containers\pill.dm" #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" +#include "code\modules\recycling\belt-placer.dm" #include "code\modules\recycling\conveyor2.dm" #include "code\modules\recycling\disposal-construction.dm" #include "code\modules\recycling\disposal.dm" @@ -2182,8 +2215,13 @@ #include "code\modules\surgery\organs\autoimplanter.dm" #include "code\modules\surgery\organs\blood.dm" #include "code\modules\surgery\organs\body_egg.dm" +#include "code\modules\surgery\organs\eyes.dm" +#include "code\modules\surgery\organs\heart.dm" #include "code\modules\surgery\organs\helpers.dm" +#include "code\modules\surgery\organs\kidneys.dm" +#include "code\modules\surgery\organs\liver.dm" #include "code\modules\surgery\organs\lungs.dm" +#include "code\modules\surgery\organs\mmi_holder.dm" #include "code\modules\surgery\organs\organ.dm" #include "code\modules\surgery\organs\organ_external.dm" #include "code\modules\surgery\organs\organ_icon.dm" diff --git a/sound/creatures/bee.ogg b/sound/creatures/bee.ogg new file mode 100644 index 00000000000..ea8dcc2b369 Binary files /dev/null and b/sound/creatures/bee.ogg differ diff --git a/sound/machines/engine_alert2.ogg b/sound/machines/engine_alert2.ogg new file mode 100644 index 00000000000..83f693617a7 Binary files /dev/null and b/sound/machines/engine_alert2.ogg differ