diff --git a/.github/boring-cyborg.yml b/.github/boring-cyborg.yml index 441c6a60b4..a1dc949a3d 100644 --- a/.github/boring-cyborg.yml +++ b/.github/boring-cyborg.yml @@ -36,6 +36,10 @@ labelPRBasedOnFilePath: "Type: .git or .github": - '.github/**' - '.git/**' + + # Contains changes to the TGUI bundle + "Type: TGUI Bundle": + - 'tgui/public/**' ##### Greetings ######################################################################################################## # Comment to be posted to welcome users when they open their first PR @@ -103,4 +107,4 @@ firstIssueWelcomeComment: > # # It helps avoid multiple heads in alembic migrations in a collaborative development project. # - airflow/migrations/* # - airflow/migrations/**/* -# - airflow/alembic.ini \ No newline at end of file +# - airflow/alembic.ini diff --git a/code/__defines/span_vr.dm b/code/__defines/span_vr.dm index 618fd52b3d..737d1a81ad 100644 --- a/code/__defines/span_vr.dm +++ b/code/__defines/span_vr.dm @@ -40,7 +40,7 @@ #define span_danger(str) ("" + str + "") #define span_warning(str) ("" + str + "") #define span_rose(str) ("" + str + "") -#define span_info(str) ("" + str + "" +#define span_info(str) ("" + str + "") #define span_notice(str) ("" + str + "") #define span_alium(str) ("" + str + "") #define span_cult(str) ("" + str + "") diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index 67d6b6e7d6..f81e48b044 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -111,6 +111,7 @@ #define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message #define NO_STUTTER 256 // No stuttering, slurring, or other speech problems #define ALT_TRANSMIT 512 // Language is not based on vision or sound (Todo: add this into the say code and use it for the rootspeak languages) +#define INAUDIBLE 1024 // Language is not audible (similar to nonverbal) but is still using hearing-based recognition #define SKIN_NORMAL 0 #define SKIN_THREAT 1 diff --git a/code/__defines/species_languages_vr.dm b/code/__defines/species_languages_vr.dm index 32457d9567..1a5fbdab4c 100644 --- a/code/__defines/species_languages_vr.dm +++ b/code/__defines/species_languages_vr.dm @@ -12,6 +12,7 @@ #define LANGUAGE_SPACER "Spacer" #define LANGUAGE_CLOWNISH "Coulrian" #define LANGUAGE_TAVAN "Tavan" +#define LANGUAGE_ECHOSONG "Echo Song" #define LANGUAGE_CHIMPANZEE "Chimpanzee" #define LANGUAGE_NEAERA "Neaera" diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 140f88886d..6cd91a852b 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -138,9 +138,9 @@ Proc for attack log creation, because really why not /proc/get_exposed_defense_zone(var/atom/movable/target) var/obj/item/weapon/grab/G = locate() in target if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people. - return pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg") + return pick(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG) else - return pick("chest", "groin") + return pick(BP_TORSO, BP_GROIN) /proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = FALSE, progress = TRUE, ignore_movement = FALSE, exclusive = FALSE) if(!user || !target) diff --git a/code/datums/supplypacks/atmospherics.dm b/code/datums/supplypacks/atmospherics.dm index a18b630892..e6fb05f220 100644 --- a/code/datums/supplypacks/atmospherics.dm +++ b/code/datums/supplypacks/atmospherics.dm @@ -106,7 +106,7 @@ cost = 35 containertype = /obj/structure/closet/crate/aether containername = "Emergency crate" - +/* /datum/supply_pack/atmos/firefighting name = "Firefighting equipment" contains = list( @@ -118,4 +118,4 @@ ) cost = 35 containertype = /obj/structure/closet/crate/aether - containername = "Firefighting crate" \ No newline at end of file + containername = "Firefighting crate"*/ \ No newline at end of file diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm index ba6a33d48c..40caa4c405 100644 --- a/code/datums/supplypacks/recreation.dm +++ b/code/datums/supplypacks/recreation.dm @@ -35,6 +35,15 @@ containertype = /obj/structure/closet/crate/allico containername = "foam weapon crate" +/datum/supply_pack/recreation/donksoftborg + name = "Donk-Soft Cyborg Blaster Crate" + contains = list( + /obj/item/borg/upgrade/toygun = 2, + ) + cost = 35 + containertype = /obj/structure/closet/crate/allico + containername = "foam weapon crate" + /datum/supply_pack/recreation/donksoftvend name = "Donk-Soft Vendor Crate" contains = list() diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm index 18cc82af76..5c4ddf1a6a 100644 --- a/code/datums/supplypacks/security.dm +++ b/code/datums/supplypacks/security.dm @@ -287,7 +287,7 @@ containertype = /obj/structure/closet/crate/secure/lawson containername = "Riot armor crate" access = access_armory - +/* /datum/supply_pack/security/riot_sprayer name = "Gear - Riot sprayer" contains = list( @@ -296,7 +296,7 @@ cost = 40 containertype = /obj/structure/closet/crate/secure/lawson containername = "Riot sprayer crate" - access = access_armory + access = access_armory*/ /datum/supply_pack/security/ablative_armor name = "Armor - Ablative" diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 3d945e5816..931b298091 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -24,14 +24,16 @@ /proc/randmutb(var/mob/living/M) if(!M) return M.dna.check_integrity() - var/block = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) + //var/block = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) // Most of these are disabled anyway. + var/block = pick(FAKEBLOCK,CLUMSYBLOCK,BLINDBLOCK,DEAFBLOCK) M.dna.SetSEState(block, 1) // Give Random Good Mutation to M /proc/randmutg(var/mob/living/M) if(!M) return M.dna.check_integrity() - var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) + //var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) // Much like above, most of these blocks are disabled in code. + var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,REGENERATEBLOCK,REMOTETALKBLOCK) M.dna.SetSEState(block, 1) // Random Appearance Mutation diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 1f2815426b..58338edf22 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -24,7 +24,7 @@ var/languages=null var/list/flavor=null var/gender = null - var/list/body_descriptors = null + var/list/body_descriptors = null // Guess we'll keep null. var/list/genetic_modifiers = list() // Modifiers with the MODIFIER_GENETIC flag are saved. Note that only the type is saved, not an instance. /datum/dna2/record/proc/GetData() @@ -54,7 +54,8 @@ newrecord.implant = implant newrecord.flavor = flavor newrecord.gender = gender - newrecord.body_descriptors = body_descriptors.Copy() + if(body_descriptors) + newrecord.body_descriptors = body_descriptors.Copy() newrecord.genetic_modifiers = genetic_modifiers.Copy() return newrecord diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 4b69a20878..fb8507074d 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -107,6 +107,9 @@ /obj/machinery/computer/guestpass/attackby(obj/I, mob/user) + if(istype(I, /obj/item/weapon/card/id/guest)) + to_chat(user, "The guest pass terminal denies to accept the guest pass.") + return if(istype(I, /obj/item/weapon/card/id)) if(!giver && user.unEquip(I)) I.forceMove(src) diff --git a/code/game/objects/items/devices/communicator/UI_tgui.dm b/code/game/objects/items/devices/communicator/UI_tgui.dm index 3759d23d4e..d9c4e3b7ce 100644 --- a/code/game/objects/items/devices/communicator/UI_tgui.dm +++ b/code/game/objects/items/devices/communicator/UI_tgui.dm @@ -340,6 +340,11 @@ if("toggle_ringer") ringer = !ringer + if("set_ringer_tone") + var/ringtone = tgui_input_text(usr, "Set Ringer Tone", "Ringer") + if(ringtone) + ttone = ringtone + if("selfie_mode") selfie_mode = !selfie_mode diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index 257694e66d..39411fbacf 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -75,6 +75,20 @@ var/global/list/obj/item/device/communicator/all_communicators = list() // If you turn this on, it changes the way communicator video works. User configurable option. var/selfie_mode = FALSE + // Ringtones! (Based on the PDA ones) + var/ttone = "beep" //The ringtone! + var/list/ttone_sound = list("beep" = 'sound/machines/twobeep.ogg', + "boom" = 'sound/effects/explosionfar.ogg', + "slip" = 'sound/misc/slip.ogg', + "honk" = 'sound/items/bikehorn.ogg', + "SKREE" = 'sound/voice/shriek1.ogg', + // "holy" = 'sound/items/PDA/ambicha4-short.ogg', + "xeno" = 'sound/voice/hiss1.ogg', + "dust" = 'sound/effects/supermatter.ogg', + "spark" = 'sound/effects/sparks4.ogg', + "rad" = 'sound/items/geiger/high1.ogg', + "servo" = 'sound/machines/rig/rigservo.ogg') + // Proc: New() // Parameters: None // Description: Adds the new communicator to the global list of all communicators, sorts the list, obtains a reference to the Exonet node, then tries to diff --git a/code/game/objects/items/devices/communicator/messaging.dm b/code/game/objects/items/devices/communicator/messaging.dm index bfe6d03eab..4195d1db98 100644 --- a/code/game/objects/items/devices/communicator/messaging.dm +++ b/code/game/objects/items/devices/communicator/messaging.dm @@ -76,9 +76,15 @@ return if(ringer) - playsound(src, 'sound/machines/twobeep.ogg', 50, 1) + var/S + if(ttone in ttone_sound) + S = ttone_sound[ttone] + else + S = 'sound/machines/twobeep.ogg' + + playsound(src, S, 50, 1) for (var/mob/O in hearers(2, loc)) - O.show_message(text("[bicon(src)] *beep*")) + O.show_message(text("[bicon(src)] *[ttone]*")) alert_called = 1 update_icon() diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index f110251a17..f743ab87f2 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -43,7 +43,7 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) return ..() var/pai_name = input(user, "Choose your character's name", "Character Name") as text - var/actual_pai_name = sanitize_name(pai_name) + var/actual_pai_name = sanitize_name(pai_name, ,1) if(isnull(actual_pai_name)) return ..() @@ -360,3 +360,40 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard) var/rendered = "[msg]" pai.show_message(rendered, type) ..() + + +// VoreEdit: Living Machine Stuff after this. +// This adds a var and proc for all machines to take a pAI. (The pAI can't control anything, it's just for RP.) +// You need to add usage of the proc to each machine to actually add support. For an example of this, see code\modules\food\kitchen\microwave.dm +/obj/machinery + var/obj/item/device/paicard/paicard = null + +/obj/machinery/proc/insertpai(mob/user, obj/item/device/paicard/card) + //var/obj/item/paicard/card = I + var/mob/living/silicon/pai/AI = card.pai + if(paicard) + to_chat(user, span_notice("This bot is already under PAI Control!")) + return + if(!istype(card)) // TODO: Add sleevecard support. + return + if(!card.pai) + to_chat(user, span_notice("This card does not currently have a personality!")) + return + paicard = card + user.unEquip(card) + card.forceMove(src) + AI.client.eye = src + to_chat(AI, span_notice("Your location is [card.loc].")) // DEBUG. TODO: Make unfolding the chassis trigger an eject. + name = AI.name + to_chat(AI, span_notice("You feel a tingle in your circuits as your systems interface with \the [initial(src.name)].")) + +/obj/machinery/proc/ejectpai(mob/user) + if(paicard) + var/mob/living/silicon/pai/AI = paicard.pai + paicard.forceMove(src.loc) + AI.client.eye = AI + paicard = null + name = initial(src.name) + to_chat(AI, span_notice("You feel a tad claustrophobic as your mind closes back into your card, ejecting from \the [initial(src.name)].")) + if(user) + to_chat(user, span_notice("You eject the card from \the [initial(src.name)].")) \ No newline at end of file diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 374fa4f1aa..dd40b46c32 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -240,7 +240,7 @@ HALOGEN COUNTER - Radcount on mobs continue // Broken limbs if(e.status & ORGAN_BROKEN) - if((e.name in list("l_arm", "r_arm", "l_leg", "r_leg", "head", "chest", "groin")) && (!e.splinted)) + if((e.name in list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG, BP_HEAD, BP_TORSO, BP_GROIN)) && (!e.splinted)) fracture_dat += "Unsecured fracture in subject [e.name]. Splinting recommended for transport.
" else if(advscan >= 1 && showadvscan == 1) fracture_dat += "Bone fractures detected in subject [e.name].
" diff --git a/code/game/objects/items/robot/robot_upgrades_vr.dm b/code/game/objects/items/robot/robot_upgrades_vr.dm index bd9f247ec7..499d535a5c 100644 --- a/code/game/objects/items/robot/robot_upgrades_vr.dm +++ b/code/game/objects/items/robot/robot_upgrades_vr.dm @@ -31,6 +31,30 @@ R.verbs += /mob/living/proc/set_size return 1 +//Robot size gun +/obj/item/borg/upgrade/sizegun + name = "robot mounted size gun" + desc = "A size gun adapted for installation in cyborgs, allows them to turn people pocket-sized among other uses. What could go wrong?" + icon_state = "cyborg_upgrade2" + item_state = "cyborg_upgrade" + require_module = 1 + +/obj/item/borg/upgrade/sizegun/action(var/mob/living/silicon/robot/R) + if(..()) return 0 + + var/obj/item/weapon/gun/energy/sizegun/mounted/T = locate() in R.module + if(!T) + T = locate() in R.module.contents + if(!T) + T = locate() in R.module.modules + if(!T) + R.module.modules += new/obj/item/weapon/gun/energy/sizegun/mounted(R.module) + return 1 + if(T) + to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") + to_chat(usr, "There's no mounting point for the module!") + return 0 + /obj/item/borg/upgrade/bellysizeupgrade name = "robohound capacity expansion module" desc = "Used to double a robohound's belly capacity. This only affects total volume, and won't allow support of more than one patient in case of sleeper bellies. Can only be applied once." @@ -152,6 +176,30 @@ if(!T) R.module.modules += new/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg(R.module) return 1 + if(T) + to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") + to_chat(usr, "There's no mounting point for the module!") + return 0 + +//cyborg foam dart gun +/obj/item/borg/upgrade/toygun + name = "Donk-Soft Cyborg Blaster module" //Cyborg Blaster is capitalized because it's the brand name + desc = "A foam dart gun designed for mounting into cyborgs. It's Donk or Don't! DISCLAIMER: Donk-Soft bears no responsibility for incidents relating to cyborgs becoming too accustomed to shooting at crew. Installation of the Donk-Soft Cyborg Blaster must be performed only by a licensed roboticist." + icon_state = "cyborg_upgrade5" + item_state = "cyborg_upgrade" + require_module = 1 + +/obj/item/borg/upgrade/toygun/action(var/mob/living/silicon/robot/R) + if(..()) return 0 + + var/obj/item/weapon/gun/projectile/cyborgtoy/T = locate() in R.module + if(!T) + T = locate() in R.module.contents + if(!T) + T = locate() in R.module.modules + if(!T) + R.module.modules += new/obj/item/weapon/gun/projectile/cyborgtoy(R.module) + return 1 if(T) to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") to_chat(usr, "There's no mounting point for the module!") diff --git a/code/game/objects/items/selectable_item_vr.dm b/code/game/objects/items/selectable_item_vr.dm new file mode 100644 index 0000000000..33b810d8d7 --- /dev/null +++ b/code/game/objects/items/selectable_item_vr.dm @@ -0,0 +1,48 @@ +/obj/item/selectable_item + name = "selectable item" + desc = "If you find this, you should definitely report this..." + icon = 'icons/obj/items.dmi' + icon_state = "gift1" + var/preface_string = "You are about to select an item. Are you sure you want to use it and select one?" + var/preface_title = "selectable item" + var/selection_string = "Select an item:" + var/selection_title = "Item Selection" + var/list/item_options = list("Gift" = /obj/item/weapon/a_gift, + "Health Analyzer" = /obj/item/device/healthanalyzer) + +/obj/item/selectable_item/attack_self(mob/user as mob) + tgui_alert(user, {"[preface_string]"}, preface_title) + var/chosen_item = tgui_input_list(usr, selection_string, selection_title, item_options) + chosen_item = item_options[chosen_item] + if(chosen_item) + user.drop_item() + var/obj/item/result = new chosen_item(get_turf(user)) + user.put_in_active_hand(result) + result.add_fingerprint(user) + qdel(src) + return + + +/obj/item/selectable_item/chemistrykit + icon = 'icons/obj/chemical_vr.dmi' + icon_state = "chemkit" + selection_string = "Select a chemical:" + selection_title = "Chemical Selection" + +/obj/item/selectable_item/chemistrykit/size + name = "size chemistry kit" + desc = "A pre-arranged home chemistry kit. This one is for rather specific set of size-altering chemicals." + preface_string = "This kit can be used to create a vial of a size-altering chemical, but there's only enough material for one." + preface_title = "Size Chemistry Kit" + item_options = list("Macrocillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/macrocillin, + "Microcillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/microcillin, + "Normalcillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/normalcillin) + +/obj/item/selectable_item/chemistrykit/gender + name = "gender chemistry kit" + desc = "A pre-arranged home chemistry kit. This one is for rather specific set of gender-altering chemicals." + preface_string = "This kit can be used to create a vial of a gender-altering chemical, but there's only enough material for one." + preface_title = "Gender Chemistry Kit" + item_options = list("Androrovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/androrovir, + "Gynorovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/gynorovir, + "Androgynorovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/androgynorovir) \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/egg_vr.dm b/code/game/objects/items/weapons/storage/egg_vr.dm index 0adb9533bf..97da55c4ff 100644 --- a/code/game/objects/items/weapons/storage/egg_vr.dm +++ b/code/game/objects/items/weapons/storage/egg_vr.dm @@ -35,6 +35,8 @@ animate_shake() drop_contents() icon = open_egg_icon + if(user.transforming) + user.transforming = FALSE /obj/item/weapon/storage/vore_egg/proc/animate_shake() var/init_px = pixel_x diff --git a/code/game/objects/items/weapons/storage/pouches.dm b/code/game/objects/items/weapons/storage/pouches.dm index 3cbf4d5130..8cd065aec1 100644 --- a/code/game/objects/items/weapons/storage/pouches.dm +++ b/code/game/objects/items/weapons/storage/pouches.dm @@ -14,7 +14,7 @@ max_storage_space = INVENTORY_POUCH_SPACE can_hold = null pocketable = TRUE - + var/insert_delay = 0 SECONDS var/remove_delay = 2 SECONDS @@ -32,7 +32,7 @@ // No delay if you have the pouch in your hands if(user.get_active_hand() == src || user.get_inactive_hand() == src) return TRUE // Skip delay - + if(remove_delay && !do_after(user, remove_delay, src, needhand = TRUE, exclusive = TASK_USER_EXCLUSIVE)) return FALSE // Moved while there is a delay @@ -58,10 +58,10 @@ /obj/item/weapon/storage/pouch/ammo name = "storage pouch (ammo)" - desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold ammunition and cells." + desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold ammunition, cells, explosives, and grenades." icon_state = "ammo" max_storage_space = INVENTORY_POUCH_SPACE - can_hold = list(/obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/cell/device/weapon) + can_hold = list(/obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/cell/device/weapon, /obj/item/weapon/grenade, /obj/item/weapon/plastique) //Vorestation Add - make it more useful for non-sec/explo /obj/item/weapon/storage/pouch/eng_tool name = "storage pouch (tools)" @@ -69,15 +69,35 @@ icon_state = "engineering_tool" max_storage_space = INVENTORY_POUCH_SPACE can_hold = list( - /obj/item/weapon/tool, + /obj/item/weapon/tool/crowbar, + /obj/item/weapon/tool/screwdriver, /obj/item/weapon/weldingtool, + /obj/item/weapon/tool/wirecutters, + /obj/item/weapon/tool/wrench, /obj/item/device/multitool, /obj/item/device/flashlight, + /obj/item/weapon/cell/device, + /obj/item/stack/cable_coil, /obj/item/device/t_scanner, /obj/item/device/analyzer, /obj/item/clothing/glasses, /obj/item/clothing/gloves, - ) + /obj/item/device/pda, + /obj/item/device/megaphone, + /obj/item/taperoll, + /obj/item/device/radio/headset, + /obj/item/device/robotanalyzer, + /obj/item/weapon/material/minihoe, + /obj/item/weapon/material/knife/machete/hatchet, + /obj/item/device/analyzer/plant_analyzer, + /obj/item/weapon/extinguisher/mini, + /obj/item/weapon/tape_roll, + /obj/item/device/integrated_electronics/wirer, + /obj/item/device/integrated_electronics/debugger, + /obj/item/weapon/shovel/spade, + /obj/item/stack/nanopaste, + /obj/item/device/geiger + ) //Vorestation Add - make it the same as the tool-belt why was it not like this to start with wtf /obj/item/weapon/storage/pouch/eng_supply name = "storage pouch (supplies)" @@ -88,15 +108,19 @@ /obj/item/weapon/cell/device, /obj/item/stack/cable_coil, /obj/item/taperoll, - /obj/item/weapon/extinguisher/mini, - /obj/item/weapon/tape_roll - ) + /obj/item/weapon/extinguisher, + /obj/item/weapon/tape_roll, + /obj/item/stack/material/steel, + /obj/item/stack/material/glass, + /obj/item/device/lightreplacer, + /obj/item/weapon/cell + ) //Vorestation Add - makes it actually useful lmao, adds sheets and cells as well as light replacers and lets you take any extinguisher that fits /obj/item/weapon/storage/pouch/eng_parts name = "storage pouch (parts)" desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold machinery components." icon_state = "part_pouch" - max_storage_space = INVENTORY_POUCH_SPACE + max_storage_space = INVENTORY_POUCH_SPACE*2 //Vorestation Add - yeah lemme give up my pocket to hold FOUR CAPACITORS or have an inferior box... now you can hold eight in your pocket so its at least a box can_hold = list( /obj/item/weapon/stock_parts, /obj/item/stack/cable_coil, @@ -120,8 +144,20 @@ /obj/item/weapon/storage/pill_bottle, /obj/item/stack/medical, /obj/item/weapon/reagent_containers/hypospray, - /obj/item/weapon/storage/quickdraw/syringe_case - ) + /obj/item/weapon/storage/quickdraw/syringe_case, + /obj/item/weapon/syringe_cartridge, + /obj/item/clothing/gloves/sterile, + /obj/item/device/sleevemate, + /obj/item/bodybag, + /obj/item/clothing/mask/surgical, + /obj/item/weapon/soap, + /obj/item/stack/nanopaste, + /obj/item/taperoll/medical, + /obj/item/weapon/storage/box/freezer, + /obj/item/clothing/mask/chewable/candy/lolli, + ) //Vorestation add - added a bunch of misc medical stuff + max_storage_space = ITEMSIZE_COST_SMALL*3 //Vorestation Add - makes it slightly smaller since its a lot of stuff with pocket access + remove_delay = 5 //Vorestation Add - .5 second delay, get the medical things faster because there is no reason to use this otherwise. still gotta stop moving to take things out. /obj/item/weapon/storage/pouch/flares name = "storage pouch (flares)" @@ -145,7 +181,7 @@ desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one normal sized weapon." icon_state = "pistol_holster" storage_slots = 1 - can_hold = list(/obj/item/weapon/gun) + can_hold = list(/obj/item/weapon/gun) //this covers basically everything I think so its fine remove_delay = 0 /obj/item/weapon/storage/pouch/holster/full_stunrevolver starts_with = list(/obj/item/weapon/gun/energy/stunrevolver) @@ -159,11 +195,11 @@ ..() /obj/item/weapon/storage/pouch/baton - name = "storage pouch (baton)" - desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one standard baton." + name = "storage pouch (melee)" + desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one normal size melee." //Vorestation add - make it a melee pouch literally why would you hold ONE BATON icon_state = "baton_holster" storage_slots = 1 - can_hold = list(/obj/item/weapon/melee/baton) + can_hold = list(/obj/item/weapon/melee, /obj/item/weapon/material, /obj/item/weapon/tool/wrench) //should be like, every melee weapon I could think of that was normal size. Can make it more specific if needed. Also wrench because I thought it was funny. remove_delay = 0 /obj/item/weapon/storage/pouch/baton/full starts_with = list(/obj/item/weapon/melee/baton) diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index aaf93580ff..c83dbe0f1a 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -97,7 +97,7 @@ starts_with = list( /obj/item/clothing/suit/fire/heavy, /obj/item/weapon/tank/oxygen/red, - /obj/item/weapon/watertank/atmos, + /obj/item/weapon/extinguisher/atmo, /obj/item/device/flashlight, /obj/item/clothing/head/hardhat/firefighter/atmos) diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm index e7eb0ea95a..c66bfe6ee4 100644 --- a/code/game/objects/structures/trash_pile_vr.dm +++ b/code/game/objects/structures/trash_pile_vr.dm @@ -247,7 +247,8 @@ prob(2);/obj/item/weapon/storage/box/syndie_kit/spy, prob(2);/obj/item/weapon/grenade/anti_photon, prob(2);/obj/item/clothing/under/hyperfiber/bluespace, - prob(2);/obj/item/weapon/reagent_containers/glass/beaker/vial/amorphorovir, + prob(2);/obj/item/selectable_item/chemistrykit/size, + prob(2);/obj/item/selectable_item/chemistrykit/gender, prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc, prob(1);/obj/item/device/nif/bad, prob(1);/obj/item/device/radio_jammer, diff --git a/code/game/turfs/simulated/fancy_shuttles.dm b/code/game/turfs/simulated/fancy_shuttles.dm index 010dced63f..c3bbf1d3e5 100644 --- a/code/game/turfs/simulated/fancy_shuttles.dm +++ b/code/game/turfs/simulated/fancy_shuttles.dm @@ -38,7 +38,7 @@ GLOBAL_LIST_EMPTY(fancy_shuttles) icon = 'icons/turf/fancy_shuttles/generic_preview.dmi' icon_state = "floors" plane = PLATING_PLANE - layer = ABOVE_TURF_LAYER + layer = DISPOSAL_LAYER alpha = 90 /obj/effect/fancy_shuttle_floor_preview/Initialize() diff --git a/code/modules/ai/ai_holder_movement.dm b/code/modules/ai/ai_holder_movement.dm index 5062492684..b553b86b7e 100644 --- a/code/modules/ai/ai_holder_movement.dm +++ b/code/modules/ai/ai_holder_movement.dm @@ -145,6 +145,8 @@ // Wanders randomly in cardinal directions. /datum/ai_holder/proc/handle_wander_movement() + if(!holder) + return ai_log("handle_wander_movement() : Entered.", AI_LOG_TRACE) if(isturf(holder.loc) && can_act()) wander_delay-- @@ -164,13 +166,13 @@ // No target, don't use the ladder // Target is visible, don't use the ladder if(!target || can_see_target(target)) - return + return var/has_hands = TRUE if(istype(holder, /mob/living/simple_mob)) var/mob/living/simple_mob/S = holder has_hands = S.has_hands - + // Don't have means to use a ladder or the space around it, don't use the ladder if(!has_hands && !holder.hovering) return @@ -178,7 +180,7 @@ var/obj/structure/ladder/L = locate() in get_turf(holder) if(!istype(L)) return // No ladder, can't use it - + if(!holder.may_climb_ladders(L)) return // Can't climb the ladder for other reasons (Probably inconsequential?) @@ -187,6 +189,6 @@ directions += L.target_down if(L.allowed_directions & UP) directions += L.target_up - + if(directions.len) L.climbLadder(holder, pick(directions)) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm index a99fab2c10..11edb589b3 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm @@ -44,6 +44,10 @@ display_name = "collar, cowbell" path = /obj/item/clothing/accessory/collar/cowbell +/datum/gear/collar/planet_earth + display_name = "collar, planet" + path = /obj/item/clothing/accessory/collar/collarplanet_earth + /datum/gear/collar/holo display_name = "collar, holo" path = /obj/item/clothing/accessory/collar/holo diff --git a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm index 6684a605f5..42aa7f50d2 100644 --- a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm @@ -198,6 +198,12 @@ ckeywhitelist = list("bobofboblandia") character_name = list("Charles Gettler") +/datum/gear/fluff/nettie_tablet + path = /obj/item/modular_computer/tablet/preset/custom_loadout/nettie + display_name = "Remodeled Tablet" + ckeywhitelist = list("bricker98") + character_name = list("Nettie Stough") + /datum/gear/fluff/xin_sovietuniform path = /obj/item/clothing/under/soviet display_name = "Xin's Soviet Uniform" @@ -1380,4 +1386,4 @@ path = /obj/item/device/modkit_conversion/crusader_luck display_name = "Lucky's amour" ckeywhitelist = list ("thedavestdave") - character_name = list("Lucky") \ No newline at end of file + character_name = list("Lucky") diff --git a/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm b/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm index 479032897e..3755d62c1e 100644 --- a/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_utility_vr.dm @@ -74,3 +74,8 @@ display_name = "bluespace bracelet" path = /obj/item/clothing/gloves/bluespace cost = 5 + +/datum/gear/utility/walkpod + display_name = "podzu music player" + path = /obj/item/device/walkpod + cost = 2 diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 1ea6bdebfb..29bd574d65 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -8,6 +8,7 @@ /obj/item/clothing/head/hairnet name = "hairnet" desc = "A hairnet used to keep the hair out of the way and out of the food." + icon_state = "hairnet" sprite_sheets = list( SPECIES_TAJARAN = 'icons/inventory/head/mob_tajaran.dmi' ) diff --git a/code/modules/clothing/under/accessories/accessory_vr.dm b/code/modules/clothing/under/accessories/accessory_vr.dm index 6032c96879..a2d996cb2f 100644 --- a/code/modules/clothing/under/accessories/accessory_vr.dm +++ b/code/modules/clothing/under/accessories/accessory_vr.dm @@ -269,6 +269,13 @@ item_state = "collar_cowbell_overlay" overlay_state = "collar_cowbell_overlay" +/obj/item/clothing/accessory/collar/collarplanet_earth + name = "planet collar" + desc = "A collar featuring a surprisingly detailed replica of planet earth surrounded by a weak battery powered force shield. There is a button to turn it off." + icon_state = "collarplanet_earth" + item_state = "collarplanet_earth" + overlay_state = "collarplanet_earth" + /obj/item/clothing/accessory/collar/holo name = "Holo-collar" diff --git a/code/modules/economy/vending_machines.dm b/code/modules/economy/vending_machines.dm index 14a81556e5..90776a7189 100644 --- a/code/modules/economy/vending_machines.dm +++ b/code/modules/economy/vending_machines.dm @@ -487,7 +487,6 @@ /obj/item/weapon/plantspray/pests = 20, /obj/item/weapon/reagent_containers/syringe = 5, /obj/item/weapon/reagent_containers/glass/beaker = 4, - /obj/item/weapon/watertank = 1, /obj/item/weapon/storage/bag/plants = 5) premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10, /obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) @@ -1536,8 +1535,7 @@ /obj/item/clothing/gloves/black = 5, /obj/item/weapon/storage/belt/janitor = 5, /obj/item/clothing/shoes/galoshes = 5, - /obj/item/weapon/cartridge/janitor = 5, - /obj/item/weapon/watertank/janitor = 1 + /obj/item/weapon/cartridge/janitor = 5 ) req_log_access = access_hop has_logs = 1 diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 48aff57f28..164a44a783 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -140,8 +140,8 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Spiders", /datum/event/spider_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15), -//YW Change new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50), + //new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300), + //new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Shipping Error", /datum/event/shipping_error , 30, list(ASSIGNMENT_ANY = 2), 0), //YW Change new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Space Dust", /datum/event/dust , 60, list(ASSIGNMENT_ENGINEER = 20), 0, 0, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), diff --git a/code/modules/events/event_container_vr.dm b/code/modules/events/event_container_vr.dm index 5e303bc989..2a27f1e6ce 100644 --- a/code/modules/events/event_container_vr.dm +++ b/code/modules/events/event_container_vr.dm @@ -41,7 +41,7 @@ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15), //new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 1, 25, 50), + //new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 1, 25, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Shipping Error", /datum/event/shipping_error , 30, list(ASSIGNMENT_ANY = 2), 0), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lore News", /datum/event/lore_news, 400), diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index e51dbf2472..68a72807f9 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -50,7 +50,7 @@ var/list/event_last_fired = list() //possibleEvents[/datum/event/mundane_news] = 300 possibleEvents[/datum/event/lore_news] = 300 // up this if the above ones get removed as they damn well should - possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200) + //possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200) possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50) if(GLOB.account_hack_attempted) possibleEvents[/datum/event/money_hacker] = max(min(25, player_list.len) * 4, 200) diff --git a/code/modules/food/kitchen/cooking_machines/fryer.dm b/code/modules/food/kitchen/cooking_machines/fryer.dm index bcaad4e693..bfc237df73 100644 --- a/code/modules/food/kitchen/cooking_machines/fryer.dm +++ b/code/modules/food/kitchen/cooking_machines/fryer.dm @@ -206,7 +206,7 @@ var/obj/item/organ/external/E var/nopain - if(ishuman(victim) && user.zone_sel.selecting != "groin" && user.zone_sel.selecting != "chest") + if(ishuman(victim) && user.zone_sel.selecting != BP_GROIN && user.zone_sel.selecting != BP_TORSO) var/mob/living/carbon/human/H = victim E = H.get_organ(user.zone_sel.selecting) if(!E || E.species.flags & NO_PAIN) diff --git a/code/modules/food/kitchen/gibber.dm b/code/modules/food/kitchen/gibber.dm index d348715bc6..329cba2edf 100644 --- a/code/modules/food/kitchen/gibber.dm +++ b/code/modules/food/kitchen/gibber.dm @@ -212,7 +212,7 @@ new_meat.name = "[slab_name] [new_meat.name]" new_meat.reagents.add_reagent("nutriment",slab_nutrition) if(src.occupant.reagents) - src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/slab_count,1)) + src.occupant.reagents.trans_to_obj(new_meat, round(occupant.reagents.total_volume/(2 + occupant.meat_amount),1)) add_attack_logs(user,occupant,"Used [src] to gib") diff --git a/code/modules/food/kitchen/microwave.dm b/code/modules/food/kitchen/microwave.dm index bab265f004..dd30240eec 100644 --- a/code/modules/food/kitchen/microwave.dm +++ b/code/modules/food/kitchen/microwave.dm @@ -22,7 +22,7 @@ var/global/list/acceptable_items // List of the items you can put in var/global/list/available_recipes // List of the recipes you can use var/global/list/acceptable_reagents // List of the reagents you can put in - + var/global/max_n_of_items = 20 var/appliancetype = MICROWAVE var/datum/looping_sound/microwave/soundloop @@ -36,7 +36,7 @@ /obj/machinery/microwave/Initialize() . = ..() - + reagents = new/datum/reagents(100) reagents.my_atom = src @@ -47,7 +47,7 @@ for(var/datum/recipe/typepath as anything in subtypesof(/datum/recipe)) if((initial(typepath.appliance) & appliancetype)) available_recipes += new typepath - + acceptable_items = new acceptable_reagents = new for (var/datum/recipe/recipe in available_recipes) @@ -66,6 +66,8 @@ soundloop = new(list(src), FALSE) /obj/machinery/microwave/Destroy() + if(paicard) + ejectpai() // Lets not delete the pAI. QDEL_NULL(soundloop) return ..() @@ -125,7 +127,8 @@ to_chat(user, "It's dirty!") return 1 else if(is_type_in_list(O,acceptable_items)) - if(contents.len>=(max_n_of_items + component_parts.len + circuit_item_capacity)) //Adds component_parts to the maximum number of items. changed 1 to actually just be the circuit item capacity var. + var/list/workingList = cookingContents() + if(workingList.len>=(max_n_of_items + circuit_item_capacity)) //Adds component_parts to the maximum number of items. changed 1 to actually just be the circuit item capacity var. to_chat(user, "This [src] is full of ingredients, you cannot put more.") return 1 if(istype(O, /obj/item/stack) && O:get_amount() > 1) // This is bad, but I can't think of how to change it @@ -144,6 +147,34 @@ "You add \the [O] to \the [src].") SStgui.update_uis(src) return + else if (istype(O,/obj/item/weapon/storage/bag/plants)) // There might be a better way about making plant bags dump their contents into a microwave, but it works. + var/obj/item/weapon/storage/bag/plants/bag = O + var/failed = 1 + for(var/obj/item/G in O.contents) + if(!G.reagents || !G.reagents.total_volume) + continue + failed = 0 + if(contents.len>=(max_n_of_items + component_parts.len + circuit_item_capacity)) + to_chat(user, "This [src] is full of ingredients, you cannot put more.") + return 0 + else + bag.remove_from_storage(G, src) + contents += G + if(contents.len>=(max_n_of_items + component_parts.len + circuit_item_capacity)) + break + + if(failed) + to_chat(user, "Nothing in the plant bag is usable.") + return 0 + + if(!O.contents.len) + to_chat(user, "You empty \the [O] into \the [src].") + else + to_chat(user, "You fill \the [src] from \the [O].") + + SStgui.update_uis(src) + return 0 + else if(istype(O,/obj/item/weapon/reagent_containers/glass) || \ istype(O,/obj/item/weapon/reagent_containers/food/drinks) || \ istype(O,/obj/item/weapon/reagent_containers/food/condiment) \ @@ -180,6 +211,9 @@ to_chat(user, "You decide not to do that.") else if(default_part_replacement(user, O)) return + else if(istype(O, /obj/item/device/paicard)) + if(!paicard) + insertpai(user, O) else to_chat(user, "You have no idea what you can cook with this [O].") ..() @@ -192,6 +226,10 @@ attack_hand(user) /obj/machinery/microwave/attack_hand(mob/user as mob) + if(user.a_intent == I_GRAB) + if(paicard) + ejectpai(user) + return user.set_machine(src) tgui_interact(user) @@ -211,7 +249,7 @@ data["operating"] = operating data["dirty"] = dirty == 100 data["items"] = get_items_list() - + return data /obj/machinery/microwave/proc/get_items_list() @@ -220,7 +258,8 @@ var/list/items_counts = list() var/list/items_measures = list() var/list/items_measures_p = list() - for(var/obj/O in ((contents - component_parts) - circuit)) + //for(var/obj/O in ((contents - component_parts) - circuit)) + for(var/obj/O in cookingContents()) var/display_name = O.name if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/egg)) items_measures[display_name] = "egg" @@ -283,7 +322,7 @@ if("dispose") dispose() return TRUE -/* +/* /obj/machinery/microwave/interact(mob/user as mob) // The microwave Menu var/dat = "" if(src.broken > 0) @@ -355,7 +394,7 @@ if(stat & (NOPOWER|BROKEN)) return start() - if(reagents.total_volume==0 && !(locate(/obj) in ((contents - component_parts) - circuit))) //dry run + if(reagents.total_volume==0 && !(locate(/obj) in cookingContents())) //dry run if(!wzhzhzh(16)) //VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was 5) abort() return @@ -390,7 +429,7 @@ cooked = fail() cooked.forceMove(src.loc) return - + //Making multiple copies of a recipe var/halftime = round(recipe.time*4/10/2) // VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was round(recipe.time/20/2)) if(!wzhzhzh(halftime)) @@ -433,7 +472,7 @@ for(var/obj/item/weapon/reagent_containers/food/snacks/S in cooked_items) reagents.trans_to_holder(S.reagents, total/cooked_items.len) - for(var/obj/item/weapon/reagent_containers/food/snacks/S in contents) + for(var/obj/item/weapon/reagent_containers/food/snacks/S in cookingContents()) S.cook() dispose(0) //clear out anything left @@ -451,7 +490,7 @@ /obj/machinery/microwave/proc/has_extra_item() //- coded to have different microwaves be able to handle different items if(item_level == 0) - for (var/obj/O in ((contents - component_parts) - circuit)) + for (var/obj/O in cookingContents()) if ( \ !istype(O,/obj/item/weapon/reagent_containers/food) && \ !istype(O, /obj/item/weapon/grown) \ @@ -459,7 +498,7 @@ return 1 return 0 if(item_level == 1) - for (var/obj/O in ((contents - component_parts) - circuit)) + for (var/obj/O in cookingContents()) if ( \ !istype(O, /obj/item/weapon/reagent_containers/food) && \ !istype(O, /obj/item/weapon/grown) && \ @@ -483,7 +522,7 @@ icon_state = "mw" SStgui.update_uis(src) soundloop.stop() - + /obj/machinery/microwave/proc/stop() playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) operating = FALSE // Turn it off again aferwards @@ -493,7 +532,7 @@ soundloop.stop() /obj/machinery/microwave/proc/dispose(var/message = 1) - for (var/atom/movable/A in ((contents-component_parts)-circuit)) + for (var/atom/movable/A in cookingContents()) A.forceMove(loc) if (src.reagents.total_volume) src.dirty++ @@ -527,11 +566,12 @@ src.operating = 0 // Turn it off again aferwards SStgui.update_uis(src) soundloop.stop() + src.ejectpai() // If it broke, time to yeet the PAI. /obj/machinery/microwave/proc/fail() var/obj/item/weapon/reagent_containers/food/snacks/badrecipe/ffuu = new(src) var/amount = 0 - for (var/obj/O in (((contents - ffuu) - component_parts) - circuit)) + for (var/obj/O in cookingContents() - ffuu) amount++ if(O.reagents) var/id = O.reagents.get_master_reagent_id() @@ -558,14 +598,14 @@ if(!do_after(usr, 1 SECONDS, target = src)) return - + if(operating) to_chat(usr, "You can't do that, [src] door is locked!") return usr.visible_message( - "[usr] opened [src] and has taken out [english_list(((contents-component_parts)-circuit))]." , - "You have opened [src] and taken out [english_list(((contents-component_parts)-circuit))]." + "[usr] opened [src] and has taken out [english_list(cookingContents())]." , + "You have opened [src] and taken out [english_list(cookingContents())]." ) dispose() @@ -594,7 +634,7 @@ /obj/item/weapon/holder ) result = /obj/effect/decal/cleanable/blood/gibs - + /datum/recipe/splat/before_cook(obj/container) if(istype(container, /obj/machinery/microwave)) var/obj/machinery/microwave/M = container @@ -617,3 +657,14 @@ var/obj/machinery/microwave/M = container M.muck_finish() . = ..() + +/obj/machinery/microwave/proc/cookingContents() //VOREEdit, this is a better way to deal with the contents of a microwave, since the previous method is stupid. + var/list/workingList = contents.Copy() // Using the copy proc because otherwise the two lists seem to become soul bonded. + workingList -= component_parts + workingList -= circuit + if(paicard) + workingList -= paicard + for(var/M in workingList) + if(istype(M, circuit)) // Yes, we remove circuit twice. Yes, it's necessary. Yes, it's stupid. + workingList -= M + return workingList \ No newline at end of file diff --git a/code/modules/food/recipes_fryer.dm b/code/modules/food/recipes_fryer.dm index bc977d8afb..4f1bc471e4 100644 --- a/code/modules/food/recipes_fryer.dm +++ b/code/modules/food/recipes_fryer.dm @@ -18,6 +18,7 @@ fruit = list("chili" = 1) coating = /datum/reagent/nutriment/coating/batter result = /obj/item/weapon/reagent_containers/food/snacks/jalapeno_poppers + result_quantity = 2 /datum/recipe/risottoballs appliance = FRYER @@ -26,6 +27,7 @@ coating = /datum/reagent/nutriment/coating/batter reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product result = /obj/item/weapon/reagent_containers/food/snacks/risottoballs + result_quantity = 2 /datum/recipe/bellefritter appliance = FRYER @@ -33,12 +35,14 @@ reagents = list("sugar" = 5) items = list(/obj/item/weapon/reagent_containers/food/snacks/frostbelle) result = /obj/item/weapon/reagent_containers/food/snacks/bellefritter + result_quantity = 2 /datum/recipe/onionrings appliance = FRYER coating = /datum/reagent/nutriment/coating/batter fruit = list("onion" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/onionrings + result_quantity = 2 //Meaty Recipes //==================== @@ -169,6 +173,7 @@ appliance = FRYER reagents = list("sugar" = 5, "batter" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/funnelcake + result_quantity = 2 /datum/recipe/pisanggoreng appliance = FRYER diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 7b30e0f5c1..1f470c81bb 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -73,6 +73,7 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/dough, ) result = /obj/item/weapon/reagent_containers/food/snacks/muffin + result_quantity = 2 /datum/recipe/eggplantparm fruit = list("eggplant" = 1) @@ -248,6 +249,7 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/dough, ) result = /obj/item/weapon/reagent_containers/food/snacks/rofflewaffles + result_quantity = 2 /datum/recipe/stew fruit = list("potato" = 1, "tomato" = 1, "carrot" = 1, "eggplant" = 1, "mushroom" = 1) @@ -415,6 +417,7 @@ I said no! fruit = list("plumphelmet" = 1) reagents = list("water" = 5, "flour" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit + result_quantity = 2 /datum/recipe/mushroomsoup fruit = list("mushroom" = 1) @@ -478,6 +481,7 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread, ) result = /obj/item/weapon/reagent_containers/food/snacks/stuffing + result_quantity = 2 /datum/recipe/mashedpotato items = list( @@ -511,6 +515,7 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/dough ) result = /obj/item/weapon/reagent_containers/food/snacks/bun + result_quantity = 3 /datum/recipe/microwaveflatbread items = list( @@ -536,6 +541,7 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/rawsunflower ) result = /obj/item/weapon/reagent_containers/food/snacks/roastedsunflower + result_quantity = 2 /datum/recipe/roastedsunflowerseeds reagents = list("sodiumchloride" = 1, "cookingoil" = 1) @@ -543,6 +549,7 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/rawsunflower ) result = /obj/item/weapon/reagent_containers/food/snacks/roastedsunflower + result_quantity = 2 /datum/recipe/roastedpeanutsunflowerseeds reagents = list("sodiumchloride" = 1, "peanutoil" = 1) @@ -550,21 +557,25 @@ I said no! /obj/item/weapon/reagent_containers/food/snacks/rawsunflower ) result = /obj/item/weapon/reagent_containers/food/snacks/roastedsunflower + result_quantity = 2 /datum/recipe/roastedpeanuts fruit = list("peanut" = 2) reagents = list("sodiumchloride" = 2, "cookingoil" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/roastedpeanuts + result_quantity = 2 /datum/recipe/roastedpeanutscorn fruit = list("peanut" = 2) reagents = list("sodiumchloride" = 2, "cornoil" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/roastedpeanuts + result_quantity = 2 /datum/recipe/roastedpeanutspeanut fruit = list("peanut" = 2) reagents = list("sodiumchloride" = 2, "peanutoil" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/roastedpeanuts + result_quantity = 2 /datum/recipe/mint reagents = list("sugar" = 5, "frostoil" = 5) @@ -596,6 +607,7 @@ I said no! ) reagents = list("sugar" = 5, "egg" = 3) result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie + result_quantity = 4 /datum/recipe/berrymuffin reagents = list("milk" = 5, "sugar" = 5) @@ -604,6 +616,7 @@ I said no! ) fruit = list("berries" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/berrymuffin/berry + result_quantity = 2 /datum/recipe/poisonberrymuffin reagents = list("milk" = 5, "sugar" = 5) @@ -612,6 +625,7 @@ I said no! ) fruit = list("poisonberries" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/berrymuffin/poison + result_quantity = 2 /datum/recipe/ghostmuffin reagents = list("milk" = 5, "sugar" = 5) @@ -621,6 +635,7 @@ I said no! ) fruit = list("berries" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/berry + result_quantity = 2 /datum/recipe/poisonghostmuffin reagents = list("milk" = 5, "sugar" = 5) @@ -630,6 +645,7 @@ I said no! ) fruit = list("poisonberries" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/poison + result_quantity = 2 /datum/recipe/eggroll reagents = list("soysauce" = 10) @@ -841,6 +857,7 @@ I said no! ) reagent_mix = RECIPE_REAGENT_REPLACE result = /obj/item/weapon/reagent_containers/food/snacks/nugget + result_quantity = 3 // Chip update /datum/recipe/microwavetortilla @@ -850,6 +867,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/tortilla reagent_mix = RECIPE_REAGENT_REPLACE //no gross flour or water + result_quantity = 3 /datum/recipe/taco items = list( @@ -1041,6 +1059,7 @@ I said no! ) fruit = list("cabbage" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/stuffed_meatball + result_quantity = 2 /datum/recipe/egg_pancake items = list( diff --git a/code/modules/food/recipes_microwave_vr.dm b/code/modules/food/recipes_microwave_vr.dm index 31c9d1268c..03c96d8296 100644 --- a/code/modules/food/recipes_microwave_vr.dm +++ b/code/modules/food/recipes_microwave_vr.dm @@ -37,6 +37,7 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/donerkebab + /datum/recipe/roastbeef fruit = list("carrot" = 2, "potato" = 2) items = list( @@ -150,7 +151,7 @@ result = /obj/item/weapon/storage/box/wings/tray /datum/recipe/bucket - fruit = list("potato" = 1) + fruit = list("durian" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/meat, diff --git a/code/modules/food/recipes_oven.dm b/code/modules/food/recipes_oven.dm index 7b8bb2e46e..bf932c9da0 100644 --- a/code/modules/food/recipes_oven.dm +++ b/code/modules/food/recipes_oven.dm @@ -76,8 +76,6 @@ /datum/recipe/bread appliance = OVEN items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough ) @@ -97,13 +95,10 @@ /datum/recipe/tofubread appliance = OVEN items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/tofu, /obj/item/weapon/reagent_containers/food/snacks/tofu, - /obj/item/weapon/reagent_containers/food/snacks/tofu, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) @@ -134,17 +129,15 @@ /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough ) result = /obj/item/weapon/reagent_containers/food/snacks/tortilla + result_quantity = 3 /datum/recipe/meatbread appliance = OVEN items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) @@ -153,13 +146,10 @@ /datum/recipe/syntibread appliance = OVEN items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, - /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) @@ -168,13 +158,10 @@ /datum/recipe/xenomeatbread appliance = OVEN items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/xenomeat, /obj/item/weapon/reagent_containers/food/snacks/xenomeat, - /obj/item/weapon/reagent_containers/food/snacks/xenomeat, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) @@ -185,7 +172,6 @@ fruit = list("banana" = 1) reagents = list("milk" = 5, "sugar" = 15) items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough ) @@ -198,6 +184,7 @@ /obj/item/weapon/reagent_containers/food/snacks/dough ) result = /obj/item/weapon/reagent_containers/food/snacks/bun + result_quantity = 3 //Predesigned pies //======================= @@ -273,6 +260,7 @@ reagents = list("sugar" = 10) items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) result = /obj/item/weapon/reagent_containers/food/snacks/appletart + result_quantity = 2 reagent_mix = RECIPE_REAGENT_REPLACE /datum/recipe/keylimepie @@ -333,7 +321,6 @@ reagent_mix = RECIPE_REAGENT_REPLACE //No egg or mix in final recipe result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/brownies - /datum/recipe/cosmicbrownies appliance = OVEN reagents = list("browniemix" = 10, "egg" = 3) @@ -344,7 +331,7 @@ /datum/recipe/buchedenoel appliance = OVEN fruit = list("berries" = 2) - reagents = list("milk" = 5, "flour" = 15, "cream" = 10, "coco" = 5, "egg" = 6) + reagents = list("cakebatter" = 20, "cream" = 10, "coco" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/buchedenoel /datum/recipe/cinnamonbun @@ -443,19 +430,19 @@ //============ /datum/recipe/cake appliance = OVEN - reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9, "vanilla" = 1) + reagents = list("cakebatter" = 30, "vanilla" = 2) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake reagent_mix = RECIPE_REAGENT_REPLACE /datum/recipe/cake/carrot appliance = OVEN fruit = list("carrot" = 3) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) + reagents = list("cakebatter" = 30) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake /datum/recipe/cake/cheese appliance = OVEN - reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) + reagents = list("cakebatter" = 30) items = list( /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge @@ -463,49 +450,48 @@ result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake /datum/recipe/cake/peanut - fruit = list("peanut" = 3) - reagents = list("milk" = 5, "flour" = 10, "sugar" = 5, "egg" = 6, "peanutbutter" = 5) + fruit = list("peanut" = 1) + reagents = list("cakebatter" = 30, "peanutbutter" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/peanutcake /datum/recipe/cake/orange appliance = OVEN - fruit = list("orange" = 1) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "sugar" = 5) + fruit = list("orange" = 2) + reagents = list("cakebatter" = 30) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake /datum/recipe/cake/lime appliance = OVEN - fruit = list("lime" = 1) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "limejuice" = 3, "sugar" = 5) + fruit = list("lime" = 2) + reagents = list("cakebatter" = 30) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake /datum/recipe/cake/lemon appliance = OVEN - fruit = list("lemon" = 1) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "lemonjuice" = 3, "sugar" = 5) + fruit = list("lemon" = 2) + reagents = list("cakebatter" = 30) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake /datum/recipe/cake/chocolate appliance = OVEN - items = list(/obj/item/weapon/reagent_containers/food/snacks/chocolatebar) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "coco" = 4, "sugar" = 5) + reagents = list("cakebatter" = 30, "coco" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake /datum/recipe/cake/birthday appliance = OVEN - reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) + reagents = list("cakebatter" = 30) items = list(/obj/item/clothing/head/cakehat) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake /datum/recipe/cake/apple appliance = OVEN fruit = list("apple" = 2) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) + reagents = list("cakebatter" = 30) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake /datum/recipe/cake/brain appliance = OVEN - reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) + reagents = list("cakebatter" = 30) items = list(/obj/item/organ/internal/brain) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake @@ -517,6 +503,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough ) result = /obj/item/weapon/reagent_containers/food/snacks/pancakes + result_quantity = 2 /datum/recipe/pancakes/berry appliance = OVEN @@ -527,6 +514,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough ) result = /obj/item/weapon/reagent_containers/food/snacks/pancakes/berry + result_quantity = 2 /datum/recipe/lasagna appliance = OVEN @@ -547,6 +535,7 @@ ) reagents = list("milk" = 5, "egg" = 3,"honey" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/honeybun + result_quantity = 4 //Bacon /datum/recipe/bacon_oven @@ -602,6 +591,7 @@ reagent_mix = RECIPE_REAGENT_REPLACE items = list(/obj/item/weapon/reagent_containers/food/snacks/dough) result = /obj/item/weapon/reagent_containers/food/snacks/croissant + result_quantity = 2 /datum/recipe/macncheese appliance = OVEN @@ -639,6 +629,7 @@ /obj/item/weapon/reagent_containers/food/snacks/dough ) result = /obj/item/weapon/reagent_containers/food/snacks/waffles + result_quantity = 2 /datum/recipe/loadedbakedpotatooven appliance = OVEN @@ -656,6 +647,7 @@ ) reagent_mix = RECIPE_REAGENT_REPLACE //Water used up in cooking result = /obj/item/weapon/reagent_containers/food/snacks/meatbun + result_quantity = 2 /datum/recipe/spicedmeatbun appliance = OVEN @@ -666,6 +658,7 @@ ) reagent_mix = RECIPE_REAGENT_REPLACE //Water used up in cooking result = /obj/item/weapon/reagent_containers/food/snacks/spicedmeatbun + result_quantity = 2 /datum/recipe/custardbun appliance = OVEN @@ -687,6 +680,7 @@ ) reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product result = /obj/item/weapon/reagent_containers/food/snacks/chickenmomo + result_quantity = 2 /datum/recipe/veggiemomo appliance = OVEN @@ -698,4 +692,5 @@ /obj/item/weapon/reagent_containers/food/snacks/doughslice ) reagent_mix = RECIPE_REAGENT_REPLACE //Get that water outta here - result = /obj/item/weapon/reagent_containers/food/snacks/veggiemomo \ No newline at end of file + result = /obj/item/weapon/reagent_containers/food/snacks/veggiemomo + result_quantity = 2 \ No newline at end of file diff --git a/code/modules/hydroponics/backtank.dm b/code/modules/hydroponics/backtank.dm index 9ecb6b7bb5..c7c4f8677e 100644 --- a/code/modules/hydroponics/backtank.dm +++ b/code/modules/hydroponics/backtank.dm @@ -1,3 +1,15 @@ +///// __ __ _____ _ _ _____ _ _ _____ ///// +///// \ \ / /\ | __ \| \ | |_ _| \ | |/ ____|///// +///// \ \ /\ / / \ | |__) | \| | | | | \| | | __ ///// +///// \ \/ \/ / /\ \ | _ /| . ` | | | | . ` | | |_ |///// +///// \ /\ / ____ \| | \ \| |\ |_| |_| |\ | |__| |///// +///// \/ \/_/ \_\_| \_\_| \_|_____|_| \_|\_____|///// + + +///// I have no clue why. I am too tired to figure out. Do not enable this file. For some esoteric reasons it breaks runtimes. Particularly, runtime logging. +///// No I don't know why. No I don't care to figure out why. Not anymore. I haven't seen these things used anywhere. By anyone. +///// If somebody REALLY wants these, they can be the ones to figure out why the hell this random-ass water backpack file breaks runtime list. I am disabling this and I am done with this. Good night. + /* * Hydroponics tank and base code */ @@ -17,7 +29,7 @@ /obj/item/weapon/watertank/Initialize() . = ..() - create_reagents(volume, OPENCONTAINER) + create_reagents(volume) noz = make_noz() /obj/item/weapon/watertank/MouseDrop() diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 56a6e54307..9e218d62c8 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -259,15 +259,28 @@ /obj/item/integrated_circuit/output/video_camera name = "video camera circuit" desc = "This small camera allows a remote viewer to see what it sees." - extended_desc = "The camera is linked to the Research camera network." + var/list/networks = list( + "research" = NETWORK_CIRCUITS, + "engine" = NETWORK_ENGINE, + "engineering" = NETWORK_ENGINEERING, + "mining" = NETWORK_MINE, + "medical" = NETWORK_MEDICAL, + "entertainment" = NETWORK_THUNDER, + "security" = NETWORK_SECURITY, + "command" = NETWORK_COMMAND + ) icon_state = "video_camera" w_class = ITEMSIZE_SMALL complexity = 10 inputs = list( "camera name" = IC_PINTYPE_STRING, + "camera network" = IC_PINTYPE_STRING, "camera active" = IC_PINTYPE_BOOLEAN ) - inputs_default = list("1" = "video camera circuit") + inputs_default = list( + "1" = "video camera circuit", + "2" = "research" + ) outputs = list() activators = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -276,6 +289,11 @@ /obj/item/integrated_circuit/output/video_camera/New() ..() + extended_desc = list() + extended_desc += "Network choices are; " + extended_desc += jointext(networks, ", ") + extended_desc += "." + extended_desc = jointext(extended_desc, null) camera = new(src) on_data_written() @@ -294,10 +312,20 @@ /obj/item/integrated_circuit/output/video_camera/on_data_written() if(camera) var/cam_name = get_pin_data(IC_INPUT, 1) - var/cam_active = get_pin_data(IC_INPUT, 2) + var/cam_network = get_pin_data(IC_INPUT, 2) + var/cam_active = get_pin_data(IC_INPUT, 3) if(!isnull(cam_name)) camera.c_tag = cam_name + camera.replace_networks(list(cam_network)) set_camera_status(cam_active) + if(isnull(cam_network)) + camera.clear_all_networks() + return + var/selected_network = networks[cam_network] + if(!selected_network) + camera.clear_all_networks() + return + camera.replace_networks(list(selected_network)) /obj/item/integrated_circuit/output/video_camera/power_fail() if(camera) diff --git a/code/modules/materials/materials/organic/cloth.dm b/code/modules/materials/materials/organic/cloth.dm index 294e046670..38a8aae265 100644 --- a/code/modules/materials/materials/organic/cloth.dm +++ b/code/modules/materials/materials/organic/cloth.dm @@ -13,7 +13,7 @@ hardness = 5 -/datum/material/cloth/generate_recipes() +/datum/material/cloth/generate_recipes() //Vorestation Add - adding some funny cool storage pouches to this so botany can do things other than food recipes = list( new /datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]"), new /datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), @@ -29,6 +29,13 @@ new /datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("pouch, small", /obj/item/weapon/storage/pouch/small, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, ammo", /obj/item/weapon/storage/pouch/ammo, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, tools", /obj/item/weapon/storage/pouch/eng_tool, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, parts", /obj/item/weapon/storage/pouch/eng_parts, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, supplies", /obj/item/weapon/storage/pouch/eng_supply, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, medical", /obj/item/weapon/storage/pouch/medical, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, flare", /obj/item/weapon/storage/pouch/flares, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add new /datum/stack_recipe("crude bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]"), new /datum/stack_recipe("painting canvas (11x11)", /obj/item/canvas, 2, time = 2 SECONDS, pass_stack_color = FALSE, supplied_material = "[name]"), diff --git a/code/modules/materials/materials/organic/leather.dm b/code/modules/materials/materials/organic/leather.dm index f5fc8cb2f9..1c46a78bfd 100644 --- a/code/modules/materials/materials/organic/leather.dm +++ b/code/modules/materials/materials/organic/leather.dm @@ -27,6 +27,10 @@ new /datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("pouch, medium", /obj/item/weapon/storage/pouch, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, large", /obj/item/weapon/storage/pouch/large, 15, time = 30 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, holster", /obj/item/weapon/storage/pouch/holster, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, melee", /obj/item/weapon/storage/pouch/baton, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add new /datum/stack_recipe("crude [display_name] bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("[display_name] net", /obj/item/weapon/material/fishing_net, 10, time = 5 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE), new /datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE), diff --git a/code/modules/materials/sheets/organic/animal_products.dm b/code/modules/materials/sheets/organic/animal_products.dm index 5ebd36d008..c0084bf93c 100644 --- a/code/modules/materials/sheets/organic/animal_products.dm +++ b/code/modules/materials/sheets/organic/animal_products.dm @@ -73,6 +73,13 @@ new /datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white/craftable, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white/craftable, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white/craftable, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"), + new /datum/stack_recipe("pouch, small", /obj/item/weapon/storage/pouch/small, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, ammo", /obj/item/weapon/storage/pouch/ammo, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, tools", /obj/item/weapon/storage/pouch/eng_tool, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, parts", /obj/item/weapon/storage/pouch/eng_parts, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, supplies", /obj/item/weapon/storage/pouch/eng_supply, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, medical", /obj/item/weapon/storage/pouch/medical, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add + new /datum/stack_recipe("pouch, flare", /obj/item/weapon/storage/pouch/flares, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add new /datum/stack_recipe("crude bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"), new /datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]"), new /datum/stack_recipe("satchel", /obj/item/weapon/storage/backpack/satchel/craftable, 30, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"), diff --git a/code/modules/mining/kinetic_crusher.dm b/code/modules/mining/kinetic_crusher.dm index 7effaf60d9..043dfe8188 100644 --- a/code/modules/mining/kinetic_crusher.dm +++ b/code/modules/mining/kinetic_crusher.dm @@ -230,7 +230,7 @@ desc = "A modified design of a proto-kinetic crusher, it is still little more of a combination of various mining tools cobbled together \ and kit-bashed into a high-tech cleaver on a stick - with a handguard and a goliath hide grip. While it is still of little use to any \ but the most skilled and/or suicidal miners against local fauna, it's an elegant weapon for a more civilized hunter." - + look gary there i am - hatterhat */ @@ -256,6 +256,9 @@ backstab_bonus = 40 // 100 thrown_bonus = 20 // 120 update_item_state = FALSE + slot_flags = SLOT_BELT + + /obj/item/weapon/kinetic_crusher/machete/gauntlets @@ -275,6 +278,7 @@ detonation_damage = 37 // 75 backstab_bonus = 55 // 130 var/obj/item/offhand/crushergauntlets/offhand + slot_flags = null /obj/item/weapon/kinetic_crusher/machete/gauntlets/equipped() . = ..() @@ -381,6 +385,7 @@ thrown_bonus = 50 // 135 but you drop your knife because you threw it + //destablizing force /obj/item/projectile/destabilizer name = "destabilizing force" diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 2c0de82adc..54a86d9b28 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -4,7 +4,7 @@ var/msg = "" // This is to make sure that the pieces have actually added something var/raw_msg = "" . = list("formatted" = "[verb], \"", "raw" = "") - + for(var/datum/multilingual_say_piece/SP in message_pieces) iteration_count++ var/piece = SP.message @@ -15,11 +15,11 @@ if(radio) .["formatted"] = SP.speaking.format_message_radio(piece) .["raw"] = piece - return + return else .["formatted"] = SP.speaking.format_message(piece) .["raw"] = piece - return + return if(iteration_count == 1) piece = capitalize(piece) @@ -27,14 +27,17 @@ if(always_stars) piece = stars(piece) else if(!say_understands(speaker, SP.speaking)) - piece = saypiece_scramble(SP) - if(isliving(speaker)) - var/mob/living/S = speaker - if(istype(S.say_list) && length(S.say_list.speak)) - piece = pick(S.say_list.speak) + if(SP.speaking.flags & INAUDIBLE) + piece = "" + else + piece = saypiece_scramble(SP) + if(isliving(speaker)) + var/mob/living/S = speaker + if(istype(S.say_list) && length(S.say_list.speak)) + piece = pick(S.say_list.speak) raw_msg += (piece + " ") - + //HTML formatting if(!SP.speaking) // Catch the most generic case first piece = "[piece]" @@ -44,7 +47,7 @@ piece = SP.speaking.format_message(piece) msg += (piece + " ") - + if(msg == "") // There is literally no content left in this message, we need to shut this shit down .["formatted"] = "" // hear_say will suppress it @@ -90,7 +93,7 @@ var/message = combined["formatted"] if(message == "") return - + if(sleeping || stat == UNCONSCIOUS) hear_sleep(multilingual_to_message(message_pieces)) return FALSE @@ -169,7 +172,7 @@ var/regex/R = new("\\[delimiter](.+?)\\[delimiter]","g") var/tag = GLOB.speech_toppings[delimiter] tagged_message = R.Replace(tagged_message,"<[tag]>$1") - + return tagged_message /mob/proc/hear_radio(var/list/message_pieces, var/verb = "says", var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname = "") @@ -226,13 +229,13 @@ final_message = "[time][final_message]" to_chat(src, final_message) -/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null) +/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/verb_understood = "gestures", var/datum/language/language, var/mob/speaker = null, var/speech_type = 1) if(!client) return if(say_understands(speaker, language)) - message = "[speaker] [verb], \"[message]\"" - else + message = "[speaker] [verb_understood], \"[message]\"" + else if(!(language.ignore_adverb)) var/adverb var/length = length(message) * pick(0.8, 0.9, 1.0, 1.1, 1.2) //Adds a little bit of fuzziness switch(length) @@ -242,8 +245,10 @@ if(48 to 90) adverb = " a lengthy message" else adverb = " a very lengthy message" message = "[speaker] [verb][adverb]." + else + message = "[speaker] [verb]." - show_message(message, type = 1) // Type 1 is visual message + show_message(message, type = speech_type) // Type 1 is visual message /mob/proc/hear_sleep(var/message) var/heard = "" @@ -293,4 +298,4 @@ name = speaker.voice_name var/rendered = "[name] [message]" - to_chat(src, rendered) + to_chat(src, rendered) diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm index 03daea6197..55ba735af4 100644 --- a/code/modules/mob/language/generic.dm +++ b/code/modules/mob/language/generic.dm @@ -145,8 +145,9 @@ // which is exactly what sign language does. /datum/language/sign/broadcast(var/mob/living/speaker, var/message, var/speaker_mask) log_say("(SIGN) [message]", speaker) - speaker.say_signlang(message, pick(signlang_verb), src) - + var/verb_to_use = pick(signlang_verb) + speaker.say_signlang(message, verb_to_use, verb_to_use, src) + // Silly language for those times when you try to talk a languague you normally can't /datum/language/gibberish diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index cf372545e7..4cb01b981f 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -12,6 +12,7 @@ var/exclaim_verb = "exclaims" // Used when sentence ends in a ! var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. var/signlang_verb = list("signs", "gestures") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags + var/signlang_verb_understood = list("signs") // snowflake bs, used only for echo var/colour = "body" // CSS style to use for strings in this language. var/key = "x" // Character used to speak in language eg. :o for Unathi. var/flags = 0 // Various language flags. @@ -20,6 +21,7 @@ var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string var/machine_understands = 1 // Whether machines can parse and understand this language var/list/partial_understanding // List of languages that can /somehwat/ understand it, format is: name = chance of understanding a word + var/ignore_adverb = FALSE // For inaudible languages that we dont want adverb for /datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4, syllable_divisor=2) if(!syllables || !syllables.len) @@ -235,7 +237,7 @@ //TBD /mob/proc/check_lang_data() . = "" - + for(var/datum/language/L in languages) if(!(L.flags & NONGLOBAL)) . += "[L.name] ([get_language_prefix()][L.key])
[L.desc]

" diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm index 13c1034424..77755a3807 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -96,7 +96,8 @@ /datum/language/tajsign/broadcast(var/mob/living/speaker, var/message, var/speaker_mask) log_say("(SIGN) [message]", speaker) - speaker.say_signlang(message, pick(signlang_verb), src) + var/verb_to_use = pick(signlang_verb) + speaker.say_signlang(message, verb_to_use, verb_to_use, src) /datum/language/tajsign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format var/list/allowed_species = list(SPECIES_TAJ, SPECIES_TESHARI) // Need a tail and ears and such to use this. diff --git a/code/modules/mob/language/station_vr.dm b/code/modules/mob/language/station_vr.dm index 38c5a7d8b7..bcc1db723e 100644 --- a/code/modules/mob/language/station_vr.dm +++ b/code/modules/mob/language/station_vr.dm @@ -167,7 +167,24 @@ exclaim_verb = "squeaks loudly" syllables = list ("sque", "uik", "squeak", "squee", "eak", "eek", "uek", "squik", "squeek", "sq", "squee", "ee", "ek", "ak", "ueak", "squea") - colour = "tavan" + colour = "tavan" + +/datum/language/echosong + name = LANGUAGE_ECHOSONG + desc = "An ultrasound-based language, inaudible to those unable to understand it." + key = "U" + signlang_verb = list("opens their mouth soundlessly", "mouthes something silently") + signlang_verb_understood = list("squeaks") + colour = "echosong" + flags = INAUDIBLE + ignore_adverb = TRUE + +/datum/language/echosong/scramble(var/input, var/list/known_languages) + return stars(input) + +/datum/language/echosong/broadcast(var/mob/living/speaker, var/message, var/speaker_mask) + log_say("(INAUDIBLE) [message]", speaker) + speaker.say_signlang(format_message(message), pick(signlang_verb), pick(signlang_verb_understood), src, 2) /datum/language/unathi flags = 0 diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index 2bc63f1bfe..563675d719 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -17,7 +17,7 @@ var/emagged = 0 var/light_strength = 3 var/busy = 0 - + var/obj/item/device/paicard/paicard = null var/obj/access_scanner = null var/list/req_access = list() var/list/req_one_access = list() @@ -72,10 +72,27 @@ SetStunned(0) SetParalysis(0) - if(on && !client && !busy) + if(on && !client && !busy && !paicard) spawn(0) handleAI() - +/* +/mob/living/bot/examine(mob/user) + . = ..() + if(health < maxHealth) + if(health > maxHealth/3) + . += "[src]'s parts look loose." + else + . += "[src]'s parts look very loose!" + else + . += "[src] is in pristine condition." + . += span_notice("Its maintenance panel is [open ? "open" : "closed"].") + . += span_info("You can use a screwdriver to [open ? "close" : "open"] it.") + . += span_notice("Its control panel is [locked ? "locked" : "unlocked"].") + if(paicard) + . += span_notice("It has a pAI device installed.") + if(open) + . += span_info("You can use a crowbar to remove it.") +*/ /mob/living/bot/updatehealth() if(status_flags & GODMODE) health = getMaxHealth() @@ -138,6 +155,17 @@ qdel(O) else to_chat(user, "Unable to repair with the maintenance panel closed.") + else if(istype(O, /obj/item/device/paicard)) + if(open) + insertpai(user, O) + to_chat(user, span_notice("You slot the card into \the [initial(src.name)].")) + else + to_chat(user, span_notice("You must open the panel first!")) + else if(O.is_crowbar()) + if(open && paicard) + to_chat(user, span_notice("You are attempting to remove the pAI..")) + if(do_after(user,10 * O.toolspeed)) + ejectpai(user) else ..() @@ -203,6 +231,13 @@ if(LAZYLEN(can_go)) if(step_towards(src, pick(can_go))) return + for(var/mob in loc) + if(istype(mob, /mob/living/bot) && mob != src) // Same as above, but we also don't want to have bots ontop of bots. Cleanbots shouldn't stack >:( + var/turf/my_turf = get_turf(src) + var/list/can_go = my_turf.CardinalTurfsWithAccess(botcard) + if(LAZYLEN(can_go)) + if(step_towards(src, pick(can_go))) + return handleIdle() /mob/living/bot/proc/handleRegular() @@ -342,6 +377,7 @@ resetTarget() patrol_path = list() ignore_list = list() + update_canmove() return 1 /mob/living/bot/proc/turn_off() @@ -349,11 +385,17 @@ busy = 0 // If ever stuck... reboot! set_light(0) update_icons() + update_canmove() /mob/living/bot/proc/explode() + if(paicard) + ejectpai() + release_vore_contents() qdel(src) /mob/living/bot/is_sentient() + if(paicard) + return TRUE return FALSE /******************************************************************/ @@ -443,3 +485,81 @@ /mob/living/bot/isSynthetic() //Robots are synthetic, no? return 1 + +/mob/living/bot/update_canmove() + ..() + canmove = on + return canmove + +/mob/living/bot/proc/insertpai(mob/user, obj/item/device/paicard/card) + //var/obj/item/paicard/card = I + var/mob/living/silicon/pai/AI = card.pai + if(paicard) + to_chat(user, span_notice("This bot is already under PAI Control!")) + return + if(!istype(card)) // TODO: Add sleevecard support. + return + if(client) + to_chat(user, span_notice("Higher levels of processing are already present!")) + return + if(!card.pai) + to_chat(user, span_notice("This card does not currently have a personality!")) + return + paicard = card + user.unEquip(card) + card.forceMove(src) + src.ckey = AI.ckey + name = AI.name + ooc_notes = AI.ooc_notes + to_chat(src, span_notice("You feel a tingle in your circuits as your systems interface with \the [initial(src.name)].")) + if(AI.idcard.access) + botcard.access |= AI.idcard.access + +/mob/living/bot/proc/ejectpai(mob/user) + if(paicard) + var/mob/living/silicon/pai/AI = paicard.pai + AI.ckey = src.ckey + AI.ooc_notes = ooc_notes + paicard.forceMove(src.loc) + paicard = null + name = initial(name) + botcard.access = botcard_access.Copy() + to_chat(AI, span_notice("You feel a tad claustrophobic as your mind closes back into your card, ejecting from \the [initial(src.name)].")) + + if(user) + to_chat(user, span_notice("You eject the card from \the [initial(src.name)].")) + +/mob/living/bot/verb/bot_nom(var/mob/living/T in oview(1)) + set name = "Bot Nom" + set category = "Bot Commands" + set desc = "Allows you to eat someone. Yum." + + if (stat != CONSCIOUS) + return + return feed_grabbed_to_self(src,T) + +/mob/living/bot/verb/ejectself() + set name = "Eject pAI" + set category = "Bot Commands" + set desc = "Eject your card, return to smole." + + return ejectpai() + +/mob/living/bot/Login() + no_vore = FALSE // ROBOT VORE + init_vore() // ROBOT VORE + verbs |= /mob/living/proc/insidePanel + + return ..() + +/mob/living/bot/Logout() + no_vore = TRUE // ROBOT VORE + release_vore_contents() + init_vore() // ROBOT VORE + verbs -= /mob/living/proc/insidePanel + no_vore = TRUE + devourable = FALSE + feeding = FALSE + can_be_drop_pred = FALSE + + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index 061574bd64..c6d790adeb 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -10,6 +10,7 @@ wait_if_pulled = 1 min_target_dist = 0 + var/cTimeMult = 1 // A multiplier for how long it should take to clean. Anything bigger than one will increase time, less than one will make it faster. var/vocal = 1 var/cleaning = 0 var/wet_floors = 0 @@ -99,31 +100,53 @@ if(get_turf(target) == src.loc) UnarmedAttack(target) -/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity) +//mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity) +/mob/living/bot/cleanbot/UnarmedAttack(atom/D, var/proximity) if(!..()) return - if(!istype(D)) - return + //if(!istype(D)) + // return if(D.loc != loc) return busy = 1 - if(prob(20)) - custom_emote(2, "begins to clean up \the [D]") update_icons() - var/cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50 - if(do_after(src, cleantime)) - if(istype(loc, /turf/simulated)) - var/turf/simulated/f = loc - f.dirt = 0 - if(!D) - return - qdel(D) - if(D == target) - cleanbot_reserved_turfs -= target - target = null + var/cleantime = 0 + if(istype(D, /obj/effect/decal/cleanable)) + cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50 + if(prob(20)) + custom_emote(2, "begins to clean up \the [D]") + if(do_after(src, cleantime * cTimeMult)) + if(istype(loc, /turf/simulated)) + var/turf/simulated/f = loc + f.dirt = 0 + if(!D) + return + qdel(D) + if(D == target) + cleanbot_reserved_turfs -= target + target = null + else if(D == src) + for(var/obj/effect/O in loc) + if(istype(O, /obj/effect/decal/cleanable/dirt)) + cleantime += 10 + if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay)) + cleantime += 50 + if(cleantime != 0) + if(prob(20)) + custom_emote(2, "begins to clean up \the [loc]") + if(do_after(src, cleantime * cTimeMult)) + clean_blood() + if(istype(loc, /turf/simulated)) + var/turf/simulated/T = loc + T.dirt = 0 + for(var/obj/effect/O in loc) + if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay)) + qdel(O) + else + handleIdle() busy = 0 update_icons() @@ -140,8 +163,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - qdel(src) - return + //qdel(src) + return ..() /mob/living/bot/cleanbot/update_icons() if(busy) diff --git a/code/modules/mob/living/bot/ed209bot.dm b/code/modules/mob/living/bot/ed209bot.dm index 17d2da7878..8700988e59 100644 --- a/code/modules/mob/living/bot/ed209bot.dm +++ b/code/modules/mob/living/bot/ed209bot.dm @@ -49,7 +49,7 @@ s.start() new /obj/effect/decal/cleanable/blood/oil(Tsec) - qdel(src) + return ..() /mob/living/bot/secbot/ed209/handleRangedTarget() RangedAttack(target) diff --git a/code/modules/mob/living/bot/edCLNbot.dm b/code/modules/mob/living/bot/edCLNbot.dm index bbb1e9861d..5ef7cdf9c9 100644 --- a/code/modules/mob/living/bot/edCLNbot.dm +++ b/code/modules/mob/living/bot/edCLNbot.dm @@ -11,6 +11,7 @@ patrol_speed = 3 target_speed = 6 + cTimeMult = 0.3 // Big bois should be big fast :3 vocal = 1 cleaning = 0 @@ -68,8 +69,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - qdel(src) - return + //qdel(src) + return ..() /mob/living/bot/cleanbot/edCLN/tgui_data(mob/user) var/list/data = ..() diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index 083da22d3d..969bfc1c83 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -286,8 +286,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - qdel(src) - return + //qdel(src) + return ..() /mob/living/bot/farmbot/confirmTarget(var/atom/targ) diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm index 9e869e0d81..a7a7def771 100644 --- a/code/modules/mob/living/bot/floorbot.dm +++ b/code/modules/mob/living/bot/floorbot.dm @@ -42,7 +42,7 @@ data["on"] = on data["open"] = open data["locked"] = locked - + data["vocal"] = vocal data["amount"] = amount @@ -75,7 +75,7 @@ /mob/living/bot/floorbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return TRUE - + add_fingerprint(src) switch(action) @@ -85,7 +85,7 @@ else turn_on() . = TRUE - + if(locked && !issilicon(usr)) return @@ -302,7 +302,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - qdel(src) + //qdel(src) + return ..() /mob/living/bot/floorbot/proc/addTiles(var/am) amount += am diff --git a/code/modules/mob/living/bot/medbot.dm b/code/modules/mob/living/bot/medbot.dm index 39b0b882bb..ced48594f1 100644 --- a/code/modules/mob/living/bot/medbot.dm +++ b/code/modules/mob/living/bot/medbot.dm @@ -268,10 +268,10 @@ /mob/living/bot/medbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return TRUE - + usr.set_machine(src) add_fingerprint(usr) - + . = TRUE switch(action) if("power") @@ -348,8 +348,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - qdel(src) - return + //qdel(src) + return ..() /mob/living/bot/medbot/handleRegular() . = ..() diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 6613433572..f6a868d11a 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -128,7 +128,7 @@ /mob/living/bot/secbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) return - + add_fingerprint(usr) switch(action) @@ -379,7 +379,8 @@ s.start() new /obj/effect/decal/cleanable/blood/oil(Tsec) - qdel(src) + //qdel(src) + return ..() /mob/living/bot/secbot/proc/target_name(mob/living/T) if(ishuman(T)) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index fa75fb5e91..f2e4ffd67a 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -484,9 +484,6 @@ return istype(H.glasses, /obj/item/clothing/glasses/hud/health) else if(istype(M, /mob/living/silicon/robot)) var/mob/living/silicon/robot/R = M - switch(hudtype) - if("security") - return R.hudmode == "Security" - if("medical") - return R.hudmode == "Medical" + return R.sensor_type //VOREStation Add - Borgo sensors are now binary so just have them on or off + return 0 diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index e43a1de6b6..8591001d28 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -323,7 +323,7 @@ emp_act if(!stat) switch(hit_zone) - if("head")//Harder to score a stun but if you do it lasts a bit longer + if(BP_HEAD)//Harder to score a stun but if you do it lasts a bit longer if(prob(effective_force)) apply_effect(20, PARALYZE, blocked, soaked) visible_message("\The [src] has been knocked unconscious!") @@ -337,7 +337,7 @@ emp_act if(glasses && prob(33)) glasses.add_blood(src) update_inv_glasses(0) - if("chest")//Easier to score a stun but lasts less time + if(BP_TORSO)//Easier to score a stun but lasts less time if(prob(effective_force + 10)) apply_effect(6, WEAKEN, blocked, soaked) visible_message("\The [src] has been knocked down!") diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm index 23605b1067..34a7054643 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm @@ -1037,3 +1037,29 @@ species.has_glowing_eyes = !species.has_glowing_eyes update_eyes() to_chat(src, "Your eyes [species.has_glowing_eyes ? "are now" : "are no longer"] glowing.") + + + +/mob/living/carbon/human/proc/enter_cocoon() + set name = "Spin Cocoon" + set category = "Abilities" + if(!isturf(loc)) + to_chat(src, "You don't have enough space to spin a cocoon!") + return + + if(do_after(src, 25, exclusive = TASK_USER_EXCLUSIVE)) + var/obj/item/weapon/storage/vore_egg/bugcocoon/C = new(loc) + forceMove(C) + transforming = TRUE + var/datum/tgui_module/appearance_changer/cocoon/V = new(src, src) + V.tgui_interact(src) + + var/mob_holder_type = src.holder_type || /obj/item/weapon/holder + C.w_class = src.size_multiplier * 4 //Egg size and weight scaled to match occupant. + var/obj/item/weapon/holder/H = new mob_holder_type(C, src) + C.max_storage_space = H.w_class + C.icon_scale_x = 0.25 * C.w_class + C.icon_scale_y = 0.25 * C.w_class + C.update_transform() + //egg_contents -= src + C.contents -= src \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm index d75848b638..9328604382 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm @@ -596,3 +596,13 @@ YW CHANGE STOP*/ /datum/trait/neutral/submit_to_prey/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) H.verbs |= /mob/living/proc/lend_prey_control + +/datum/trait/neutral/vertical_nom + name = "Vertical Nom" + desc = "Allows you to consume people from up above." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/vertical_nom/apply(var/datum/species/S,var/mob/living/carbon/human/H) + ..(S,H) + H.verbs |= /mob/living/proc/vertical_nom diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm index 34ac638b1a..211d7eef1f 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm @@ -293,3 +293,13 @@ desc = "You can breathe under water." cost = 1 var_changes = list("water_breather" = 1) + +/datum/trait/positive/cocoon_tf + name = "Cocoon Spinner" + desc = "Allows you to build a cocoon around yourself, using it to transform your body if you desire." + cost = 1 + //custom_only = FALSE + +/datum/trait/positive/cocoon_tf/apply(var/datum/species/S,var/mob/living/carbon/human/H) + ..(S,H) + H.verbs |= /mob/living/carbon/human/proc/enter_cocoon \ No newline at end of file diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f06445165b..09147c527f 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -79,14 +79,21 @@ return 1 /mob/living/verb/succumb() - set hidden = 1 -// if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable - if (src.health < 0 && stat != DEAD) + set name = "Succumb to death" + set category = "IC" + set desc = "Press this button if you are in crit and wish to die. Use this sparingly (ending a scene, no medical, etc.)" + var/confirm1 = tgui_alert(usr, "Pressing this button will kill you instantenously! Are you sure you wish to proceed?", "Confirm wish to succumb", list("No","Yes")) + var/confirm2 = "No" + if(confirm1 == "Yes") + confirm2 = tgui_alert(usr, "Pressing this buttom will really kill you, no going back", "Are you sure?", list("Yes", "No")) //Swapped answers to protect from accidental double clicks. + if (src.health < 0 && stat != DEAD && confirm1 == "Yes" && confirm2 == "Yes") // Checking both confirm1 and confirm2 for good measure. I don't trust TGUI. src.death() to_chat(src, "You have given up life and succumbed to death.") else if(stat == DEAD) to_chat(src, "As much as you'd like, you can't die when already dead") + else if(confirm1 == "No" || confirm2 == "No") + to_chat(src, "You chose to live another day.") else to_chat(src, "You are not injured enough to succumb to death!") diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index d8b5b24a62..15bedb2016 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -1,435 +1,447 @@ -var/list/department_radio_keys = list( - ":r" = "right ear", ".r" = "right ear", - ":l" = "left ear", ".l" = "left ear", - ":i" = "intercom", ".i" = "intercom", - ":h" = "department", ".h" = "department", - ":+" = "special", ".+" = "special", //activate radio-specific special functions - ":c" = "Command", ".c" = "Command", - ":n" = "Science", ".n" = "Science", - ":m" = "Medical", ".m" = "Medical", - ":e" = "Engineering", ".e" = "Engineering", - ":k" = "Response Team", ".k" = "Response Team", - ":s" = "Security", ".s" = "Security", - ":w" = "whisper", ".w" = "whisper", - ":t" = "Mercenary", ".t" = "Mercenary", - ":x" = "Raider", ".x" = "Raider", - ":u" = "Supply", ".u" = "Supply", - ":v" = "Service", ".v" = "Service", - ":p" = "AI Private", ".p" = "AI Private", - ":y" = "Explorer", ".y" = "Explorer", - ":a" = "Talon", ".a" = "Talon", //VOREStation Add, - - ":R" = "right ear", ".R" = "right ear", - ":L" = "left ear", ".L" = "left ear", - ":I" = "intercom", ".I" = "intercom", - ":H" = "department", ".H" = "department", - ":C" = "Command", ".C" = "Command", - ":N" = "Science", ".N" = "Science", - ":M" = "Medical", ".M" = "Medical", - ":E" = "Engineering", ".E" = "Engineering", - ":k" = "Response Team", ".k" = "Response Team", - ":S" = "Security", ".S" = "Security", - ":W" = "whisper", ".W" = "whisper", - ":T" = "Mercenary", ".T" = "Mercenary", - ":X" = "Raider", ".X" = "Raider", - ":U" = "Supply", ".U" = "Supply", - ":V" = "Service", ".V" = "Service", - ":P" = "AI Private", ".P" = "AI Private", - ":Y" = "Explorer", ".Y" = "Explorer", - ":A" = "Talon", ".A" = "Talon", //VOREStation Add, - - // Cyrillic characters on the same keys on the Russian QWERTY (phonetic) layout - ":к" = "right ear", ".к" = "right ear", - ":д" = "left ear", ".д" = "left ear", - ":ш" = "intercom", ".ш" = "intercom", - ":р" = "department", ".р" = "department", - ":+" = "special", ".+" = "special", //activate radio-specific special functions - ":с" = "Command", ".с" = "Command", - ":т" = "Science", ".т" = "Science", - ":ь" = "Medical", ".ь" = "Medical", - ":у" = "Engineering", ".у" = "Engineering", - ":л" = "Response Team", ".л" = "Response Team", - ":ы" = "Security", ".ы" = "Security", - ":ц" = "whisper", ".ц" = "whisper", - ":е" = "Mercenary", ".е" = "Mercenary", - ":ч" = "Raider", ".ч" = "Raider", - ":г" = "Supply", ".г" = "Supply", - ":м" = "Service", ".м" = "Service", - ":з" = "AI Private", ".з" = "AI Private", - ":н" = "Explorer", ".н" = "Explorer", - ":ф" = "Talon", ".ф" = "Talon" //VOREStation Add -) - - -var/list/channel_to_radio_key = new -/proc/get_radio_key_from_channel(var/channel) - var/key = channel_to_radio_key[channel] - if(!key) - for(var/radio_key in department_radio_keys) - if(department_radio_keys[radio_key] == channel) - key = radio_key - break - if(!key) - key = "" - channel_to_radio_key[channel] = key - - return key - -/mob/living/proc/binarycheck() - return FALSE - -/mob/proc/get_default_language() - return null - -/mob/living/get_default_language() - return default_language - -//Takes a list of the form list(message, verb, whispering) and modifies it as needed -//Returns 1 if a speech problem was applied, 0 otherwise -/mob/living/proc/handle_speech_problems(var/list/message_data) - var/list/message_pieces = message_data[1] - var/verb = message_data[2] - var/whispering = message_data[3] - . = 0 - - // Technically this rerolls the verb for as many say pieces as there are. _shrug_ - for(var/datum/multilingual_say_piece/S in message_pieces) - if(S.speaking && (S.speaking.flags & NO_STUTTER || S.speaking.flags & SIGNLANG)) - continue - - if((HULK in mutations) && health >= 25 && length(S.message)) - S.message = "[uppertext(S.message)]!!!" - verb = pick("yells","roars","hollers") - whispering = 0 - . = 1 - if(slurring) - S.message = slur(S.message) - verb = pick("slobbers","slurs") - . = 1 - if(stuttering) - S.message = stutter(S.message) - verb = pick("stammers","stutters") - . = 1 - //VOREStation Edit Start - if(muffled) - verb = pick("muffles") - whispering = 1 - . = 1 - //VOREStation Edit End - //YW Edit start - if(wingdings) - S.message = span("wingdings",(S.message)) - . = 1 - //YW Edit End - - message_data[1] = message_pieces - message_data[2] = verb - message_data[3] = whispering - -/mob/living/proc/handle_message_mode(message_mode, list/message_pieces, verb, used_radios) - if(message_mode == "intercom") - for(var/obj/item/device/radio/intercom/I in view(1, null)) - I.talk_into(src, message_pieces, verb) - used_radios += I - return 0 - -/mob/living/proc/handle_speech_sound() - var/list/returns[2] - returns[1] = null - returns[2] = null - return returns - -/mob/living/proc/get_speech_ending(verb, var/ending) - if(ending == "!") - return pick("exclaims","shouts","yells") - if(ending == "?") - return "asks" - return verb - -/mob/living/say(var/message, var/whispering = 0) - //If you're muted for IC chat - if(client) - if(message) - client.handle_spam_prevention(MUTE_IC) - if((client.prefs.muted & MUTE_IC) || say_disabled) - to_chat(src, "You cannot speak in IC (Muted).") - return - - //Redirect to say_dead if talker is dead - if(stat) - if(stat == DEAD && !forbid_seeing_deadchat) - return say_dead(message) - return - //VOREStation Addition Start - if(forced_psay) - psay(message) - return - //VOREStation Addition End - //Parse the mode - var/message_mode = parse_message_mode(message, "headset") - - //Maybe they are using say/whisper to do a quick emote, so do those - switch(copytext(message, 1, 2)) - if("*") return emote(copytext(message, 2)) - if("^") return custom_emote(1, copytext(message, 2)) - - //Parse the radio code and consume it - if(message_mode) - if(message_mode == "headset") - message = copytext(message, 2) //it would be really nice if the parse procs could do this for us. - else if(message_mode == "whisper") - whispering = 1 - message_mode = null - message = copytext(message, 3) - else - message = copytext(message, 3) - - //Clean up any remaining space on the left - message = trim_left(message) - - // VOREStation Edit - Reflect messages as needed, no sanitizing because parse_languages will handle it for us - if(reflect_if_needed(message, src)) - return - // VOREStation Edit End - - //Parse the language code and consume it - var/list/message_pieces = parse_languages(message) - if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quark for dealing with hivemind/signlang languages. - var/datum/multilingual_say_piece/S = message_pieces // Yay for BYOND's hilariously broken typecasting for allowing us to do this. - S.speaking.broadcast(src, S.message) - return 1 - - if(!LAZYLEN(message_pieces)) - log_runtime(EXCEPTION("Message failed to generate pieces. [message] - [json_encode(message_pieces)]")) - return 0 - - // If you're muzzled, you can only speak sign language - // However, sign language is handled above. - if(is_muzzled()) - to_chat(src, "You're muzzled and cannot speak!") - return - - //Whisper vars - var/w_scramble_range = 5 //The range at which you get ***as*th**wi**** - var/w_adverb //An adverb prepended to the verb in whispers - var/w_not_heard //The message for people in watching range - - var/datum/multilingual_say_piece/first_piece = message_pieces[1] - var/verb = "" - //Handle language-specific verbs and adverb setup if necessary - if(!whispering) //Just doing normal 'say' (for now, may change below) - verb = say_quote(message, first_piece.speaking) - else if(whispering && first_piece.speaking.whisper_verb) //Language has defined whisper verb - verb = first_piece.speaking.whisper_verb - w_not_heard = "[verb] something" - else //Whispering but language has no whisper verb, use say verb - w_adverb = pick("quietly", "softly") - verb = first_piece.speaking.speech_verb - w_not_heard = "[first_piece.speaking.speech_verb] something [w_adverb]" - - //For speech disorders (hulk, slurring, stuttering) - var/list/message_data = list(message_pieces, verb, whispering) - if(handle_speech_problems(message_data)) - message_pieces = message_data[1] - whispering = message_data[3] - - if(verb != message_data[2]) //They changed our verb - if(whispering) - w_adverb = pick("quietly", "softly") - verb = message_data[2] - - //Whisper may have adverbs, add those if one was set - if(w_adverb) - verb = "[verb] [w_adverb]" - - //If something nulled or emptied the message, forget it - if(!LAZYLEN(message_pieces)) - return 0 - - //Radio message handling - var/list/used_radios = list() - if(handle_message_mode(message_mode, message_pieces, verb, used_radios, whispering)) - return 1 - - //For languages with actual speech sounds - var/list/handle_v = handle_speech_sound() - var/sound/speech_sound = handle_v[1] - var/sound_vol = handle_v[2] - - //Default range and italics, may be overridden past here - var/message_range = world.view - var/italics = 0 - - //Speaking into radios - if(used_radios.len) - italics = 1 - message_range = 1 - - if(first_piece.speaking) - message_range = first_piece.speaking.get_talkinto_msg_range(message) - var/msg - if(!first_piece.speaking || !(first_piece.speaking.flags & NO_TALK_MSG)) - msg = "[src] talks into [used_radios[1]]" - - if(msg) - for(var/mob/living/M in hearers(5, src) - src) - M.show_message(msg) - - if(speech_sound) - sound_vol *= 0.5 - - //Set vars if we're still whispering by this point - if(whispering) - italics = 1 - message_range = 1 - sound_vol *= 0.5 - - //VOREStation edit - allows for custom say verbs, overriding all other say-verb types- e.g. "says loudly" instead of "shouts" - //You'll still stammer if injured or slur if drunk, but it won't have those specific words - var/ending = copytext(message, length(message)) - - if(custom_whisper && whispering) - verb = "[custom_whisper]" - else if(custom_exclaim && ending=="!") - verb = "[custom_exclaim]" - else if(custom_ask && ending=="?") - verb = "[custom_ask]" - else if(custom_say) - verb = "[custom_say]" - //VOREStation edit ends - - //Handle nonverbal languages here - for(var/datum/multilingual_say_piece/S in message_pieces) - if(S.speaking.flags & NONVERBAL) - custom_emote(1, "[pick(S.speaking.signlang_verb)].") - - //These will contain the main receivers of the message - var/list/listening = list() - var/list/listening_obj = list() - - //Atmosphere calculations (speaker's side only, for now) - var/turf/T = get_turf(src) - if(T) - //Air is too thin to carry sound at all, contact speech only - var/datum/gas_mixture/environment = T.return_air() - var/pressure = environment ? environment.return_pressure() : 0 - if(pressure < SOUND_MINIMUM_PRESSURE) - message_range = 1 - - //Air is nearing minimum levels, make text italics as a hint, and muffle sound - if(pressure < ONE_ATMOSPHERE * 0.4) - italics = 1 - sound_vol *= 0.5 - - //Obtain the mobs and objects in the message range - var/list/results = get_mobs_and_objs_in_view_fast(T, world.view, remote_ghosts = client ? TRUE : FALSE) - listening = results["mobs"] - listening_obj = results["objs"] - else - return 1 //If we're in nullspace, then forget it. - - //Remember the speech images so we can remove them later and they can get GC'd - var/list/images_to_clients = list() - - //The 'post-say' static speech bubble - var/speech_bubble_test = say_test(message) - //var/image/speech_bubble = image('icons/mob/talk_vr.dmi',src,"h[speech_bubble_test]") //VOREStation Edit. Commented this out in case we need to reenable. - var/speech_type = speech_bubble_appearance() - var/image/speech_bubble = generate_speech_bubble(src, "[speech_type][speech_bubble_test]") - var/sb_alpha = 255 - var/atom/loc_before_turf = src - //VOREStation Add - if(isbelly(loc)) - speech_bubble.pixel_y = -13 //teehee - //VOREStation Add End - while(loc_before_turf && !isturf(loc_before_turf.loc)) - loc_before_turf = loc_before_turf.loc - sb_alpha -= 50 - if(sb_alpha < 0) - break - speech_bubble.loc = loc_before_turf - speech_bubble.alpha = CLAMP(sb_alpha, 0, 255) - images_to_clients[speech_bubble] = list() - - //Main 'say' and 'whisper' message delivery - for(var/mob/M in listening) - spawn(0) //Using spawns to queue all the messages for AFTER this proc is done, and stop runtimes - - if(M && src) //If we still exist, when the spawn processes - //VOREStation Add - Ghosts don't hear whispers - if(whispering && !is_preference_enabled(/datum/client_preference/whisubtle_vis) && isobserver(M) && !M.client?.holder) - M.show_message("[src.name] [w_not_heard].", 2) - return - //VOREStation Add End - - var/dst = get_dist(get_turf(M),get_turf(src)) - var/runechat_enabled = M.client?.is_preference_enabled(/datum/client_preference/runechat_mob) - - if(dst <= message_range || (M.stat == DEAD && !forbid_seeing_deadchat)) //Inside normal message range, or dead with ears (handled in the view proc) - if(M.client && !runechat_enabled) - var/image/I1 = listening[M] || speech_bubble - images_to_clients[I1] |= M.client - M << I1 - M.hear_say(message_pieces, verb, italics, src, speech_sound, sound_vol) - if(whispering && !isobserver(M)) //Don't even bother with these unless whispering - if(dst > message_range && dst <= w_scramble_range) //Inside whisper scramble range - if(M.client && !runechat_enabled) - var/image/I2 = listening[M] || speech_bubble - images_to_clients[I2] |= M.client - M << I2 - M.hear_say(stars_all(message_pieces), verb, italics, src, speech_sound, sound_vol*0.2) - if(dst > w_scramble_range && dst <= world.view) //Inside whisper 'visible' range - M.show_message("[name] [w_not_heard].", 2) - - //Object message delivery - for(var/obj/O in listening_obj) - spawn(0) - if(O && src) //If we still exist, when the spawn processes - var/dst = get_dist(get_turf(O),get_turf(src)) - if(dst <= message_range) - O.hear_talk(src, message_pieces, verb) - - //Remove all those images. At least it's just ONE spawn this time. - spawn(30) - for(var/image/I as anything in images_to_clients) - var/list/clients_from_image = images_to_clients[I] - for(var/client/C as anything in clients_from_image) - if(C) //Could have disconnected after message sent, before removing bubble. - C.images -= I - qdel(I) - - //Log the message to file - if(message_mode) - message = "([message_mode == "headset" ? "Common" : capitalize(message_mode)]) [message]" //Adds radio keys used if available - if(whispering) - log_whisper(message, src) - else - log_say(message, src) - return 1 - -/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language) - var/turf/T = get_turf(src) - //We're in something, gesture to people inside the same thing - if(loc != T) - for(var/mob/M in loc) - M.hear_signlang(message, verb, language, src) - - //We're on a turf, gesture to visible as if we were a normal language - else - var/list/potentials = get_mobs_and_objs_in_view_fast(T, world.view) - var/list/mobs = potentials["mobs"] - for(var/mob/M as anything in mobs) - M.hear_signlang(message, verb, language, src) - var/list/objs = potentials["objs"] - for(var/obj/O as anything in objs) - O.hear_signlang(message, verb, language, src) - return 1 - -/obj/effect/speech_bubble - var/mob/parent - -/mob/proc/GetVoice() - return name - -/mob/proc/speech_bubble_appearance() - return "normal" +var/list/department_radio_keys = list( + ":r" = "right ear", ".r" = "right ear", + ":l" = "left ear", ".l" = "left ear", + ":i" = "intercom", ".i" = "intercom", + ":h" = "department", ".h" = "department", + ":+" = "special", ".+" = "special", //activate radio-specific special functions + ":c" = "Command", ".c" = "Command", + ":n" = "Science", ".n" = "Science", + ":m" = "Medical", ".m" = "Medical", + ":e" = "Engineering", ".e" = "Engineering", + ":k" = "Response Team", ".k" = "Response Team", + ":s" = "Security", ".s" = "Security", + ":w" = "whisper", ".w" = "whisper", + ":t" = "Mercenary", ".t" = "Mercenary", + ":x" = "Raider", ".x" = "Raider", + ":u" = "Supply", ".u" = "Supply", + ":v" = "Service", ".v" = "Service", + ":p" = "AI Private", ".p" = "AI Private", + ":y" = "Explorer", ".y" = "Explorer", + ":a" = "Talon", ".a" = "Talon", //VOREStation Add, + + ":R" = "right ear", ".R" = "right ear", + ":L" = "left ear", ".L" = "left ear", + ":I" = "intercom", ".I" = "intercom", + ":H" = "department", ".H" = "department", + ":C" = "Command", ".C" = "Command", + ":N" = "Science", ".N" = "Science", + ":M" = "Medical", ".M" = "Medical", + ":E" = "Engineering", ".E" = "Engineering", + ":k" = "Response Team", ".k" = "Response Team", + ":S" = "Security", ".S" = "Security", + ":W" = "whisper", ".W" = "whisper", + ":T" = "Mercenary", ".T" = "Mercenary", + ":X" = "Raider", ".X" = "Raider", + ":U" = "Supply", ".U" = "Supply", + ":V" = "Service", ".V" = "Service", + ":P" = "AI Private", ".P" = "AI Private", + ":Y" = "Explorer", ".Y" = "Explorer", + ":A" = "Talon", ".A" = "Talon", //VOREStation Add, + + // Cyrillic characters on the same keys on the Russian QWERTY (phonetic) layout + ":к" = "right ear", ".к" = "right ear", + ":д" = "left ear", ".д" = "left ear", + ":ш" = "intercom", ".ш" = "intercom", + ":р" = "department", ".р" = "department", + ":+" = "special", ".+" = "special", //activate radio-specific special functions + ":с" = "Command", ".с" = "Command", + ":т" = "Science", ".т" = "Science", + ":ь" = "Medical", ".ь" = "Medical", + ":у" = "Engineering", ".у" = "Engineering", + ":л" = "Response Team", ".л" = "Response Team", + ":ы" = "Security", ".ы" = "Security", + ":ц" = "whisper", ".ц" = "whisper", + ":е" = "Mercenary", ".е" = "Mercenary", + ":ч" = "Raider", ".ч" = "Raider", + ":г" = "Supply", ".г" = "Supply", + ":м" = "Service", ".м" = "Service", + ":з" = "AI Private", ".з" = "AI Private", + ":н" = "Explorer", ".н" = "Explorer", + ":ф" = "Talon", ".ф" = "Talon" //VOREStation Add +) + + +var/list/channel_to_radio_key = new +/proc/get_radio_key_from_channel(var/channel) + var/key = channel_to_radio_key[channel] + if(!key) + for(var/radio_key in department_radio_keys) + if(department_radio_keys[radio_key] == channel) + key = radio_key + break + if(!key) + key = "" + channel_to_radio_key[channel] = key + + return key + +/mob/living/proc/binarycheck() + return FALSE + +/mob/proc/get_default_language() + return null + +/mob/living/get_default_language() + return default_language + +//Takes a list of the form list(message, verb, whispering) and modifies it as needed +//Returns 1 if a speech problem was applied, 0 otherwise +/mob/living/proc/handle_speech_problems(var/list/message_data) + var/list/message_pieces = message_data[1] + var/verb = message_data[2] + var/whispering = message_data[3] + . = 0 + + // Technically this rerolls the verb for as many say pieces as there are. _shrug_ + for(var/datum/multilingual_say_piece/S in message_pieces) + if(S.speaking && (S.speaking.flags & NO_STUTTER || S.speaking.flags & SIGNLANG)) + continue + + if((HULK in mutations) && health >= 25 && length(S.message)) + S.message = "[uppertext(S.message)]!!!" + verb = pick("yells","roars","hollers") + whispering = 0 + . = 1 + if(slurring) + S.message = slur(S.message) + verb = pick("slobbers","slurs") + . = 1 + if(stuttering) + S.message = stutter(S.message) + verb = pick("stammers","stutters") + . = 1 + //VOREStation Edit Start + if(muffled) + verb = pick("muffles") + whispering = 1 + . = 1 + //VOREStation Edit End + //YW Edit start + if(wingdings) + S.message = span("wingdings",(S.message)) + . = 1 + //YW Edit End + + message_data[1] = message_pieces + message_data[2] = verb + message_data[3] = whispering + +/mob/living/proc/handle_message_mode(message_mode, list/message_pieces, verb, used_radios) + if(message_mode == "intercom") + for(var/obj/item/device/radio/intercom/I in view(1, null)) + I.talk_into(src, message_pieces, verb) + used_radios += I + return 0 + +/mob/living/proc/handle_speech_sound() + var/list/returns[2] + returns[1] = null + returns[2] = null + return returns + +/mob/living/proc/get_speech_ending(verb, var/ending) + if(ending == "!") + return pick("exclaims","shouts","yells") + if(ending == "?") + return "asks" + return verb + +/mob/living/say(var/message, var/whispering = 0) + //If you're muted for IC chat + if(client) + if(message) + client.handle_spam_prevention(MUTE_IC) + if((client.prefs.muted & MUTE_IC) || say_disabled) + to_chat(src, "You cannot speak in IC (Muted).") + return + + //Redirect to say_dead if talker is dead + if(stat) + if(stat == DEAD && !forbid_seeing_deadchat) + return say_dead(message) + return + //VOREStation Addition Start + if(forced_psay) + psay(message) + return + //VOREStation Addition End + //Parse the mode + var/message_mode = parse_message_mode(message, "headset") + + //Maybe they are using say/whisper to do a quick emote, so do those + switch(copytext(message, 1, 2)) + if("*") return emote(copytext(message, 2)) + if("^") return custom_emote(1, copytext(message, 2)) + + //Parse the radio code and consume it + if(message_mode) + if(message_mode == "headset") + message = copytext(message, 2) //it would be really nice if the parse procs could do this for us. + else if(message_mode == "whisper") + whispering = 1 + message_mode = null + message = copytext(message, 3) + else + message = copytext(message, 3) + + //Clean up any remaining space on the left + message = trim_left(message) + + // VOREStation Edit - Reflect messages as needed, no sanitizing because parse_languages will handle it for us + if(reflect_if_needed(message, src)) + return + // VOREStation Edit End + + //Parse the language code and consume it + var/list/message_pieces = parse_languages(message) + if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quark for dealing with hivemind/signlang languages. + var/datum/multilingual_say_piece/S = message_pieces // Yay for BYOND's hilariously broken typecasting for allowing us to do this. + S.speaking.broadcast(src, S.message) + return 1 + + if(!LAZYLEN(message_pieces)) + log_runtime(EXCEPTION("Message failed to generate pieces. [message] - [json_encode(message_pieces)]")) + return 0 + + // If you're muzzled, you can only speak sign language + // However, sign language is handled above. + if(is_muzzled()) + to_chat(src, "You're muzzled and cannot speak!") + return + + //Whisper vars + var/w_scramble_range = 5 //The range at which you get ***as*th**wi**** + var/w_adverb //An adverb prepended to the verb in whispers + var/w_not_heard //The message for people in watching range + + var/datum/multilingual_say_piece/first_piece = message_pieces[1] + var/verb = "" + //Handle language-specific verbs and adverb setup if necessary + if(!whispering) //Just doing normal 'say' (for now, may change below) + verb = say_quote(message, first_piece.speaking) + else if(whispering && first_piece.speaking.whisper_verb) //Language has defined whisper verb + verb = first_piece.speaking.whisper_verb + w_not_heard = "[verb] something" + else //Whispering but language has no whisper verb, use say verb + w_adverb = pick("quietly", "softly") + verb = first_piece.speaking.speech_verb + w_not_heard = "[first_piece.speaking.speech_verb] something [w_adverb]" + + //For speech disorders (hulk, slurring, stuttering) + var/list/message_data = list(message_pieces, verb, whispering) + if(handle_speech_problems(message_data)) + message_pieces = message_data[1] + whispering = message_data[3] + + if(verb != message_data[2]) //They changed our verb + if(whispering) + w_adverb = pick("quietly", "softly") + verb = message_data[2] + + //Whisper may have adverbs, add those if one was set + if(w_adverb) + verb = "[verb] [w_adverb]" + + //If something nulled or emptied the message, forget it + if(!LAZYLEN(message_pieces)) + return 0 + + //Radio message handling + var/list/used_radios = list() + if(handle_message_mode(message_mode, message_pieces, verb, used_radios, whispering)) + return 1 + + //For languages with actual speech sounds + var/list/handle_v = handle_speech_sound() + var/sound/speech_sound = handle_v[1] + var/sound_vol = handle_v[2] + + //Default range and italics, may be overridden past here + var/message_range = world.view + var/italics = 0 + + //Speaking into radios + if(used_radios.len) + italics = 1 + message_range = 1 + + if(first_piece.speaking) + message_range = first_piece.speaking.get_talkinto_msg_range(message) + var/msg + if(!first_piece.speaking || !(first_piece.speaking.flags & NO_TALK_MSG)) + msg = "[src] talks into [used_radios[1]]" + + if(msg) + for(var/mob/living/M in hearers(5, src) - src) + M.show_message(msg) + + if(speech_sound) + sound_vol *= 0.5 + + //Set vars if we're still whispering by this point + if(whispering) + italics = 1 + message_range = 1 + sound_vol *= 0.5 + + //VOREStation edit - allows for custom say verbs, overriding all other say-verb types- e.g. "says loudly" instead of "shouts" + //You'll still stammer if injured or slur if drunk, but it won't have those specific words + var/ending = copytext(message, length(message)) + + if(custom_whisper && whispering) + verb = "[custom_whisper]" + else if(custom_exclaim && ending=="!") + verb = "[custom_exclaim]" + else if(custom_ask && ending=="?") + verb = "[custom_ask]" + else if(custom_say) + verb = "[custom_say]" + //VOREStation edit ends + + //Handle nonverbal languages here + for(var/datum/multilingual_say_piece/S in message_pieces) + if((S.speaking.flags & NONVERBAL) || (S.speaking.flags & INAUDIBLE)) + custom_emote(1, "[pick(S.speaking.signlang_verb)].") + + //These will contain the main receivers of the message + var/list/listening = list() + var/list/listening_obj = list() + + //Atmosphere calculations (speaker's side only, for now) + var/turf/T = get_turf(src) + if(T) + //Air is too thin to carry sound at all, contact speech only + var/datum/gas_mixture/environment = T.return_air() + var/pressure = environment ? environment.return_pressure() : 0 + if(pressure < SOUND_MINIMUM_PRESSURE) + message_range = 1 + + //Air is nearing minimum levels, make text italics as a hint, and muffle sound + if(pressure < ONE_ATMOSPHERE * 0.4) + italics = 1 + sound_vol *= 0.5 + + //Obtain the mobs and objects in the message range + var/list/results = get_mobs_and_objs_in_view_fast(T, world.view, remote_ghosts = client ? TRUE : FALSE) + listening = results["mobs"] + listening_obj = results["objs"] + else + return 1 //If we're in nullspace, then forget it. + + //Remember the speech images so we can remove them later and they can get GC'd + var/list/images_to_clients = list() + + //The 'post-say' static speech bubble + var/speech_bubble_test = say_test(message) + //var/image/speech_bubble = image('icons/mob/talk_vr.dmi',src,"h[speech_bubble_test]") //VOREStation Edit. Commented this out in case we need to reenable. + var/speech_type = speech_bubble_appearance() + var/image/speech_bubble = generate_speech_bubble(src, "[speech_type][speech_bubble_test]") + var/sb_alpha = 255 + var/atom/loc_before_turf = src + //VOREStation Add + if(isbelly(loc)) + speech_bubble.pixel_y = -13 //teehee + //VOREStation Add End + while(loc_before_turf && !isturf(loc_before_turf.loc)) + loc_before_turf = loc_before_turf.loc + sb_alpha -= 50 + if(sb_alpha < 0) + break + speech_bubble.loc = loc_before_turf + speech_bubble.alpha = CLAMP(sb_alpha, 0, 255) + images_to_clients[speech_bubble] = list() + + //Main 'say' and 'whisper' message delivery + for(var/mob/M in listening) + spawn(0) //Using spawns to queue all the messages for AFTER this proc is done, and stop runtimes + + if(M && src) //If we still exist, when the spawn processes + //VOREStation Add - Ghosts don't hear whispers + if(whispering && !is_preference_enabled(/datum/client_preference/whisubtle_vis) && isobserver(M) && !M.client?.holder) + M.show_message("[src.name] [w_not_heard].", 2) + return + //VOREStation Add End + + var/dst = get_dist(get_turf(M),get_turf(src)) + var/runechat_enabled = M.client?.is_preference_enabled(/datum/client_preference/runechat_mob) + + if(dst <= message_range || (M.stat == DEAD && !forbid_seeing_deadchat)) //Inside normal message range, or dead with ears (handled in the view proc) + if(M.client && !runechat_enabled) + var/image/I1 = listening[M] || speech_bubble + images_to_clients[I1] |= M.client + M << I1 + M.hear_say(message_pieces, verb, italics, src, speech_sound, sound_vol) + if(whispering && !isobserver(M)) //Don't even bother with these unless whispering + if(dst > message_range && dst <= w_scramble_range) //Inside whisper scramble range + if(M.client && !runechat_enabled) + var/image/I2 = listening[M] || speech_bubble + images_to_clients[I2] |= M.client + M << I2 + M.hear_say(stars_all(message_pieces), verb, italics, src, speech_sound, sound_vol*0.2) + if(dst > w_scramble_range && dst <= world.view) //Inside whisper 'visible' range + M.show_message("[name] [w_not_heard].", 2) + + //Object message delivery + for(var/obj/O in listening_obj) + spawn(0) + if(O && src) //If we still exist, when the spawn processes + var/dst = get_dist(get_turf(O),get_turf(src)) + if(dst <= message_range) + O.hear_talk(src, message_pieces, verb) + + //Remove all those images. At least it's just ONE spawn this time. + spawn(30) + for(var/image/I as anything in images_to_clients) + var/list/clients_from_image = images_to_clients[I] + for(var/client/C as anything in clients_from_image) + if(C) //Could have disconnected after message sent, before removing bubble. + C.images -= I + qdel(I) + + //Log the message to file + if(message_mode) + message = "([message_mode == "headset" ? "Common" : capitalize(message_mode)]) [message]" //Adds radio keys used if available + if(whispering) + log_whisper(message, src) + else + log_say(message, src) + return 1 + +/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/verb_understood="gestures", var/datum/language/language, var/type = 1) + var/turf/T = get_turf(src) + //We're in something, gesture to people inside the same thing + if(loc != T) + for(var/mob/M in loc) + M.hear_signlang(message, verb, verb_understood, language, src, type) + + //We're on a turf, gesture to visible as if we were a normal language + else + var/low_range = FALSE + if(T && type == 2) // type 2 is audible signlang. yes. sue me. + //Air is too thin to carry sound at all, contact speech only + var/datum/gas_mixture/environment = T.return_air() + var/pressure = environment ? environment.return_pressure() : 0 + if(pressure < SOUND_MINIMUM_PRESSURE) + low_range = TRUE + + var/list/potentials = get_mobs_and_objs_in_view_fast(T, world.view) + var/list/mobs = potentials["mobs"] + for(var/mob/M as anything in mobs) + if(low_range && !(M in range(1, src))) + continue + M.hear_signlang(message, verb, verb_understood, language, src, type) + var/list/objs = potentials["objs"] + for(var/obj/O as anything in objs) + if(low_range && !(O in range(1, src))) + continue + O.hear_signlang(message, verb, language, src) + return 1 + +/obj/effect/speech_bubble + var/mob/parent + +/mob/proc/GetVoice() + return name + +/mob/proc/speech_bubble_appearance() + return "normal" diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index a2876c61aa..dd3fc5f064 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -787,9 +787,11 @@ var/list/ai_verbs_default = list( src.aiRadio.interact(src) /mob/living/silicon/ai/proc/sensor_mode() - set name = "Set Sensor Augmentation" + set name = "Toggle Sensor Augmentation" //VOREStation Add set category = "AI Settings" set desc = "Augment visual feed with internal sensor overlays" + sensor_type = !sensor_type //VOREStation Add + to_chat(usr, "You [sensor_type ? "enable" : "disable"] your sensors.") //VOREStation Add toggle_sensor_mode() /mob/living/silicon/ai/proc/toggle_hologram_movement() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 7df66eaff4..a1764fbcd2 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -127,7 +127,7 @@ pda.ownjob = "Personal Assistant" pda.owner = text("[]", src) pda.name = pda.owner + " (" + pda.ownjob + ")" - + var/datum/data/pda/app/messenger/M = pda.find_program(/datum/data/pda/app/messenger) if(M) M.toff = TRUE @@ -247,6 +247,9 @@ last_special = world.time + 100 + if(istype(card.loc, /obj/machinery)) // VOREStation edit, this statement allows pAIs stuck in a machine to eject themselves. + var/obj/machinery/M = card.loc + M.ejectpai() //I'm not sure how much of this is necessary, but I would rather avoid issues. if(istype(card.loc,/obj/item/rig_module)) to_chat(src, "There is no room to unfold inside this rig module. You're good and stuck.") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 552032ddee..f1d2b353cf 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1074,9 +1074,11 @@ to_chat(src, "Your icon has been set. You now require a module reset to change it.") /mob/living/silicon/robot/proc/sensor_mode() //Medical/Security HUD controller for borgs - set name = "Set Sensor Augmentation" + set name = "Toggle Sensor Augmentation" //VOREStation Add set category = "Robot Commands" set desc = "Augment visual feed with internal sensor overlays." + sensor_type = !sensor_type //VOREStation Add + to_chat(usr, "You [sensor_type ? "enable" : "disable"] your sensors.") //VOREStation Add toggle_sensor_mode() /mob/living/silicon/robot/proc/add_robot_verbs() diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station.dm b/code/modules/mob/living/silicon/robot/robot_modules/station.dm index c1d149d30c..d6a7ee6caa 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm @@ -338,6 +338,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/gripper/no_use/organ(src) src.modules += new /obj/item/weapon/gripper/medical(src) src.modules += new /obj/item/weapon/shockpaddles/robot(src) + src.modules += new /obj/item/weapon/inflatable_dispenser/robot(src) //VOREStation Add - This is kinda important for rescuing people without making it worse for everyone src.emag = new /obj/item/weapon/reagent_containers/spray(src) src.modules += new /obj/item/device/sleevemate(src) src.emag.reagents.add_reagent("pacid", 250) diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm index 30bc06d6c7..45935c90be 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm @@ -277,6 +277,7 @@ src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)//For holding the chemicals when the chemist is nice src.modules += new /obj/item/device/sleevemate(src) //Lets them scan people. src.modules += new /obj/item/weapon/shockpaddles/robot/hound(src) //Paws of life + src.modules += new /obj/item/weapon/inflatable_dispenser/robot(src) //This is kinda important for rescuing people without making it worse for everyone src.emag = new /obj/item/weapon/dogborg/pounce(src) //Pounce var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(2000) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 56b042e363..7caad30448 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -25,6 +25,8 @@ var/obj/item/weapon/card/id/idcard var/idcard_type = /obj/item/weapon/card/id/synthetic + var/sensor_type = 0 //VOREStation add - silicon omni "is sensor on or nah" + var/hudmode = null /mob/living/silicon/New() @@ -221,52 +223,36 @@ var/synth = (L in speech_synthesizer_langs) . += "[L.name] ([get_language_prefix()][L.key])[synth ? default_str : null]
Speech Synthesizer: [synth ? "YES" : "NOT SUPPORTED"]
[L.desc]

" -/mob/living/silicon/proc/toggle_sensor_mode() - var/sensor_type = tgui_input_list(usr, "Please select sensor type.", "Sensor Integration", list("Security","Medical","Disable")) - switch(sensor_type) - if ("Security") - if(plane_holder) - //Enable Security planes - plane_holder.set_vis(VIS_CH_ID,TRUE) - plane_holder.set_vis(VIS_CH_WANTED,TRUE) - plane_holder.set_vis(VIS_CH_IMPLOYAL,TRUE) - plane_holder.set_vis(VIS_CH_IMPTRACK,TRUE) - plane_holder.set_vis(VIS_CH_IMPCHEM,TRUE) +/mob/living/silicon/proc/toggle_sensor_mode() //VOREStation Add to make borgs use omni starts here - Tank, clueless bird + if(sensor_type) + if(plane_holder) + //Enable the planes, its basically just AR-Bs + plane_holder.set_vis(VIS_CH_ID,TRUE) + plane_holder.set_vis(VIS_CH_WANTED,TRUE) + plane_holder.set_vis(VIS_CH_IMPLOYAL,TRUE) //antag related so prob not useful but leaving them in + plane_holder.set_vis(VIS_CH_IMPTRACK,TRUE) + plane_holder.set_vis(VIS_CH_IMPCHEM,TRUE) + plane_holder.set_vis(VIS_CH_STATUS_R,TRUE) + plane_holder.set_vis(VIS_CH_HEALTH_VR,TRUE) + plane_holder.set_vis(VIS_CH_BACKUP,TRUE) //backup stuff from silicon_vr is here now + return TRUE - //Disable Medical planes - plane_holder.set_vis(VIS_CH_STATUS,FALSE) - plane_holder.set_vis(VIS_CH_HEALTH,FALSE) + else + if(plane_holder) + //Disable the planes + plane_holder.set_vis(VIS_CH_ID,FALSE) + plane_holder.set_vis(VIS_CH_WANTED,FALSE) + plane_holder.set_vis(VIS_CH_IMPLOYAL,FALSE) + plane_holder.set_vis(VIS_CH_IMPTRACK,FALSE) + plane_holder.set_vis(VIS_CH_IMPCHEM,FALSE) + plane_holder.set_vis(VIS_CH_STATUS_R,FALSE) + plane_holder.set_vis(VIS_CH_HEALTH_VR,FALSE) + plane_holder.set_vis(VIS_CH_BACKUP,FALSE) + return FALSE - to_chat(src, "Security records overlay enabled.") - if ("Medical") - if(plane_holder) - //Disable Security planes - plane_holder.set_vis(VIS_CH_ID,FALSE) - plane_holder.set_vis(VIS_CH_WANTED,FALSE) - plane_holder.set_vis(VIS_CH_IMPLOYAL,FALSE) - plane_holder.set_vis(VIS_CH_IMPTRACK,FALSE) - plane_holder.set_vis(VIS_CH_IMPCHEM,FALSE) - - //Enable Medical planes - plane_holder.set_vis(VIS_CH_STATUS,TRUE) - plane_holder.set_vis(VIS_CH_HEALTH,TRUE) - - to_chat(src, "Life signs monitor overlay enabled.") - if ("Disable") - if(plane_holder) - //Disable Security planes - plane_holder.set_vis(VIS_CH_ID,FALSE) - plane_holder.set_vis(VIS_CH_WANTED,FALSE) - plane_holder.set_vis(VIS_CH_IMPLOYAL,FALSE) - plane_holder.set_vis(VIS_CH_IMPTRACK,FALSE) - plane_holder.set_vis(VIS_CH_IMPCHEM,FALSE) - - //Disable Medical planes - plane_holder.set_vis(VIS_CH_STATUS,FALSE) - plane_holder.set_vis(VIS_CH_HEALTH,FALSE) - to_chat(src, "Sensor augmentations disabled.") - - hudmode = sensor_type //This is checked in examine.dm on humans, so they can see medical/security records depending on mode +//hudmode = sensor_type //This is checked in examine.dm on humans, so they can see medical/security records depending on mode +//I made it work like omnis with records by adding stuff to examine.dm +//VOREStation Add ends here /mob/living/silicon/verb/pose() set name = "Set Pose" diff --git a/code/modules/mob/living/silicon/silicon_vr.dm b/code/modules/mob/living/silicon/silicon_vr.dm index 168b3facab..73a25dbd76 100644 --- a/code/modules/mob/living/silicon/silicon_vr.dm +++ b/code/modules/mob/living/silicon/silicon_vr.dm @@ -4,18 +4,18 @@ return 1 return ..() -// For handling any custom visibility in borgo sensor modes, like sleeve implants -/mob/living/silicon/toggle_sensor_mode() - . = ..() - switch(hudmode) // This is set in parent - if ("Security") - //Disable Medical planes - plane_holder?.set_vis(VIS_CH_BACKUP,FALSE) - - if ("Medical") - //Enable Medical planes - plane_holder?.set_vis(VIS_CH_BACKUP,TRUE) - - if ("Disable") - //Disable Medical planes - plane_holder?.set_vis(VIS_CH_BACKUP,FALSE) +// For handling any custom visibility in borgo sensor modes, like sleeve implants - not needed anymore but leaving anyways - Tank +///mob/living/silicon/toggle_sensor_mode() +// . = ..() +// switch(hudmode) // This is set in parent +// if ("Security") +// //Disable Medical planes +// plane_holder?.set_vis(VIS_CH_BACKUP,FALSE) +// +// if ("Medical") +// //Enable Medical planes +// plane_holder?.set_vis(VIS_CH_BACKUP,TRUE) +// +// if ("Disable") +// //Disable Medical planes +// plane_holder?.set_vis(VIS_CH_BACKUP,FALSE) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/cockroach.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/cockroach.dm index b170d192d0..29b54fad74 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/cockroach.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/cockroach.dm @@ -4,6 +4,7 @@ real_name = "cockroach" desc = "This station is just crawling with bugs." tt_desc = "E Blattella germanica" + icon = 'icons/mob/animal_vr.dmi' icon_state = "cockroach" item_state = "cockroach" icon_living = "cockroach" diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm index a5782f880c..4730c3ae4b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm +++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/xenobio.dm @@ -225,7 +225,11 @@ if(T.density) // No walls. continue for(var/atom/movable/AM in T) - if(AM.density || istype(AM, /mob/living/simple_mob/slime)) + if(istype(AM, /mob/living/simple_mob/slime) || !(AM.CanPass(src, T))) + free = FALSE + break + for(var/atom/movable/AM in get_turf(src)) + if(!(AM.CanPass(src, T)) && !(AM == src)) free = FALSE break @@ -238,7 +242,7 @@ var/list/babies = list() for(var/i = 1 to split_amount) - babies.Add(make_new_slime()) + babies.Add(make_new_slime(no_step = i)) var/mob/living/simple_mob/slime/new_slime = pick(babies) new_slime.universal_speak = universal_speak @@ -253,7 +257,7 @@ to_chat(src, span("warning", "I have not evolved enough to reproduce yet...")) // Used when reproducing or dying. -/mob/living/simple_mob/slime/xenobio/proc/make_new_slime(var/desired_type) +/mob/living/simple_mob/slime/xenobio/proc/make_new_slime(var/desired_type, var/no_step) var/t = src.type if(desired_type) t = desired_type @@ -275,7 +279,8 @@ baby.faction = faction baby.friends = friends.Copy() - step_away(baby, src) + if(no_step != 1) + step_away(baby, src) return baby /mob/living/simple_mob/slime/xenobio/get_description_interaction() diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index b36a1ee37c..4b72d56741 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -602,33 +602,33 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT) //The base miss chance for the different defence zones var/list/global/base_miss_chance = list( - "head" = 40, - "chest" = 10, - "groin" = 20, - "l_leg" = 20, - "r_leg" = 20, - "l_arm" = 20, - "r_arm" = 20, - "l_hand" = 50, - "r_hand" = 50, - "l_foot" = 50, - "r_foot" = 50, + BP_HEAD = 40, + BP_TORSO = 10, + BP_GROIN = 20, + BP_L_LEG = 20, + BP_R_LEG = 20, + BP_L_ARM = 20, + BP_R_ARM = 20, + BP_L_HAND = 50, + BP_R_HAND = 50, + BP_L_FOOT = 50, + BP_R_FOOT = 50, ) //Used to weight organs when an organ is hit randomly (i.e. not a directed, aimed attack). //Also used to weight the protection value that armour provides for covering that body part when calculating protection from full-body effects. var/list/global/organ_rel_size = list( - "head" = 25, - "chest" = 70, - "groin" = 30, - "l_leg" = 25, - "r_leg" = 25, - "l_arm" = 25, - "r_arm" = 25, - "l_hand" = 10, - "r_hand" = 10, - "l_foot" = 10, - "r_foot" = 10, + BP_HEAD = 25, + BP_TORSO = 70, + BP_GROIN = 30, + BP_L_LEG = 25, + BP_R_LEG = 25, + BP_L_ARM = 25, + BP_R_ARM = 25, + BP_L_HAND = 10, + BP_R_HAND = 10, + BP_L_FOOT = 10, + BP_R_FOOT = 10, ) /mob/proc/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash) diff --git a/code/modules/mob/new_player/sprite_accessories_taur_vr.dm b/code/modules/mob/new_player/sprite_accessories_taur_vr.dm index 320bea3898..f182b5792e 100644 --- a/code/modules/mob/new_player/sprite_accessories_taur_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_taur_vr.dm @@ -135,6 +135,13 @@ extra_overlay = "naga_markings" //icon_sprite_tag = "naga2c" +/datum/sprite_accessory/tail/taur/naga/alt_2c + name = "Naga alt style dual-color (Taur)" + suit_sprites = 'icons/mob/taursuits_naga_alt_vr.dmi' + icon_state = "altnaga_s" + extra_overlay = "altnaga_markings" + //icon_sprite_tag = "altnaga2c" + /datum/sprite_accessory/tail/taur/horse name = "Horse (Taur)" icon_state = "horse_s" diff --git a/code/modules/mob/new_player/sprite_accessories_wing_vr.dm b/code/modules/mob/new_player/sprite_accessories_wing_vr.dm index c747c4923b..e96a72bf7f 100644 --- a/code/modules/mob/new_player/sprite_accessories_wing_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_wing_vr.dm @@ -226,3 +226,12 @@ do_colouration = 1 color_blend_mode = ICON_MULTIPLY extra_overlay = "drago_wing_2" + +/datum/sprite_accessory/wing/aeromorph_flat + name = "aeromorph wings, flat" + desc = "" + icon_state = "aeromorph_flat" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + extra_overlay = "aeromorph_flat_1" + extra_overlay2 = "aeromorph_flat_2" diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index d51d048da1..646c82a168 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -249,7 +249,7 @@ // There are a few things that will make us want to ignore all other languages in - namely, HIVEMIND languages. var/datum/language/L = current[1] - if(L && (L.flags & HIVEMIND || L.flags & SIGNLANG)) + if(L && (L.flags & HIVEMIND || L.flags & SIGNLANG || L.flags & INAUDIBLE)) return new /datum/multilingual_say_piece(L, trim(sanitize(strip_prefixes(message)))) if(i + 1 > length(prefix_locations)) // We are out of lookaheads, that means the rest of the message is in cur lang diff --git a/code/modules/modular_computers/file_system/programs/generic/camera.dm b/code/modules/modular_computers/file_system/programs/generic/camera.dm index 57948d6e8a..41551e0cb0 100644 --- a/code/modules/modular_computers/file_system/programs/generic/camera.dm +++ b/code/modules/modular_computers/file_system/programs/generic/camera.dm @@ -9,10 +9,12 @@ switch(network) if(NETWORK_THUNDER) return 0 - if(NETWORK_ENGINE,NETWORK_ALARM_ATMOS,NETWORK_ALARM_FIRE,NETWORK_ALARM_POWER) + if(NETWORK_ENGINE,NETWORK_ENGINEERING,NETWORK_ALARM_ATMOS,NETWORK_ALARM_FIRE,NETWORK_ALARM_POWER) return access_engine if(NETWORK_CIRCUITS) return access_research + if(NETWORK_MINE) + return access_qm if(NETWORK_ERT) return access_cent_specops //VOREStation Add Start diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 264ef3d6b7..071bb05e91 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -77,12 +77,16 @@ var/const/CE_STABLE_THRESHOLD = 0.5 var/obj/item/organ/internal/heart/heart = internal_organs_by_name[O_HEART] if(!heart) + blood_volume_raw = 0 blood_volume = 0 else if(heart.is_broken()) + blood_volume_raw *= 0.3 blood_volume *= 0.3 else if(heart.is_bruised()) + blood_volume_raw *= 0.7 blood_volume *= 0.7 else if(heart.damage) + blood_volume_raw *= 0.8 blood_volume *= 0.8 //Effects of bloodloss diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 13d288c93a..708fe7fca4 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -384,5 +384,6 @@ /obj/item/device/toner name = "toner cartridge" + icon = 'icons/obj/device.dmi' icon_state = "tonercartridge" var/toner_amount = 30 diff --git a/code/modules/projectiles/guns/toy.dm b/code/modules/projectiles/guns/toy.dm index e3b90bd1be..a4ef0dbf3b 100644 --- a/code/modules/projectiles/guns/toy.dm +++ b/code/modules/projectiles/guns/toy.dm @@ -199,7 +199,52 @@ icon_state = initial(icon_state) else icon_state = "[initial(icon_state)]-e" +/* + * Cyborg + */ +/obj/item/weapon/gun/projectile/cyborgtoy + name = "\improper Donk-Soft Cyborg Blaster" + desc = "Donk-Soft Cyborg Blaster! It's Donk or Don't! Adult supervision required. Use to toggle between battle and cleanup mode." + icon = 'icons/obj/gun_toy.dmi' + icon_state = "smg" + caliber = "foam" + load_method = SINGLE_CASING + max_shells = 15 + var/cleanup = 0 + ammo_type = /obj/item/ammo_casing/afoam_dart + projectile_type = /obj/item/projectile/bullet/foam_dart + recoil = null + handle_casings = null +/obj/item/weapon/gun/projectile/cyborgtoy/attack_self(var/mob/user) + cleanup = !cleanup + to_chat(user, "The [src] is now on [cleanup ? "cleanup" : "battle"] mode.") + +/obj/item/weapon/gun/projectile/cyborgtoy/afterattack(atom/A, mob/living/user, adjacent, params) + if(cleanup) + if(!adjacent) + return 0 + collectammo(A, user) + return 0 + ..() + +/obj/item/weapon/gun/projectile/cyborgtoy/proc/collectammo(atom/A, user) + if(loaded.len >= max_shells) + to_chat(user, "The [src] is at max capacity.") + return + var/T = get_turf(A) + var/success = 0 + for(var/obj/item/ammo_casing/afoam_dart/D in T) + if(loaded.len >= max_shells) + break + D.loc = src + loaded.Insert(1, D) + success = 1 + if(success) + playsound(src, 'sound/machines/hiss.ogg', 50, 0) + to_chat(user, "The [src] vacuums in the darts!") + else + to_chat(user, "No Donk-Soft brand foam darts detected. Aborting.") /* * Laser Tag */ diff --git a/code/modules/reagents/reactions/instant/food.dm b/code/modules/reagents/reactions/instant/food.dm index 188e285623..d3f934051a 100644 --- a/code/modules/reagents/reactions/instant/food.dm +++ b/code/modules/reagents/reactions/instant/food.dm @@ -140,7 +140,7 @@ id = "dough" result = null required_reagents = list("egg" = 3, "flour" = 10) - inhibitors = list("water" = 1, "beer" = 1) //To prevent it messing with batter recipes + inhibitors = list("water" = 1, "beer" = 1, "sugar" = 1) //To prevent it messing with batter recipes result_amount = 1 /decl/chemical_reaction/instant/food/dough/on_reaction(var/datum/reagents/holder, var/created_volume) @@ -189,6 +189,13 @@ required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) result_amount = 15 +/decl/chemical_reaction/instant/food/cakebatter + name = "Cake Batter" + id = "cakebatter" + result = "cakebatter" + required_reagents = list("flour" = 15, "milk" = 10, "sugar" = 15, "egg" = 3) + result_amount = 60 + /decl/chemical_reaction/instant/food/butter name = "Butter" id = "butter" diff --git a/code/modules/reagents/reagent_containers/glass_vr.dm b/code/modules/reagents/reagent_containers/glass_vr.dm index e0d11cd585..350a64e224 100644 --- a/code/modules/reagents/reagent_containers/glass_vr.dm +++ b/code/modules/reagents/reagent_containers/glass_vr.dm @@ -53,6 +53,30 @@ name = "vial (amorphorovir)" prefill = list("amorphorovir" = 1) +/obj/item/weapon/reagent_containers/glass/beaker/vial/androrovir + name = "vial (androrovir)" + prefill = list("androrovir" = 1) + +/obj/item/weapon/reagent_containers/glass/beaker/vial/gynorovir + name = "vial (gynorovir)" + prefill = list("gynorovir" = 1) + +/obj/item/weapon/reagent_containers/glass/beaker/vial/androgynorovir + name = "vial (androgynorovir)" + prefill = list("androgynorovir" = 1) + +/obj/item/weapon/reagent_containers/glass/beaker/vial/macrocillin + name = "vial (macrocillin)" + prefill = list("macrocillin" = 1) + +/obj/item/weapon/reagent_containers/glass/beaker/vial/microcillin + name = "vial (microcillin)" + prefill = list("microcillin" = 1) + +/obj/item/weapon/reagent_containers/glass/beaker/vial/normalcillin + name = "vial (normalcillin)" + prefill = list("normalcillin" = 1) + /obj/item/weapon/reagent_containers/glass/beaker/vial/supermatter name = "vial (supermatter)" desc = "A glass vial containing the extremely dangerous results of grinding a shard of supermatter down to a fine powder." diff --git a/code/modules/reagents/reagents/food_drinks.dm b/code/modules/reagents/reagents/food_drinks.dm index 0323520e89..2b16a45f46 100644 --- a/code/modules/reagents/reagents/food_drinks.dm +++ b/code/modules/reagents/reagents/food_drinks.dm @@ -692,6 +692,13 @@ reagent_state = SOLID color = "#441a03" +/datum/reagent/cakebatter + name = "Cake Batter" + id = "cakebatter" + description = "A batter for making delicious cakes." + reagent_state = LIQUID + color = "#F0EDDA" + /datum/reagent/frostoil name = "Frost Oil" id = "frostoil" diff --git a/code/modules/research/prosfab_designs_vr.dm b/code/modules/research/prosfab_designs_vr.dm index bb15c848f8..8275a456c9 100644 --- a/code/modules/research/prosfab_designs_vr.dm +++ b/code/modules/research/prosfab_designs_vr.dm @@ -7,6 +7,13 @@ materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000) build_path = /obj/item/borg/upgrade/sizeshift +/datum/design/item/prosfab/robot_upgrade/sizegun + name = "Size Gun Module" + id = "borg_sizegun_module" + req_tech = list(TECH_COMBAT = 3, TECH_BLUESPACE = 3, TECH_MATERIAL = 3, TECH_POWER = 2) + materials = list(MAT_STEEL = 6000, MAT_GLASS = 4000) + build_path = /obj/item/borg/upgrade/sizegun + /datum/design/item/prosfab/robot_upgrade/bellysizeupgrade name = "Robohound Capacity Expansion Module" id = "borg_hound_capacity_module" diff --git a/code/modules/spells/targeted/projectile/projectile.dm b/code/modules/spells/targeted/projectile/projectile.dm index 7181d3c140..f98b71598c 100644 --- a/code/modules/spells/targeted/projectile/projectile.dm +++ b/code/modules/spells/targeted/projectile/projectile.dm @@ -33,7 +33,7 @@ If the spell_projectile is seeking, it will update its target every process and if(istype(projectile, /obj/item/projectile/spell_projectile)) var/obj/item/projectile/spell_projectile/SP = projectile SP.carried = src //casting is magical - projectile.def_zone = check_zone("chest") + projectile.def_zone = check_zone(BP_TORSO) projectile.old_style_target(target) projectile.fire() diff --git a/code/modules/stockmarket/computer.dm b/code/modules/stockmarket/computer.dm index 6d44e78d82..ffa09437c5 100644 --- a/code/modules/stockmarket/computer.dm +++ b/code/modules/stockmarket/computer.dm @@ -5,21 +5,36 @@ icon_state = "stockmarket" icon_screen = "stocks" icon_keyboard = "stockmarket_key" + circuit = /obj/item/weapon/circuitboard/stockexchange var/logged_in = "Cargo Department" var/vmode = 1 + + var/screen = "stocks" + var/datum/stock/current_stock = null + light_color = LIGHT_COLOR_GREEN /obj/machinery/computer/stockexchange/Initialize() . = ..() logged_in = "Cargo Department" +/obj/machinery/computer/stockexchange/Destroy() + return ..() + +/obj/machinery/computer/stockexchange/attackby(obj/item/W, mob/user, params) + ..() + SStgui.update_uis(src) + return + +/obj/machinery/computer/stockexchange/attack_ai(mob/user) + src.attack_hand(user) + /obj/machinery/computer/stockexchange/attack_hand(mob/user) if(..(user)) return - //if(!ai_control && issilicon(user)) - // to_chat(user, "Access Denied.") - // return TRUE + if(stat & (BROKEN|NOPOWER)) + return tgui_interact(user) @@ -51,56 +66,28 @@ sell_some_shares(S, usr) if("stocks_check") - var/dat = "Stock Transaction Logs

Stock Transaction Logs

Refresh

" - for(var/D in GLOB.stockExchange.logs) - var/datum/stock_log/L = D - if(istype(L, /datum/stock_log/buy)) - dat += "[L.time] | [L.user_name] bought [L.stocks] stocks at [L.shareprice] a share for [L.money] total credits in [L.company_name].
" - continue - if(istype(L, /datum/stock_log/sell)) - dat += "[L.time] | [L.user_name] sold [L.stocks] stocks at [L.shareprice] a share for [L.money] total credits from [L.company_name].
" - continue - if(istype(L, /datum/stock_log/borrow)) - dat += "[L.time] | [L.user_name] borrowed [L.stocks] stocks with a deposit of [L.money] credits in [L.company_name].
" - continue - var/datum/browser/popup = new(usr, "stock_logs", "Stock Transaction Logs", 600, 400) - popup.set_content(dat) - popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() + screen = "logs" if("stocks_archive") var/datum/stock/S = locate(params["share"]) - if (logged_in && logged_in != "") - var/list/LR = GLOB.stockExchange.last_read[S] - LR[logged_in] = world.time - var/dat = "News feed for [S.name]

News feed for [S.name]

Refresh
" - dat += "

Events

" - var/p = 0 - for (var/datum/stockEvent/E in S.events) - if (E.hidden) - continue - if (p > 0) - dat += "
" - dat += "
[E.current_title]
[E.current_desc]
" - p++ - dat += "

Articles

" - p = 0 - for (var/datum/article/A in S.articles) - if (p > 0) - dat += "
" - dat += "
[A.headline]
[A.subtitle]

[A.article]
- [A.author], [A.spacetime] (via [A.outlet])
" - p++ - dat += "
" - var/datum/browser/popup = new(usr, "archive_[S.name]", "Stock News", 600, 400) - popup.set_content(dat) - popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() + if(S) + current_stock = S + //if (logged_in && logged_in != "") + // var/list/LR = GLOB.stockExchange.last_read[S] + // LR[logged_in] = world.time + screen = "archive" if("stocks_history") var/datum/stock/S = locate(params["share"]) in GLOB.stockExchange.stocks if (S) + //current_stock = S + //screen = "graph" S.displayValues(usr) + if("stocks_backbutton") + current_stock = null + screen = "stocks" + if("stocks_cycle_view") vmode++ if (vmode > 1) @@ -111,87 +98,158 @@ data["stationName"] = using_map.station_name data["balance"] = balance() + data["screen"] = screen + + switch(screen) + // Main Stocks List + if("stocks") + if (vmode) + data["viewMode"] = "Full" + else + data["viewMode"] = "Compressed" - if (vmode) - data["viewMode"] = "Full" - else - data["viewMode"] = "Compressed" - - for (var/datum/stock/S in GLOB.stockExchange.last_read) - var/list/LR = GLOB.stockExchange.last_read[S] - if (!(logged_in in LR)) - LR[logged_in] = 0 - - data["stocks"] = list() - - if (vmode) - for (var/datum/stock/S in GLOB.stockExchange.stocks) - var/mystocks = 0 - if (logged_in && (logged_in in S.shareholders)) - mystocks = S.shareholders[logged_in] - - var/value = 0 - if (!S.bankrupt) - value = S.current_value - - data["stocks"] += list(list( - "REF" = REF(S), - "valueChange" = S.disp_value_change, // > 0 is +, < 0 is -, else its = - "bankrupt" = S.bankrupt, - "ID" = S.short_name, - "Name" = S.name, - "Value" = value, - "Owned" = mystocks, - "Avail" = S.available_shares, - "Products" = S.products, - )) - - var/news = 0 - if (logged_in) + for (var/datum/stock/S in GLOB.stockExchange.last_read) var/list/LR = GLOB.stockExchange.last_read[S] - var/lrt = LR[logged_in] - for (var/datum/article/A in S.articles) - if (A.ticks > lrt) - news = 1 - break - if (!news) - for (var/datum/stockEvent/E in S.events) - if (E.last_change > lrt && !E.hidden) - news = 1 - else - for (var/datum/stock/S in GLOB.stockExchange.stocks) - var/mystocks = 0 - if (logged_in && (logged_in in S.shareholders)) - mystocks = S.shareholders[logged_in] + if (!(logged_in in LR)) + LR[logged_in] = 0 - var/unification = 0 - if (S.last_unification) - unification = DisplayTimeText(world.time - S.last_unification) + data["stocks"] = list() - data["stocks"] += list(list( - "REF" = REF(S), - "bankrupt" = S.bankrupt, - "ID" = S.short_name, - "Name" = S.name, - "Owned" = mystocks, - "Avail" = S.available_shares, - "Unification" = unification, - "Products" = S.products, - )) + if (vmode) + for (var/datum/stock/S in GLOB.stockExchange.stocks) + var/mystocks = 0 + if (logged_in && (logged_in in S.shareholders)) + mystocks = S.shareholders[logged_in] - var/news = 0 - if (logged_in) - var/list/LR = GLOB.stockExchange.last_read[S] - var/lrt = LR[logged_in] - for (var/datum/article/A in S.articles) - if (A.ticks > lrt) - news = 1 - break - if (!news) - for (var/datum/stockEvent/E in S.events) - if (E.last_change > lrt && !E.hidden) - news = 1 - break + var/value = 0 + if (!S.bankrupt) + value = S.current_value + + data["stocks"] += list(list( + "REF" = REF(S), + "valueChange" = S.disp_value_change, // > 0 is +, < 0 is -, else its = + "bankrupt" = S.bankrupt, + "ID" = S.short_name, + "Name" = S.name, + "Value" = value, + "Owned" = mystocks, + "Avail" = S.available_shares, + "Products" = S.products, + )) + + var/news = 0 + if (logged_in) + var/list/LR = GLOB.stockExchange.last_read[S] + var/lrt = LR[logged_in] + for (var/datum/article/A in S.articles) + if (A.ticks > lrt) + news = 1 + break + if (!news) + for (var/datum/stockEvent/E in S.events) + if (E.last_change > lrt && !E.hidden) + news = 1 + else + for (var/datum/stock/S in GLOB.stockExchange.stocks) + var/mystocks = 0 + if (logged_in && (logged_in in S.shareholders)) + mystocks = S.shareholders[logged_in] + + var/unification = 0 + if (S.last_unification) + unification = DisplayTimeText(world.time - S.last_unification) + + data["stocks"] += list(list( + "REF" = REF(S), + "bankrupt" = S.bankrupt, + "ID" = S.short_name, + "Name" = S.name, + "Owned" = mystocks, + "Avail" = S.available_shares, + "Unification" = unification, + "Products" = S.products, + )) + + var/news = 0 + if (logged_in) + var/list/LR = GLOB.stockExchange.last_read[S] + var/lrt = LR[logged_in] + for (var/datum/article/A in S.articles) + if (A.ticks > lrt) + news = 1 + break + if (!news) + for (var/datum/stockEvent/E in S.events) + if (E.last_change > lrt && !E.hidden) + news = 1 + break + + // Stocks Logs Screen + if("logs") + data["logs"] = list() + + for(var/D in GLOB.stockExchange.logs) + var/datum/stock_log/L = D + + if (istype(L, /datum/stock_log/buy)) + data["logs"] += list(list( + "type" = "transaction_bought", + "time" = L.time, + "user_name" = L.user_name, + "stocks" = L.stocks, + "shareprice" = L.shareprice, + "money" = L.money, + "company_name" = L.company_name, + )) + else if (istype(L, /datum/stock_log/sell)) + data["logs"] += list(list( + "type" = "transaction_sold", + "time" = L.time, + "user_name" = L.user_name, + "stocks" = L.stocks, + "shareprice" = L.shareprice, + "money" = L.money, + "company_name" = L.company_name, + )) + else if (istype(L, /datum/stock_log/borrow)) + data["logs"] += list(list( + "type" = "borrow", + "time" = L.time, + "user_name" = L.user_name, + "stocks" = L.stocks, + "money" = L.money, + "company_name" = L.company_name, + )) + + // Archive Screen + if("archive") + data["name"] = current_stock.name + data["events"] = list() + data["articles"] = list() + + for (var/datum/stockEvent/E in current_stock.events) + if (E.hidden) + continue + data["events"] += list(list( + "current_title" = E.current_title, + "current_desc" = E.current_desc, + )) + + for (var/datum/article/A in current_stock.articles) + data["articles"] += list(list( + "headline" = A.headline, + "subtitle" = A.subtitle, + "article" = A.article, + "author" = A.author, + "spacetime" = A.spacetime, + "outlet" = A.outlet, + )) + + // Stock Graph + if("graph") + data["name"] = current_stock.name + data["maxValue"] = 100 + data["values"] = current_stock.values return data @@ -201,52 +259,6 @@ ui = new(user, src, "StockExchange") ui.open() -///// HISTORY SCREEN ///// - -/obj/machinery/computer/stockexchange/history/tgui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "StockExchangeHistory") - ui.open() - -/obj/machinery/computer/stockexchange/history/tgui_data(mob/user) - var/list/data = list() - //data["var"] = var - return data - -/obj/machinery/computer/stockexchange/history/tgui_act(action, params) - if(..()) - return - switch(action) - if("copypasta") - //var/newvar = params["var"] - // A demo of proper input sanitation. - //var = CLAMP(newvar, min_val, max_val) - . = TRUE - -///// ARCHIVE SCREEN ///// - -/obj/machinery/computer/stockexchange/archive/tgui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "StockExchangeArchive") - ui.open() - -/obj/machinery/computer/stockexchange/archive/tgui_data(mob/user) - var/list/data = list() - //data["var"] = var - return data - -/obj/machinery/computer/stockexchange/archive/tgui_act(action, params) - if(..()) - return - switch(action) - if("copypasta") - //var/newvar = params["var"] - // A demo of proper input sanitation. - //var = CLAMP(newvar, min_val, max_val) - . = TRUE - ///// PROCS ///// /obj/machinery/computer/stockexchange/proc/sell_some_shares(var/datum/stock/S, var/mob/user) diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm index b125338b30..37a7231b97 100644 --- a/code/modules/tgui/modules/appearance_changer.dm +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -38,6 +38,7 @@ map_name = "appearance_changer_[REF(src)]_map" // Initialize map objects cam_screen = new + cam_screen.name = "screen" cam_screen.assigned_map = map_name cam_screen.del_on_map_removal = FALSE @@ -407,6 +408,11 @@ return data /datum/tgui_module/appearance_changer/proc/update_active_camera_screen() + cam_screen.vis_contents = list(owner) // Copied from the vore version. + cam_background.icon_state = "clear" + cam_background.fill_rect(1, 1, 1, 1) + local_skybox.cut_overlays() + /* var/turf/newturf = get_turf(customize_usr ? tgui_host() : owner) if(newturf == last_camera_turf) return @@ -425,6 +431,7 @@ local_skybox.add_overlay(SSskybox.get_skybox(get_z(newturf))) local_skybox.scale_to_view(3) local_skybox.set_position("CENTER", "CENTER", (world.maxx>>1) - newturf.x, (world.maxy>>1) - newturf.y) + */ /datum/tgui_module/appearance_changer/proc/update_dna() var/mob/living/carbon/human/target = owner @@ -544,7 +551,7 @@ // VOREStation Add - Ears/Tails/Wings /datum/tgui_module/appearance_changer/proc/can_use_sprite(datum/sprite_accessory/X, mob/living/carbon/human/target, mob/user) - if(!isnull(X.species_allowed) && !(target.species.name in X.species_allowed)) + if(!isnull(X.species_allowed) && !(target.species.name in X.species_allowed) && (!istype(target.species, /datum/species/custom))) // Letting custom species access wings/ears/tails. return FALSE if(LAZYLEN(X.ckeys_allowed) && !(user?.ckey in X.ckeys_allowed) && !(target.ckey in X.ckeys_allowed)) diff --git a/code/modules/tgui/modules/appearance_changer_vr.dm b/code/modules/tgui/modules/appearance_changer_vr.dm index d5ace1b7e7..fc77d8663c 100644 --- a/code/modules/tgui/modules/appearance_changer_vr.dm +++ b/code/modules/tgui/modules/appearance_changer_vr.dm @@ -43,3 +43,15 @@ if(APPEARANCECHANGER_CHANGED_EYES) to_chat(M, "You feel lightheaded and drowsy...") to_chat(O, "You feel warm as you make subtle changes to your captive's body.") + +// Cocoon Stuff +/datum/tgui_module/appearance_changer/cocoon + name ="Appearance Editor (Cocoon)" + flags = APPEARANCE_ALL_HAIR + customize_usr = TRUE + +/datum/tgui_module/appearance_changer/cocoon/tgui_status(mob/user, datum/tgui_state/state) + //if(!istype(owner.loc, /obj/item/weapon/storage/vore_egg/bugcocoon)) + if(!owner.transforming) + return STATUS_CLOSE + return ..() \ No newline at end of file diff --git a/code/modules/vchat/css/ss13styles.css b/code/modules/vchat/css/ss13styles.css index 499e29dbc8..b43f33600a 100644 --- a/code/modules/vchat/css/ss13styles.css +++ b/code/modules/vchat/css/ss13styles.css @@ -157,11 +157,13 @@ h1.alert, h2.alert {color: #000000;} .skrell {color: #00B0B3;} .skrellfar {color: #70FCFF;} .soghun {color: #50BA6C;} -.solcom {color: #22228B;} +.solcom {color: #3333CE;} /* VOREStation Edit */ .changeling {color: #800080;} .sergal {color: #0077FF;} .birdsongc {color: #CC9900;} .vulpkanin {color: #B97A57;} +.tavan {color: #f54298; font-family: Arial} +.echosong {color: #826D8C;} .enochian {color: #848A33; letter-spacing:-1pt; word-spacing:4pt; font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;} .daemon {color: #5E339E; letter-spacing:-1pt; word-spacing:0pt; font-family: "Courier New", Courier, monospace;} .drudakar {color: #bb2463; word-spacing:0pt; font-family: "High Tower Text", monospace;} @@ -176,7 +178,6 @@ h1.alert, h2.alert {color: #000000;} .interface {color: #330033;} .spacer {color: #9c660b;} /* VOREStation Add */ .blob {color: #ff950d; font-weight: bold; font-style: italic;} -.tavan {color: #f54298; font-family: Arial} /* YW Edit start */ .psionic {color: #993399;} .wingdings {font-family: Wingdings, Webdings} diff --git a/code/modules/vore/eating/vertical_nom_vr.dm b/code/modules/vore/eating/vertical_nom_vr.dm new file mode 100644 index 0000000000..c9ff0a3096 --- /dev/null +++ b/code/modules/vore/eating/vertical_nom_vr.dm @@ -0,0 +1,47 @@ +/mob/living/proc/vertical_nom() + set name = "Nom from Above" + set desc = "Allows you to eat people who are below your tile or adjacent one. Requires passability." + set category = "Abilities" + + if(stat == DEAD || paralysis || weakened || stunned) + to_chat(src, "You cannot do that while in your current state.") + return + + if(!(src.vore_selected)) + to_chat(src, "No selected belly found.") + return + + var/list/targets = list() + + for(var/turf/T in range(1, src)) + if(isopenspace(T)) + while(isopenspace(T)) + T = GetBelow(T) + if(T) + for(var/mob/living/L in T) + if(L.devourable && L.can_be_drop_prey) + targets += L + + if(!(targets.len)) + to_chat(src, "No eligible targets found.") + return + + var/mob/living/target = tgui_input_list(src, "Please select a target.", "Victim", targets) + + if(!target) + return + + to_chat(target, "You feel yourself being pulled up by something... Or someone?!") + var/starting_loc = target.loc + + if(do_after(src, 50)) + if(target.loc != starting_loc) + to_chat(target, "You have interrupted whatever that was...") + to_chat(src, "They got away.") + return + if(target.buckled) + target.buckled.unbuckle_mob() + target.visible_message("\The [target] suddenly disappears somewhere above!",\ + "You are dragged above and feel yourself slipping directly into \the [src]'s [vore_selected]!") + to_chat(src, "You successfully snatch \the [target], slipping them into your [vore_selected].") + target.forceMove(src.vore_selected) \ No newline at end of file diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index 2f52628453..f71ea8c998 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -1491,4 +1491,22 @@ desc = "A well-worn slime custom-made yellow plushie, extensively hugged and loved. It reeks of lemon." icon = 'icons/vore/custom_items_vr.dmi' icon_state = "lemonplush" - attack_verb = list("blorbled", "slimed", "absorbed", "glomped") \ No newline at end of file + attack_verb = list("blorbled", "slimed", "absorbed", "glomped") + +//Bricker98:Nettie Stough +/obj/item/modular_computer/tablet/preset/custom_loadout/nettie + name = "Remodeled Tablet" + desc = "A tablet computer, looks quite high-tech and has some emblems on the back." + icon = 'icons/obj/modular_tablet.dmi' + icon_state = "elite" + icon_state_unpowered = "elite" + +/obj/item/modular_computer/tablet/preset/custom_loadout/nettie/install_default_hardware() + ..() + processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(src) + tesla_link = new/obj/item/weapon/computer_hardware/tesla_link(src) + hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/(src) + network_card = new/obj/item/weapon/computer_hardware/network_card/advanced(src) + nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src) + battery_module = new/obj/item/weapon/computer_hardware/battery_module(src) + battery_module.charge_to_full() diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 3bbdae1530..a8109a52fe 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -1,140 +1,142 @@ -/client/script = {""} +/client/script = {""} diff --git a/icons/_nanomaps/tether_nanomap_z1.png b/icons/_nanomaps/tether_nanomap_z1.png index fa1d0d6148..2cf0c71d84 100644 Binary files a/icons/_nanomaps/tether_nanomap_z1.png and b/icons/_nanomaps/tether_nanomap_z1.png differ diff --git a/icons/_nanomaps/tether_nanomap_z2.png b/icons/_nanomaps/tether_nanomap_z2.png index b15ae23be0..53492f77ee 100644 Binary files a/icons/_nanomaps/tether_nanomap_z2.png and b/icons/_nanomaps/tether_nanomap_z2.png differ diff --git a/icons/_nanomaps/tether_nanomap_z3.png b/icons/_nanomaps/tether_nanomap_z3.png index af24bb981d..53888984ca 100644 Binary files a/icons/_nanomaps/tether_nanomap_z3.png and b/icons/_nanomaps/tether_nanomap_z3.png differ diff --git a/icons/inventory/accessory/item_vr.dmi b/icons/inventory/accessory/item_vr.dmi index 09e8425850..b1e6a60a0e 100644 Binary files a/icons/inventory/accessory/item_vr.dmi and b/icons/inventory/accessory/item_vr.dmi differ diff --git a/icons/inventory/accessory/mob_vr.dmi b/icons/inventory/accessory/mob_vr.dmi index 7327c9b136..cab7916a32 100644 Binary files a/icons/inventory/accessory/mob_vr.dmi and b/icons/inventory/accessory/mob_vr.dmi differ diff --git a/icons/inventory/back/mob.dmi b/icons/inventory/back/mob.dmi index 380709f036..0d98a933c9 100644 Binary files a/icons/inventory/back/mob.dmi and b/icons/inventory/back/mob.dmi differ diff --git a/icons/mob/animal_vr.dmi b/icons/mob/animal_vr.dmi index 5d29e60511..87b050acbc 100644 Binary files a/icons/mob/animal_vr.dmi and b/icons/mob/animal_vr.dmi differ diff --git a/icons/mob/taursuits_horse.dmi b/icons/mob/taursuits_horse.dmi index 4162463c69..192f282796 100644 Binary files a/icons/mob/taursuits_horse.dmi and b/icons/mob/taursuits_horse.dmi differ diff --git a/icons/mob/taursuits_horse_vr.dmi b/icons/mob/taursuits_horse_vr.dmi index 4162463c69..192f282796 100644 Binary files a/icons/mob/taursuits_horse_vr.dmi and b/icons/mob/taursuits_horse_vr.dmi differ diff --git a/icons/mob/taursuits_naga_alt_vr.dmi b/icons/mob/taursuits_naga_alt_vr.dmi new file mode 100644 index 0000000000..ef43161887 Binary files /dev/null and b/icons/mob/taursuits_naga_alt_vr.dmi differ diff --git a/icons/mob/vore/taurs_vr.dmi b/icons/mob/vore/taurs_vr.dmi index 7b6f62e7f6..d10b18cb04 100644 Binary files a/icons/mob/vore/taurs_vr.dmi and b/icons/mob/vore/taurs_vr.dmi differ diff --git a/icons/mob/vore/wings_vr.dmi b/icons/mob/vore/wings_vr.dmi index 4dac461599..68432f86f2 100644 Binary files a/icons/mob/vore/wings_vr.dmi and b/icons/mob/vore/wings_vr.dmi differ diff --git a/icons/obj/chemical_vr.dmi b/icons/obj/chemical_vr.dmi index 1046726245..a08a052c90 100644 Binary files a/icons/obj/chemical_vr.dmi and b/icons/obj/chemical_vr.dmi differ diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index 087ceb08b7..517ce37d4b 100644 Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ diff --git a/maps/groundbase/gb-z3.dmm b/maps/groundbase/gb-z3.dmm index d2eb7dbd37..ca76c1335f 100644 --- a/maps/groundbase/gb-z3.dmm +++ b/maps/groundbase/gb-z3.dmm @@ -115,7 +115,7 @@ /obj/effect/shuttle_landmark{ base_area = /area/groundbase/level3/escapepad; base_turf = /turf/simulated/floor/outdoors/sidewalk/slab/virgo3c; - docking_controller = "escape_dock"; + docking_controller = null; landmark_tag = "escape_station"; name = "Ship Arrivals" }, diff --git a/maps/tether/tether-03-surface3.dmm b/maps/tether/tether-03-surface3.dmm index be5642fd3b..b91bb8c2bc 100644 --- a/maps/tether/tether-03-surface3.dmm +++ b/maps/tether/tether-03-surface3.dmm @@ -31643,10 +31643,10 @@ dir = 1; fancy_shuttle_tag = "tourbus" }, -/obj/effect/fancy_shuttle_floor_preview/tourbus{ +/obj/machinery/atmospherics/unary/engine/fancy_shuttle{ dir = 1 }, -/obj/machinery/atmospherics/unary/engine/fancy_shuttle{ +/obj/effect/fancy_shuttle_floor_preview/tourbus{ dir = 1 }, /turf/simulated/wall/fancy_shuttle{ @@ -38696,18 +38696,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_main) -"eGv" = ( -/obj/effect/floor_decal/fancy_shuttle{ - fancy_shuttle_tag = "tourbus"; - name = "tourbus" - }, -/obj/machinery/atmospherics/binary/pump, -/obj/structure/cable/green{ - dir = 1; - icon_state = "1-2" - }, -/turf/simulated/floor/tiled, -/area/shuttle/tourbus/general) "eHk" = ( /obj/structure/sign/nosmoking_2{ pixel_x = 29 @@ -39271,9 +39259,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/yellow{ dir = 9 }, -/obj/machinery/power/terminal{ - dir = 4 - }, /obj/machinery/light, /obj/machinery/power/apc{ name = "south bump"; @@ -40243,7 +40228,7 @@ /turf/simulated/wall, /area/tether/surfacebase/security/iaa/officeb) "jZe" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow, +/obj/machinery/atmospherics/binary/pump, /turf/simulated/floor/tiled/monotile, /area/tether/surfacebase/shuttle_pad) "kar" = ( @@ -55989,7 +55974,7 @@ xOa aXa aXa kcC -eGv +sJY sJY fEX gCZ diff --git a/maps/tether/tether-05-station1.dmm b/maps/tether/tether-05-station1.dmm index 62779227b6..6f79a19b09 100644 --- a/maps/tether/tether-05-station1.dmm +++ b/maps/tether/tether-05-station1.dmm @@ -15814,8 +15814,8 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 8 }, /turf/simulated/wall/fancy_shuttle{ fancy_shuttle_tag = "secbus" @@ -16452,8 +16452,8 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 8 }, /turf/simulated/wall/fancy_shuttle{ fancy_shuttle_tag = "medbus" @@ -17229,11 +17229,11 @@ d2 = 8; icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow, /obj/effect/floor_decal/fancy_shuttle{ fancy_shuttle_tag = "medbus"; name = "medbus" }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel, /turf/simulated/floor/tiled, /area/shuttle/medivac/engines) "dqh" = ( @@ -17770,9 +17770,6 @@ d2 = 8; icon_state = "0-8" }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 10 - }, /obj/structure/table/standard, /obj/item/weapon/tank/phoron, /obj/random/medical, @@ -17780,6 +17777,9 @@ fancy_shuttle_tag = "medbus"; name = "medbus" }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 10 + }, /turf/simulated/floor/tiled, /area/shuttle/medivac/engines) "dSp" = ( @@ -18604,7 +18604,7 @@ /turf/simulated/floor/plating, /area/tether/station/dock_two) "eVl" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ dir = 6 }, /turf/simulated/wall/fancy_shuttle/low{ @@ -21085,10 +21085,12 @@ /area/maintenance/substation/cargo) "hsf" = ( /obj/machinery/shipsensors/fancy_shuttle, -/turf/simulated/wall/fancy_shuttle{ - fancy_shuttle_tag = "secbus" +/turf/simulated/wall/fancy_shuttle/nondense{ + fancy_shuttle_tag = "secbus"; + nitrogen = 0; + oxygen = 0 }, -/area/shuttle/securiship/cockpit) +/area/shuttle/securiship/general) "hsq" = ( /obj/structure/catwalk, /obj/random/junk, @@ -24208,13 +24210,13 @@ /obj/structure/fuel_port{ pixel_y = 32 }, -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{ - dir = 1 - }, /obj/effect/floor_decal/fancy_shuttle{ fancy_shuttle_tag = "medbus"; name = "medbus" }, +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ + dir = 1 + }, /turf/simulated/floor/tiled, /area/shuttle/medivac/engines) "kjA" = ( @@ -25601,8 +25603,8 @@ /turf/simulated/floor/tiled/white, /area/tether/station/dock_two) "lof" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 8 }, /turf/simulated/wall/fancy_shuttle{ fancy_shuttle_tag = "medbus" @@ -27303,9 +27305,6 @@ /turf/simulated/floor/tiled, /area/tether/station/dock_one) "mIV" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 6 - }, /obj/structure/cable/green{ icon_state = "4-8" }, @@ -27319,6 +27318,9 @@ fancy_shuttle_tag = "secbus"; name = "secbus" }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 6 + }, /turf/simulated/floor/tiled, /area/shuttle/securiship/engines) "mJd" = ( @@ -27759,10 +27761,10 @@ /turf/simulated/floor/tiled, /area/tether/station/dock_two) "ncN" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow, /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 10 }, +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel, /turf/simulated/wall/fancy_shuttle{ fancy_shuttle_tag = "secbus" }, @@ -28192,7 +28194,7 @@ /turf/simulated/floor/tiled, /area/quartermaster/belterdock/gear) "nAr" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ dir = 10 }, /turf/simulated/wall/fancy_shuttle/low{ @@ -28202,9 +28204,6 @@ }, /area/shuttle/securiship/engines) "nAx" = ( -/obj/machinery/atmospherics/portables_connector{ - dir = 4 - }, /obj/machinery/portable_atmospherics/canister/phoron, /obj/machinery/light{ dir = 8 @@ -28213,6 +28212,9 @@ fancy_shuttle_tag = "medbus"; name = "medbus" }, +/obj/machinery/atmospherics/portables_connector/fuel{ + dir = 4 + }, /turf/simulated/floor/tiled, /area/shuttle/medivac/engines) "nAA" = ( @@ -28827,8 +28829,8 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 6 }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 8 }, /turf/simulated/wall/fancy_shuttle{ fancy_shuttle_tag = "medbus" @@ -30136,7 +30138,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow, +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel, /turf/simulated/wall/fancy_shuttle{ fancy_shuttle_tag = "medbus" }, @@ -31095,8 +31097,8 @@ /turf/simulated/floor, /area/storage/emergency_storage/emergency4) "rkl" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 8 }, /turf/simulated/wall/fancy_shuttle{ fancy_shuttle_tag = "secbus" @@ -31166,7 +31168,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 5 }, -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{ +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ dir = 1 }, /turf/simulated/wall/fancy_shuttle{ @@ -32508,7 +32510,7 @@ /turf/simulated/floor/tiled, /area/tether/exploration/hallway) "sOn" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ dir = 6 }, /turf/simulated/wall/fancy_shuttle{ @@ -33996,14 +33998,14 @@ /turf/simulated/shuttle/wall, /area/shuttle/belter) "uvN" = ( -/obj/machinery/atmospherics/portables_connector{ - dir = 4 - }, /obj/machinery/portable_atmospherics/canister/phoron, /obj/effect/floor_decal/fancy_shuttle{ fancy_shuttle_tag = "medbus"; name = "medbus" }, +/obj/machinery/atmospherics/portables_connector/fuel{ + dir = 4 + }, /turf/simulated/floor/tiled, /area/shuttle/medivac/engines) "uxR" = ( @@ -34872,13 +34874,13 @@ /turf/simulated/floor/tiled, /area/hallway/station/docks) "vtg" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 9 - }, /obj/effect/floor_decal/fancy_shuttle{ fancy_shuttle_tag = "medbus"; name = "medbus" }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 9 + }, /turf/simulated/floor/tiled, /area/shuttle/medivac/engines) "vtx" = ( @@ -35419,7 +35421,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 9 }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ dir = 10 }, /turf/simulated/wall/fancy_shuttle{ @@ -35489,13 +35491,13 @@ /obj/structure/cable/green{ icon_state = "1-4" }, -/obj/machinery/atmospherics/binary/pump{ - dir = 4 - }, /obj/effect/floor_decal/fancy_shuttle{ fancy_shuttle_tag = "medbus"; name = "medbus" }, +/obj/machinery/atmospherics/binary/pump/fuel{ + dir = 4 + }, /turf/simulated/floor/tiled, /area/shuttle/medivac/engines) "whg" = ( @@ -35674,7 +35676,7 @@ /turf/simulated/floor/tiled, /area/tether/station/dock_two) "wwJ" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{ +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ dir = 1 }, /turf/simulated/wall/fancy_shuttle{ @@ -36732,9 +36734,6 @@ /turf/simulated/floor/tiled, /area/hallway/station/docks) "xMQ" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{ - dir = 1 - }, /obj/structure/cable/green{ icon_state = "1-8" }, @@ -36755,6 +36754,9 @@ fancy_shuttle_tag = "secbus"; name = "secbus" }, +/obj/machinery/atmospherics/pipe/manifold/hidden/fuel{ + dir = 1 + }, /turf/simulated/floor/tiled, /area/shuttle/securiship/engines) "xMZ" = ( @@ -37002,9 +37004,6 @@ /turf/simulated/floor/tiled, /area/quartermaster/belterdock/surface_mining_outpost_shuttle_hangar) "xZE" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 10 - }, /obj/structure/cable{ icon_state = "0-8" }, @@ -37018,6 +37017,9 @@ fancy_shuttle_tag = "secbus"; name = "secbus" }, +/obj/machinery/atmospherics/pipe/simple/hidden/fuel{ + dir = 10 + }, /turf/simulated/floor/tiled, /area/shuttle/securiship/engines) "xZW" = ( @@ -37095,7 +37097,6 @@ /obj/structure/cable{ icon_state = "1-8" }, -/obj/machinery/atmospherics/binary/pump, /obj/machinery/light, /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 9 @@ -37104,6 +37105,7 @@ fancy_shuttle_tag = "secbus"; name = "secbus" }, +/obj/machinery/atmospherics/binary/pump/fuel, /turf/simulated/floor/tiled, /area/shuttle/securiship/engines) "ydT" = ( @@ -53894,7 +53896,7 @@ aaa aaa aaa aaa -hsf +osM osM scB sJw @@ -54754,7 +54756,7 @@ aaa aaa aaa aaa -tqu +hsf tqu mRq psE diff --git a/tgui/packages/tgui/interfaces/Communicator.js b/tgui/packages/tgui/interfaces/Communicator.js index 0206324624..d97f01937b 100644 --- a/tgui/packages/tgui/interfaces/Communicator.js +++ b/tgui/packages/tgui/interfaces/Communicator.js @@ -1129,6 +1129,10 @@ const SettingsTab = (props, context) => { : "Ringer off." } onClick={() => act("toggle_ringer")} /> +