diff --git a/code/__DEFINES/human.dm b/code/__DEFINES/human.dm index f2d60983b74c..d6a479bae5ab 100644 --- a/code/__DEFINES/human.dm +++ b/code/__DEFINES/human.dm @@ -191,6 +191,7 @@ #define SYNTH_GEN_ONE "First Generation Synthetic" #define SYNTH_GEN_TWO "Second Generation Synthetic" #define SYNTH_GEN_THREE "Third Generation Synthetic" +#define SYNTH_K9 "Synthetic K9" #define PLAYER_SYNTHS list(SYNTH_GEN_ONE, SYNTH_GEN_TWO, SYNTH_GEN_THREE) #define SYNTH_TYPES list(SYNTH_COLONY, SYNTH_COLONY_GEN_ONE, SYNTH_COLONY_GEN_TWO, SYNTH_COMBAT, SYNTH_INFILTRATOR, SYNTH_WORKING_JOE, SYNTH_GEN_ONE, SYNTH_GEN_TWO, SYNTH_GEN_THREE) diff --git a/code/__DEFINES/job.dm b/code/__DEFINES/job.dm index 0173a55e2d17..2cea4038c03f 100644 --- a/code/__DEFINES/job.dm +++ b/code/__DEFINES/job.dm @@ -67,6 +67,7 @@ GLOBAL_LIST_INIT(job_squad_roles, JOB_SQUAD_ROLES_LIST) #define JOB_COMBAT_REPORTER "Combat Correspondent" #define JOB_MESS_SERGEANT "Mess Technician" #define JOB_SYNTH "Synthetic" +#define JOB_SYNTH_K9 "Synthetic K9" #define JOB_WORKING_JOE "Working Joe" #define JOB_CO "Commanding Officer" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 53ad9904abd0..54546a6f046e 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -218,6 +218,7 @@ #define SPECIAL_BONEBREAK (1<<13) //species do not get their bonebreak chance modified by endurance #define NO_SHRAPNEL (1<<14) #define HAS_HARDCRIT (1<<15) +#define NO_OVERLAYS (1<<16) // Stop OnMob overlays from appearing on sprite //================================================= @@ -346,6 +347,7 @@ GLOBAL_LIST_INIT(default_xeno_onmob_icons, list( #define SPECIES_HUMAN "Human" #define SPECIES_YAUTJA "Yautja" #define SPECIES_SYNTHETIC "Synthetic" +#define SPECIES_SYNTHETIC_K9 "Synthetic K9" #define SPECIES_MONKEY "Monkey" #define SPECIES_ZOMBIE "Zombie" diff --git a/code/__DEFINES/paygrade_defs/marines.dm b/code/__DEFINES/paygrade_defs/marines.dm index 74b659630820..bb9b185f53dc 100644 --- a/code/__DEFINES/paygrade_defs/marines.dm +++ b/code/__DEFINES/paygrade_defs/marines.dm @@ -78,3 +78,6 @@ /// MO10S, Commandant of the Marine Corps #define PAY_SHORT_MO10S "MO10S" + +/// SYN_K9, Synthetic K9 +#define PAY_SHORT_SYN_K9 "K9" diff --git a/code/__DEFINES/typecheck/humanoids.dm b/code/__DEFINES/typecheck/humanoids.dm index 76f561e5fa1f..9f39d66a5012 100644 --- a/code/__DEFINES/typecheck/humanoids.dm +++ b/code/__DEFINES/typecheck/humanoids.dm @@ -17,6 +17,7 @@ #define isworkingjoe(A) (ishuman(A) && istype(A?:species, /datum/species/synthetic/colonial/working_joe)) #define ishazardjoe(A) (ishuman(A) && istype(A?:species, /datum/species/synthetic/colonial/working_joe/hazard)) #define isinfiltratorsynthetic(A) (ishuman(A) && istype(A?:species, /datum/species/synthetic/infiltrator)) +#define isk9synth(A) (ishuman(A) && istype(A?:species, /datum/species/synthetic/synth_k9)) //Specic group checks, use instead of typechecks (but use traits instead) #define issamespecies(A, B) (A.species?.group == B.species?.group) diff --git a/code/datums/factions/uscm.dm b/code/datums/factions/uscm.dm index 6a4b61289ea3..af45455424f8 100644 --- a/code/datums/factions/uscm.dm +++ b/code/datums/factions/uscm.dm @@ -17,7 +17,11 @@ if(JOB_SQUAD_ENGI) marine_rk = "engi" if(JOB_SQUAD_SPECIALIST) marine_rk = "spec" if(JOB_SQUAD_TEAM_LEADER) marine_rk = "tl" - if(JOB_SQUAD_MEDIC) marine_rk = "med" + if(JOB_SQUAD_MEDIC) + if(current_human.rank_fallback == "medk9") + marine_rk = "medk9" //We don't need Medics to lose their job when converting to K9 Handlers as it would duplicate JOB_SQUAD_MEDIC + else + marine_rk = "med" if(JOB_SQUAD_SMARTGUN) marine_rk = "gun" if(JOB_XO) marine_rk = "xo" if(JOB_CO) marine_rk = "co" @@ -139,6 +143,8 @@ border_rk = "command" if(JOB_SYNTH) marine_rk = "syn" + if(JOB_SYNTH_K9) + marine_rk = "syn_k9" if(JOB_MESS_SERGEANT) marine_rk = "messtech" // Provost diff --git a/code/datums/paygrades/factions/uscm/marine.dm b/code/datums/paygrades/factions/uscm/marine.dm index 6a1446dd6b60..f6f77b717a98 100644 --- a/code/datums/paygrades/factions/uscm/marine.dm +++ b/code/datums/paygrades/factions/uscm/marine.dm @@ -231,3 +231,13 @@ ranking = 25 pay_multiplier = 7 officer_grade = GRADE_FLAG + +//Historical Background: Combat Dogs were given the lowest officer rank possible, they have no notional command but if someone were to abuse the animal, the offender could be charged with assaulting an officer. +/datum/paygrade/marine/k9 + paygrade = PAY_SHORT_SYN_K9 + name = "Second Lieutenant Combat Lifesaver" + prefix = "2ndLt Combat Lifesaver" + rank_pin = /obj/item/clothing/accessory/ranks/marine/o1 + ranking = 12 + pay_multiplier = 0 + officer_grade = GRADE_OFFICER diff --git a/code/datums/skills/synthetic.dm b/code/datums/skills/synthetic.dm index c4d7296dee5d..99d86dda7a3e 100644 --- a/code/datums/skills/synthetic.dm +++ b/code/datums/skills/synthetic.dm @@ -88,3 +88,28 @@ SYNTHETIC SKILL_DOMESTIC = SKILL_DOMESTIC_MASTER, SKILL_ANTAG = SKILL_ANTAG_AGENT, ) + +/datum/skills/synth_k9 + name = "Synthetic K9" + skills = list( + SKILL_CQC = SKILL_CQC_MASTER, + SKILL_ENGINEER = SKILL_ENGINEER_DEFAULT, + SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_DEFAULT, + SKILL_FIREARMS = SKILL_FIREARMS_CIVILIAN, + SKILL_SPEC_WEAPONS = SKILL_SPEC_ALL, + SKILL_LEADERSHIP = SKILL_LEAD_NOVICE, + SKILL_OVERWATCH = SKILL_OVERWATCH_DEFAULT, + SKILL_MEDICAL = SKILL_MEDICAL_MASTER, + SKILL_SURGERY = SKILL_SURGERY_DEFAULT, + SKILL_RESEARCH = SKILL_RESEARCH_DEFAULT, + SKILL_MELEE_WEAPONS = SKILL_MELEE_SUPER, + SKILL_PILOT = SKILL_PILOT_EXPERT, + SKILL_POLICE = SKILL_POLICE_SKILLED, + SKILL_FIREMAN = SKILL_FIREMAN_MAX, + SKILL_POWERLOADER = SKILL_POWERLOADER_DEFAULT, + SKILL_VEHICLE = SKILL_VEHICLE_DEFAULT, + SKILL_JTAC = SKILL_JTAC_NOVICE, + SKILL_INTEL = SKILL_INTEL_NOVICE, + SKILL_DOMESTIC = SKILL_DOMESTIC_MASTER, + SKILL_NAVIGATIONS = SKILL_NAVIGATIONS_DEFAULT, + ) diff --git a/code/game/machinery/vending/vendor_types/crew/k9_synth.dm b/code/game/machinery/vending/vendor_types/crew/k9_synth.dm new file mode 100644 index 000000000000..9dc13058749b --- /dev/null +++ b/code/game/machinery/vending/vendor_types/crew/k9_synth.dm @@ -0,0 +1,28 @@ +/obj/structure/machinery/cm_vending/clothing/k9_synth + name = "\improper Wey-Yu Synthetic K9 Equipment Requisitions" + desc = "An automated equipment vendor for Synthetic K9s." + show_points = FALSE + req_access = list(ACCESS_MARINE_SYNTH) + vendor_role = list(JOB_SYNTH_K9) + +/obj/structure/machinery/cm_vending/clothing/k9_synth/get_listed_products(mob/user) + return GLOB.cm_vending_clothing_k9_synth + +//------------GEAR--------------- + +GLOBAL_LIST_INIT(cm_vending_clothing_k9_synth, list( + list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), + list("Headset", 0, /obj/item/device/radio/headset/almayer/mcom/synth, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), + list("K9 Serial ID Tags", 0, /obj/item/clothing/under/rank/synthetic/synth_k9, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), + list("Name Changer", 0, /obj/item/k9_name_changer/, MARINE_CAN_BUY_ACCESSORY, VENDOR_ITEM_MANDATORY), + + list("HANDLER KIT (CHOOSE 1)", 0, null, null, null), + list("Squad Corpsman -> K9 Handler", 0, /obj/item/storage/box/kit/k9_handler/corpsman, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_RECOMMENDED), + list("Military Police -> K9 Handler", 0, /obj/item/storage/box/kit/k9_handler/mp, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_REGULAR), + + list("CARRYPACK (CHOOSE 1)", 0, null, null, null), + list("Medical Carry Harness", 0, /obj/item/storage/backpack/marine/k9_synth/medicalpack, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_RECOMMENDED), + list("Cargo Carry Harness", 0, /obj/item/storage/backpack/marine/k9_synth/cargopack, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), + list("MP Carry Harness", 0, /obj/item/storage/backpack/marine/k9_synth/mppack, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), + + )) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 7fd82aeb9c10..0356b4227fc5 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -163,6 +163,8 @@ var/ground_offset_x = 0 /// How much to offset the item randomly either way alongside Y visually var/ground_offset_y = 0 + /// bypass any species specific OnMob overlay blockers + var/force_overlays_on = FALSE /// Special storages this item prioritizes var/list/preferred_storage diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index e03defc37dfe..2d02cbd82f9e 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -146,3 +146,36 @@ sharp = FALSE edge = FALSE force = 0 + +/obj/item/k9_name_changer + name = "K9 name implanter" + desc = "Syncs the implanted W-Y Serial Chip to the unit's preferred name." + icon = 'icons/obj/items/items.dmi' + icon_state = "efundcard" + w_class = SIZE_TINY + +/obj/item/k9_name_changer/attack_self(mob/user) + . = ..() + var/newname = capitalize(tgui_input_text(user, "What do you wish to be named", "Name:", encode = FALSE)) + if(!newname) + return + + var/verify = tgui_input_list(user, "Are you SURE you wish to be named: [newname]?", "Confirm", list("Yes", "No")) + if(verify != "Yes") + return + + user.change_real_name(user, newname) + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/altered_human = user + var/obj/item/card/id/ID = altered_human.get_idcard() + if(ID) + ID.name = "[altered_human.real_name]'s ID Card" + ID.registered_name = "[altered_human.real_name]" + if(ID.assignment) + ID.name += " ([ID.assignment])" + + var/genderswap = tgui_input_list(user, "Which Gender?", "Gender", list("Male", "Female")) + if(!genderswap) + return + user.gender = lowertext(genderswap) + qdel(src) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 0e7680cd2f7d..e2a77e4b8977 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -8,6 +8,7 @@ PLANT ANALYZER MASS SPECTROMETER REAGENT SCANNER FORENSIC SCANNER +K9 SCANNER */ /obj/item/device/t_scanner name = "\improper T-ray scanner" @@ -491,3 +492,59 @@ FORENSIC SCANNER flags_atom = FPRINT flags_equip_slot = SLOT_WAIST inherent_traits = list(TRAIT_TOOL_TRADEBAND) + +/obj/item/device/k9_scanner + name = "\improper K9 tracking device" + desc = "A small handheld tool used to track Synthetic K9 helpers, they tend to run off to strange places at inopportune times..." + icon_state = "tracking0" + item_state = "tracking1" + pickup_sound = 'sound/handling/multitool_pickup.ogg' + drop_sound = 'sound/handling/multitool_drop.ogg' + flags_atom = FPRINT + force = 5 + w_class = SIZE_TINY + throwforce = 5 + throw_range = 15 + throw_speed = SPEED_VERY_FAST + + matter = list("metal" = 50,"glass" = 20) + + var/mob/living/carbon/human/tracked_k9 + +/obj/item/device/k9_scanner/Destroy() + . = ..() + tracked_k9 = null + +/obj/item/device/k9_scanner/attack(mob/attacked_mob as mob, mob/user as mob) + if(!isk9synth(attacked_mob)) + to_chat(user, SPAN_BOLDWARNING("ERROR: Cannot Sync To This.")) + return + //we now know the attacked mob is a k9 + tracked_k9 = attacked_mob + icon_state = "tracking1" + to_chat(user, SPAN_WARNING("[src] is now synced to: [attacked_mob].")) + +/obj/item/device/k9_scanner/attack_self(mob/user) + . = ..() + if (!tracked_k9) + to_chat(user, SPAN_WARNING("ERROR: No K9 unit currently tracked. Use scanner on K9 unit to track them.")) + return + + var/turf/self_turf = get_turf(src) + var/turf/scanner_turf = get_turf(tracked_k9) + var/area/self_area = get_area(self_turf) + var/area/scanner_area = get_area(scanner_turf) + + if(self_turf.z != scanner_turf.z || self_area.fake_zlevel != scanner_area.fake_zlevel) + to_chat(user, SPAN_BOLDWARNING("The [src] lights up: UNABLE TO REACH LINKED K9!")) + playsound(src, 'sound/machines/buzz-sigh.ogg', 15, TRUE) + return + + var/dist = get_dist(self_turf, scanner_turf) + var/direction = dir2text(Get_Compass_Dir(self_turf, scanner_turf)) + if(dist > 1) + to_chat(user, SPAN_BOLDNOTICE("[src] lights up: [tracked_k9] is '[dist] meters to the [direction]'")) + else + to_chat(user, SPAN_BOLDNOTICE("[src] lights up: --><--")) + playsound(src, 'sound/machines/ping.ogg', 15, TRUE) + diff --git a/code/game/objects/items/pamphlets.dm b/code/game/objects/items/pamphlets.dm index d8bbb2a01432..315b8e26b99e 100644 --- a/code/game/objects/items/pamphlets.dm +++ b/code/game/objects/items/pamphlets.dm @@ -99,6 +99,43 @@ ID.set_assignment((user.assigned_squad ? (user.assigned_squad.name + " ") : "") + "Spotter") GLOB.data_core.manifest_modify(user.real_name, WEAKREF(user), "Spotter") +/obj/item/pamphlet/skill/k9_handler + name = "K9 handler instructional pamphlet" + desc = "A pamphlet used to quickly impart vital knowledge. This one has the image of a Synthetic K9 Rescue unit on it." + icon_state = "pamphlet_k9_handler" + trait = /datum/character_trait/skills/k9_handler + bypass_pamphlet_limit = TRUE + +/obj/item/pamphlet/skill/k9_handler/can_use(mob/living/carbon/human/user) + if(isk9synth(user)) + to_chat(user, SPAN_WARNING("You don't need to use this! Give it to another marine to make them your handler.")) + return FALSE + + if(user.job != JOB_SQUAD_MEDIC && user.job != JOB_POLICE) + to_chat(user, SPAN_WARNING("This is not meant for you.")) + return + + var/obj/item/card/id/ID = user.get_idcard() + if(!istype(ID)) //not wearing an ID + to_chat(user, SPAN_WARNING("You should wear your ID before doing this.")) + return FALSE + if(!ID.check_biometrics(user)) + to_chat(user, SPAN_WARNING("You should wear your ID before doing this.")) + return FALSE + + return ..() + +/obj/item/pamphlet/skill/k9_handler/on_use(mob/living/carbon/human/user) + . = ..() + user.rank_fallback = "medk9" + user.hud_set_squad() + user.assigned_equipment_preset.minimap_icon = "medic_k9" + user.update_minimap_icon() + + var/obj/item/card/id/ID = user.get_idcard() + ID.set_assignment((user.assigned_squad ? (user.assigned_squad.name + " ") : "") + "K9 Handler") + GLOB.data_core.manifest_modify(user.real_name, WEAKREF(user), "K9 Handler") + /obj/item/pamphlet/skill/machinegunner name = "heavy machinegunner instructional pamphlet" desc = "A pamphlet used to quickly impart vital knowledge. This one has an engineering and a machinegun insignia." diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 9ed53236789d..a8b2e8a32920 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -453,6 +453,26 @@ xeno_icon_state = "medicpack" xeno_types = list(/mob/living/carbon/xenomorph/runner, /mob/living/carbon/xenomorph/praetorian, /mob/living/carbon/xenomorph/drone, /mob/living/carbon/xenomorph/warrior, /mob/living/carbon/xenomorph/defender, /mob/living/carbon/xenomorph/sentinel, /mob/living/carbon/xenomorph/spitter) +/obj/item/storage/backpack/marine/k9_synth/ + icon_override = 'icons/mob/humans/species/synth_k9/onmob/synth_k9_overlays.dmi' + uniform_restricted = list(/obj/item/clothing/under/rank/synthetic/synth_k9) //K9 Synth only + force_overlays_on = TRUE + +/obj/item/storage/backpack/marine/k9_synth/cargopack + name = "\improper M209 portable K9 backpack" + desc = "Form fitted for the K9 Rescue Unit line of synthetics. Designed to lug gear into the battlefield." + icon_state = "marinepack_k9" + +/obj/item/storage/backpack/marine/k9_synth/medicalpack + name = "\improper M210 portable K9 medical backpack" + desc = "Form fitted for the K9 Rescue Unit line of synthetics. For carrying medical supplies." + icon_state = "marinepack_medic_k9" + +/obj/item/storage/backpack/marine/k9_synth/mppack + name = "\improper M553 portable K9 police backpack" + desc = "Form fitted for the K9 Rescue Unit line of synthetics. For carrying MP Equipment." + icon_state = "mppack_k9" + /obj/item/storage/backpack/marine/medic/upp name = "\improper UPP corpsman backpack" desc = "Uncommon issue backpack worn by UPP medics from isolated sectors. You can swear you can see a faded USCM symbol." diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 3ee8ef5b616d..a445652f264d 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -256,6 +256,7 @@ list("ass", "hudsquad_ass"), list("Eng", "hudsquad_engi"), list("Med", "hudsquad_med"), + list("medk9", "hudsquad_medk9"), list("SG", "hudsquad_gun"), list("Spc", "hudsquad_spec"), list("TL", "hudsquad_tl"), diff --git a/code/modules/character_traits/skills.dm b/code/modules/character_traits/skills.dm index 8cd82e1e109a..e02b7ef61f55 100644 --- a/code/modules/character_traits/skills.dm +++ b/code/modules/character_traits/skills.dm @@ -90,6 +90,11 @@ trait_desc = "Boosts the JTAC skill by 1. Crewmember received additional training in using JTAC equipment and Ghillie outfits." skill = SKILL_JTAC +/datum/character_trait/skills/k9_handler + trait_name = "K9 Handler Training" + trait_desc = "Allows the user to interface with Wey-Yu Synthetic K9 Units for rescue purposes" + skill = SKILL_JTAC + /datum/character_trait/skills/powerloader trait_name = "Powerloader Usage Training" trait_desc = "Boosts the powerloader skill to 1. Crewmember received training in operating powerloaders." diff --git a/code/modules/clothing/under/marine_uniform.dm b/code/modules/clothing/under/marine_uniform.dm index a9aec9544641..45273d1a7c9e 100644 --- a/code/modules/clothing/under/marine_uniform.dm +++ b/code/modules/clothing/under/marine_uniform.dm @@ -952,6 +952,15 @@ worn_state = "rdalt" flags_jumpsuit = FALSE +/obj/item/clothing/under/rank/synthetic/synth_k9 + name = "\improper W-Y K9 serial identification collar" + desc = "Contains a serialized manufacturing number related to this unit's manufacturing date and time." + icon = 'icons/mob/humans/species/synth_k9/onmob/synth_k9_overlays.dmi' + flags_item = NODROP + icon_state = "k9_dogtags" + worn_state = "k9_dogtags" + flags_jumpsuit = FALSE + /obj/item/clothing/under/rank/synthetic/frontier name = "\improper frontier jumpsuit" desc = "A cargo jumpsuit dressed down for full range of motion and state-of-the-art frontier temperature control. It's the best thing an engineer can wear in the Outer Veil." diff --git a/code/modules/cm_marines/equipment/kit_boxes.dm b/code/modules/cm_marines/equipment/kit_boxes.dm index 7be519896097..59009bc898e4 100644 --- a/code/modules/cm_marines/equipment/kit_boxes.dm +++ b/code/modules/cm_marines/equipment/kit_boxes.dm @@ -545,6 +545,34 @@ new /obj/item/device/binoculars/range/designator/spotter(src) new /obj/item/pamphlet/skill/spotter(src) +/obj/item/storage/box/kit/k9_handler/mp + name = "\improper Police K9 handler Kit" + desc = "Contains the equipment needed for a Police K9 Handler to perform their duties." + pro_case_overlay = "k9_handler" + +/obj/item/storage/box/kit/k9_handler/mp/fill_preset_inventory() + new /obj/item/device/k9_scanner(src) + new /obj/item/storage/firstaid/synth(src) + new /obj/item/device/helmet_visor/welding_visor(src) + new /obj/item/device/binoculars(src) + new /obj/item/pamphlet/skill/k9_handler(src) + new /obj/item/storage/box/evidence(src) + new /obj/item/restraint/handcuffs(src) + new /obj/item/reagent_container/spray/pepper(src) + +/obj/item/storage/box/kit/k9_handler/corpsman + name = "\improper Medical K9 handler Kit" + desc = "Contains the equipment needed for a Medical K9 Handler to perform their duties." + pro_case_overlay = "k9_handler" + +/obj/item/storage/box/kit/k9_handler/corpsman/fill_preset_inventory() + new /obj/item/device/k9_scanner(src) + new /obj/item/storage/firstaid/synth(src) + new /obj/item/device/helmet_visor/welding_visor(src) + new /obj/item/device/binoculars(src) + new /obj/item/pamphlet/skill/k9_handler(src) + new /obj/item/storage/pouch/autoinjector/full(src) + /obj/item/storage/box/kit/engineering_supply_kit name = "\improper Engineering Supply Kit" diff --git a/code/modules/cm_marines/marines_consoles.dm b/code/modules/cm_marines/marines_consoles.dm index 778f3f4f18bf..191e35f078c6 100644 --- a/code/modules/cm_marines/marines_consoles.dm +++ b/code/modules/cm_marines/marines_consoles.dm @@ -969,6 +969,7 @@ GLOBAL_LIST_EMPTY_TYPED(crewmonitor, /datum/crewmonitor) JOB_CARGO_TECH = 61, JOB_MESS_SERGEANT = 62, // 70-139: SQUADS (look below) + JOB_SYNTH_K9 = 71, // 140+: Civilian/other JOB_CORPORATE_LIAISON = 140, JOB_PASSENGER = 141, diff --git a/code/modules/cm_marines/radar.dm b/code/modules/cm_marines/radar.dm index aa332d601395..f12f0e79d81c 100644 --- a/code/modules/cm_marines/radar.dm +++ b/code/modules/cm_marines/radar.dm @@ -235,3 +235,33 @@ if(uniform.has_sensor && uniform.sensor_mode >= SENSOR_MODE_LOCATION) // Suit sensors must be on maximum return TRUE return FALSE + + +//Synthetic K9 Scent Tracking, allows K9s to track CLF, UPP, etc as well as Preds... optic camo can't hide the fact you stink! +/datum/radar/scenttracker/find_atom() + return locate(selected) in GLOB.human_mob_list + +/datum/radar/scenttracker/scan() + . = ..() + objects = list() + for(var/mob/living/carbon/human/humanoid as anything in GLOB.human_mob_list) + var/crewmember_name = "Unknown" + var/crewmember_rank = "Unknown" + if(humanoid.get_idcard()) + var/obj/item/card/id/ID = humanoid.get_idcard() + if(ID?.registered_name) + crewmember_name = ID.registered_name + if(ID?.assignment) + crewmember_rank = ID.assignment + switch(humanoid.stat) + if(CONSCIOUS) + crewmember_name = "[crewmember_name] ([crewmember_rank]) (Conscious)" + if(UNCONSCIOUS) + crewmember_name = "[crewmember_name] ([crewmember_rank]) (Unconscious)" + if(DEAD) + crewmember_name = "[crewmember_name] ([crewmember_rank]) (DEAD)" + var/list/crewinfo = list( + ref = REF(humanoid), + name = crewmember_name, + ) + objects += list(crewinfo) diff --git a/code/modules/gear_presets/synth_k9.dm b/code/modules/gear_presets/synth_k9.dm new file mode 100644 index 000000000000..2059990655db --- /dev/null +++ b/code/modules/gear_presets/synth_k9.dm @@ -0,0 +1,38 @@ +/datum/equipment_preset/synth_k9 + name = "K9 Synthetic" + uses_special_name = TRUE + languages = ALL_SYNTH_LANGUAGES + skills = /datum/skills/synth_k9 + minimap_icon = "synth_k9" + flags = EQUIPMENT_PRESET_START_OF_ROUND|EQUIPMENT_PRESET_MARINE + faction = FACTION_MARINE + idtype = /obj/item/card/id/gold + assignment = JOB_SYNTH_K9 + rank = "Synthetic K9" + paygrades = list(PAY_SHORT_SYN_K9 = JOB_PLAYTIME_TIER_0) + role_comm_title = "K9" + +/datum/equipment_preset/synth_k9/New() + . = ..() + access = get_access(ACCESS_LIST_GLOBAL) + +/datum/equipment_preset/synth_k9/load_race(mob/living/carbon/human/new_human) + . = ..() + new_human.h_style = "Bald" + new_human.f_style = "Shaved" + if(new_human.client?.prefs?.synthetic_type) + new_human.set_species(new_human.client.prefs.synthetic_type) + return + new_human.set_species(SYNTH_K9) + +/datum/equipment_preset/synth_k9/load_name(mob/living/carbon/human/new_human, randomise) + var/final_name = "Rex" + if(new_human.client?.prefs) + final_name = new_human.client.prefs.synthetic_name + if(!final_name || final_name == "Undefined") + final_name = "Rex" + new_human.change_real_name(new_human, final_name) + +/datum/equipment_preset/synth_k9/load_skills(mob/living/carbon/human/new_human) + . = ..() + new_human.allow_gun_usage = FALSE diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 7da0376bbef1..c82aa1f6de31 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -5,7 +5,7 @@ /// Species that can use this emote. var/list/species_type_allowed_typecache = list(/datum/species/human, /datum/species/synthetic, /datum/species/yautja) /// Species that can't use this emote. - var/list/species_type_blacklist_typecache = list(/datum/species/monkey) + var/list/species_type_blacklist_typecache = list(/datum/species/monkey, /datum/species/synthetic/synth_k9) /datum/emote/living/carbon/human/New() . = ..() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0a6a42d09ba5..3739addc44f6 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1489,6 +1489,8 @@ /mob/living/carbon/human/synthetic/second/Initialize(mapload) . = ..(mapload, SYNTH_GEN_TWO) +/mob/living/carbon/human/synthetic/synth_k9/Initialize(mapload) + . = ..(mapload, SYNTH_K9) /mob/living/carbon/human/resist_fire() if(isyautja(src)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 0bb446bf5f02..882d51674b00 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -172,6 +172,9 @@ /// Stored image references associated with focus-fire. var/image/focused_fire_marker + // Are we currently using inherent zoom vision? + var/is_zoomed = FALSE + /client/var/cached_human_playtime /client/proc/get_total_human_playtime(skip_cache = FALSE) diff --git a/code/modules/mob/living/carbon/human/powers/human_powers.dm b/code/modules/mob/living/carbon/human/powers/human_powers.dm index fef87c2f3263..970affa8eae2 100644 --- a/code/modules/mob/living/carbon/human/powers/human_powers.dm +++ b/code/modules/mob/living/carbon/human/powers/human_powers.dm @@ -288,3 +288,70 @@ synthetic_HUD_toggled[chosen_HUD] = TRUE H.add_hud_to(src, src) to_chat(src, SPAN_INFO("[hud_choice] Enabled")) + +/mob/living/carbon/human/synthetic/synth_k9/proc/toggle_scent_tracking() + set category = "Synthetic" + set name = "Track Scent" + set desc = "Activates the K9's keen sense of smell." + + if(usr.is_mob_incapacitated()) + return + + if(!isk9synth(usr)) + return + + var/datum/species/synthetic/synth_k9/speciesk9 = species + + speciesk9.radar.tgui_interact(src) + +/mob/living/carbon/human/synthetic/synth_k9/proc/toggle_binocular_vision(mob/user) + set category = "Synthetic" + set name = "Binocular Vision" + set desc = "Activates the K9's keen sense of sight." + + if(usr.is_mob_incapacitated()) + return + + if(!is_zoomed) + enable_zoom() + user.visible_message(SPAN_NOTICE("[user] starts looking off into the distance."), \ + SPAN_NOTICE("You start focusing your sight to look off into the distance."), null, 5) + return + + if(is_zoomed) + disable_zoom() + return + +/mob/living/carbon/human/proc/enable_zoom() + var/viewsize = 12 + var/tileoffset = 11 + + if(is_zoomed || !client) + return + is_zoomed = TRUE + RegisterSignal(src, COMSIG_MOB_MOVE_OR_LOOK, PROC_REF(disable_zoom)) + client.change_view(viewsize) + var/viewoffset = 32 * tileoffset + switch(dir) + if(NORTH) + client.pixel_x = 0 + client.pixel_y = viewoffset + if(SOUTH) + client.pixel_x = 0 + client.pixel_y = -viewoffset + if(EAST) + client.pixel_x = viewoffset + client.pixel_y = 0 + if(WEST) + client.pixel_x = -viewoffset + client.pixel_y = 0 + +/mob/living/carbon/human/proc/disable_zoom() + SIGNAL_HANDLER + if(!client) + return + UnregisterSignal(src, COMSIG_MOB_MOVE_OR_LOOK) + client.change_view(GLOB.world_view_size) + client.pixel_x = 0 + client.pixel_y = 0 + is_zoomed = FALSE diff --git a/code/modules/mob/living/carbon/human/species/emote-monkey.dm b/code/modules/mob/living/carbon/human/species/emote-monkey.dm index 52b6d31c4fe0..c05d2fe58b83 100644 --- a/code/modules/mob/living/carbon/human/species/emote-monkey.dm +++ b/code/modules/mob/living/carbon/human/species/emote-monkey.dm @@ -1,7 +1,11 @@ /datum/emote/living/carbon/human/primate species_type_allowed_typecache = list(/datum/species/monkey) + species_type_blacklist_typecache = list() keybind = FALSE +/datum/emote/living/carbon/human/primate/New() //Monkey's are blacklisted from human emotes on emote.dm, we need to not block the new emotes below + . = ..() + /datum/emote/living/carbon/human/primate/jump key = "jump" key_third_person = "jumps" diff --git a/code/modules/mob/living/carbon/human/species/emote-synth_k9.dm b/code/modules/mob/living/carbon/human/species/emote-synth_k9.dm new file mode 100644 index 000000000000..376449f6d688 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/emote-synth_k9.dm @@ -0,0 +1,31 @@ +/datum/emote/living/carbon/human/synthetic/synth_k9/New() //K9's are blacklisted from human emotes on emote.dm, we need to not block the new emotes below + . = ..() + +//Synth K9 Emotes +/datum/emote/living/carbon/human/synthetic/synth_k9 + species_type_allowed_typecache = list(/datum/species/synthetic/synth_k9) + species_type_blacklist_typecache = list() + keybind_category = CATEGORY_SYNTH_EMOTE + volume = 75 + +//Standard Bark +/datum/emote/living/carbon/human/synthetic/synth_k9/bark + key = "bark" + key_third_person = "barks" + message = "barks." + audio_cooldown = 3 SECONDS + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/synth_k9/bark/get_sound(mob/living/user) + return pick('sound/voice/barkstrong1.ogg','sound/voice/barkstrong2.ogg','sound/voice/barkstrong3.ogg') + +//Threatening Growl +/datum/emote/living/carbon/human/synthetic/synth_k9/growl + key = "growl" + key_third_person = "growls" + message = "growls." + audio_cooldown = 3 SECONDS + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/synth_k9/growl/get_sound(mob/living/user) + return pick('sound/voice/growl1.ogg','sound/voice/growl2.ogg','sound/voice/growl3.ogg','sound/voice/growl4.ogg') diff --git a/code/modules/mob/living/carbon/human/species/human.dm b/code/modules/mob/living/carbon/human/species/human.dm index 320aa9504826..208f304bc3b4 100644 --- a/code/modules/mob/living/carbon/human/species/human.dm +++ b/code/modules/mob/living/carbon/human/species/human.dm @@ -90,6 +90,8 @@ mob_flags = KNOWS_TECHNOLOGY uses_skin_color = TRUE special_body_types = TRUE + fire_sprite_prefix = "Standing" + fire_sprite_sheet = 'icons/mob/humans/onmob/OnFire.dmi' /datum/species/human/handle_on_fire(humanoidmob) . = ..() diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index 2973e4b6a556..152a6a9a1b70 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -21,6 +21,8 @@ /mob/living/proc/ventcrawl, /mob/living/proc/hide, ) + fire_sprite_prefix = "monkey" + fire_sprite_sheet = 'icons/mob/humans/onmob/OnFire.dmi' /datum/species/monkey/New() equip_adjust = list( diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 42338c2c40a2..85f084524041 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -119,6 +119,9 @@ var/has_species_tab_items = FALSE + var/fire_sprite_prefix = "Standing" + var/fire_sprite_sheet = 'icons/mob/humans/onmob/OnFire.dmi' + /datum/species/New() if(unarmed_type) unarmed = new unarmed_type() diff --git a/code/modules/mob/living/carbon/human/species/synth_k9.dm b/code/modules/mob/living/carbon/human/species/synth_k9.dm new file mode 100644 index 000000000000..fa067d87e5ef --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/synth_k9.dm @@ -0,0 +1,41 @@ +//woof! +/datum/species/synthetic/synth_k9 + name = SPECIES_SYNTHETIC_K9 + uses_skin_color = FALSE + + slowdown = -1.75 //Faster than Human run, slower than rooney run + + icobase = 'icons/mob/humans/species/synth_k9/r_k9.dmi' + deform = 'icons/mob/humans/species/synth_k9/r_k9.dmi' + eyes = "blank_eyes_s" + blood_mask = 'icons/mob/humans/species/synth_k9/r_k9.dmi' + unarmed_type = /datum/unarmed_attack/bite/synthetic + secondary_unarmed_type = /datum/unarmed_attack + death_message = "lets out a faint whimper as it collapses and stops moving..." + flags = IS_WHITELISTED|NO_BREATHE|NO_CLONE_LOSS|NO_BLOOD|NO_POISON|IS_SYNTHETIC|NO_CHEM_METABOLIZATION|NO_NEURO|NO_OVERLAYS + + mob_inherent_traits = list(TRAIT_SUPER_STRONG, TRAIT_IRON_TEETH, TRAIT_EMOTE_CD_EXEMPT) + + fire_sprite_prefix = "k9" + fire_sprite_sheet = 'icons/mob/humans/onmob/OnFire.dmi' + + inherent_verbs = list( + /mob/living/carbon/human/synthetic/proc/toggle_HUD, + /mob/living/carbon/human/proc/toggle_inherent_nightvison, + /mob/living/carbon/human/synthetic/synth_k9/proc/toggle_scent_tracking, + /mob/living/carbon/human/synthetic/synth_k9/proc/toggle_binocular_vision, + ) + + //Scent tracking + var/datum/radar/scenttracker/radar + var/faction = FACTION_MARINE + +//Lets have a place for radar data to live +/datum/species/synthetic/synth_k9/handle_post_spawn(mob/living/carbon/human/spawned_k9) + . = ..() + radar = new /datum/radar/scenttracker(spawned_k9, faction) + +/datum/species/synthetic/synth_k9/Destroy() + . = ..() + qdel(radar) + faction = null diff --git a/code/modules/mob/living/carbon/human/unarmed_attacks.dm b/code/modules/mob/living/carbon/human/unarmed_attacks.dm index f933e853207a..8d4ca1df6d8d 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attacks.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attacks.dm @@ -23,6 +23,14 @@ sharp = TRUE edge = TRUE +/datum/unarmed_attack/bite/synthetic + attack_verb = list("gnash", "chew", "munch", "crunch") + attack_sound = 'sound/weapons/alien_bite1.ogg' + shredding = FALSE + damage = 35 + sharp = TRUE + edge = TRUE + /datum/unarmed_attack/bite/is_usable(mob/living/carbon/human/user) if(!user.melee_allowed) return FALSE diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 6b2739780288..1cf4403f12c4 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -328,6 +328,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(w_uniform) w_uniform.screen_loc = hud_used.ui_datum.hud_slot_offset(w_uniform, hud_used.ui_datum.ui_iclothing) + if(species.flags & NO_OVERLAYS && !w_uniform.force_overlays_on) + return + if(!(wear_suit && wear_suit.flags_inv_hide & HIDEJUMPSUIT)) var/image/I = w_uniform.get_mob_overlay(src, WEAR_BODY) I.layer = -UNIFORM_LAYER @@ -348,6 +351,8 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, var/obj/item/card/id/card = get_idcard() if(!card) return + if(species.flags & NO_OVERLAYS && !wear_id.force_overlays_on) + return if(!card.pinned_on_uniform || (w_uniform && w_uniform.displays_id && !(w_uniform.flags_jumpsuit & UNIFORM_JACKET_REMOVED))) var/image/id_overlay = card.get_mob_overlay(src, WEAR_ID) id_overlay.layer = -ID_LAYER @@ -362,6 +367,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(gloves) gloves.screen_loc = hud_used.ui_datum.hud_slot_offset(gloves, hud_used.ui_datum.ui_gloves) + if(species.flags & NO_OVERLAYS && !gloves.force_overlays_on) + return + if(!(wear_suit && wear_suit.flags_inv_hide & HIDEGLOVES)) I = gloves.get_mob_overlay(src, WEAR_HANDS) @@ -381,6 +389,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(glasses) glasses.screen_loc = hud_used.ui_datum.hud_slot_offset(glasses, hud_used.ui_datum.ui_glasses) + if(species.flags & NO_OVERLAYS && !glasses.force_overlays_on) + return + var/image/I = glasses.get_mob_overlay(src, WEAR_EYES) I.layer = -GLASSES_LAYER overlays_standing[GLASSES_LAYER] = I @@ -399,6 +410,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, wear_l_ear?.screen_loc = hud_used.ui_datum.hud_slot_offset(wear_l_ear, hud_used.ui_datum.ui_wear_l_ear) wear_r_ear?.screen_loc = hud_used.ui_datum.hud_slot_offset(wear_r_ear, hud_used.ui_datum.ui_wear_r_ear) + if(species.flags & NO_OVERLAYS) + return + var/image/standing_image = image('icons/mob/humans/onmob/med_human.dmi', icon_state = "blank", layer = -EARS_LAYER) standing_image.overlays += wear_l_ear?.get_mob_overlay(src, WEAR_L_EAR) @@ -417,6 +431,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(shoes) shoes.screen_loc = hud_used.ui_datum.hud_slot_offset(shoes, hud_used.ui_datum.ui_shoes) + if(species.flags & NO_OVERLAYS && !shoes.force_overlays_on) + return + if(!((wear_suit && wear_suit.flags_inv_hide & HIDESHOES) || (w_uniform && w_uniform.flags_inv_hide & HIDESHOES))) I = shoes.get_mob_overlay(src, WEAR_FEET) @@ -436,6 +453,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(s_store) s_store.screen_loc = hud_used.ui_datum.hud_slot_offset(s_store, hud_used.ui_datum.ui_sstore1) + if(species.flags & NO_OVERLAYS && !s_store.force_overlays_on) + return + var/image/I = s_store.get_mob_overlay(src, WEAR_J_STORE) I.layer = -SUIT_STORE_LAYER overlays_standing[SUIT_STORE_LAYER] = I @@ -456,6 +476,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(head) head.screen_loc = hud_used.ui_datum.hud_slot_offset(head, hud_used.ui_datum.ui_head) + if(species.flags & NO_OVERLAYS && !head.force_overlays_on) + return + var/image/I = head.get_mob_overlay(src, WEAR_HEAD) I.layer = -HEAD_LAYER overlays_standing[HEAD_LAYER] = I @@ -501,6 +524,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(belt) belt.screen_loc = hud_used.ui_datum.hud_slot_offset(belt, hud_used.ui_datum.ui_belt) + if(species.flags & NO_OVERLAYS && !belt.force_overlays_on) + return + var/image/I = belt.get_mob_overlay(src, WEAR_WAIST) I.layer = -BELT_LAYER overlays_standing[BELT_LAYER] = I @@ -518,6 +544,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(wear_suit) wear_suit.screen_loc = hud_used.ui_datum.hud_slot_offset(wear_suit, hud_used.ui_datum.ui_oclothing) + if(species.flags & NO_OVERLAYS && !wear_suit.force_overlays_on) + return + var/image/I = wear_suit.get_mob_overlay(src, WEAR_JACKET) I.layer = -SUIT_LAYER overlays_standing[SUIT_LAYER] = I @@ -566,6 +595,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, if(!(client && hud_used && hud_used.hud_shown && hud_used.ui_datum)) return + if(species.flags & NO_OVERLAYS) + return + if(l_store) client.add_to_screen(l_store) l_store.screen_loc = hud_used.ui_datum.hud_slot_offset(l_store, hud_used.ui_datum.ui_storage1) @@ -582,6 +614,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(wear_mask) wear_mask.screen_loc = hud_used.ui_datum.hud_slot_offset(wear_mask, hud_used.ui_datum.ui_mask) + if(species.flags & NO_OVERLAYS && !wear_mask.force_overlays_on) + return + if(!(head && head.flags_inv_hide & HIDEMASK)) var/image/I = wear_mask.get_mob_overlay(src, WEAR_FACE) I.layer = -FACEMASK_LAYER @@ -596,6 +631,9 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, client.add_to_screen(back) back.screen_loc = hud_used.ui_datum.hud_slot_offset(back, hud_used.ui_datum.ui_back) + if(species.flags & NO_OVERLAYS && !back.force_overlays_on) + return + var/image/I = back.get_mob_overlay(src, WEAR_BACK) I.layer = -BACK_LAYER @@ -710,13 +748,17 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate, if(!on_fire) set_light_on(FALSE) return + + var/fire_sprite_sheet = species.fire_sprite_sheet + var/fire_sprite_prefix = species.fire_sprite_prefix + var/image/I switch(fire_stacks) if(1 to 14) - I = image("icon"='icons/mob/humans/onmob/OnFire.dmi', "icon_state"="Standing_weak", "layer"= -FIRE_LAYER) + I = image(icon = fire_sprite_sheet, icon_state = "[fire_sprite_prefix]_weak", layer = -FIRE_LAYER) set_light_range(2) if(15 to INFINITY) - I = image("icon"='icons/mob/humans/onmob/OnFire.dmi', "icon_state"="Standing_medium", "layer"= -FIRE_LAYER) + I = image(icon = fire_sprite_sheet, icon_state = "[fire_sprite_prefix]_medium", layer = -FIRE_LAYER) set_light_range(3) else return diff --git a/colonialmarines.dme b/colonialmarines.dme index 78f81b2e1213..0be6a414f18d 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -1000,6 +1000,7 @@ #include "code\game\machinery\vending\vendor_types\crew\commanding_officer.dm" #include "code\game\machinery\vending\vendor_types\crew\corporate_liaison.dm" #include "code\game\machinery\vending\vendor_types\crew\engineering.dm" +#include "code\game\machinery\vending\vendor_types\crew\k9_synth.dm" #include "code\game\machinery\vending\vendor_types\crew\medical.dm" #include "code\game\machinery\vending\vendor_types\crew\mp.dm" #include "code\game\machinery\vending\vendor_types\crew\pilot_officer.dm" @@ -1771,6 +1772,7 @@ #include "code\modules\gear_presets\other.dm" #include "code\modules\gear_presets\pmc.dm" #include "code\modules\gear_presets\royal_marines.dm" +#include "code\modules\gear_presets\synth_k9.dm" #include "code\modules\gear_presets\synths.dm" #include "code\modules\gear_presets\upp.dm" #include "code\modules\gear_presets\uscm.dm" @@ -1953,9 +1955,11 @@ #include "code\modules\mob\living\carbon\human\powers\human_powers.dm" #include "code\modules\mob\living\carbon\human\powers\issue_order.dm" #include "code\modules\mob\living\carbon\human\species\emote-monkey.dm" +#include "code\modules\mob\living\carbon\human\species\emote-synth_k9.dm" #include "code\modules\mob\living\carbon\human\species\human.dm" #include "code\modules\mob\living\carbon\human\species\monkey.dm" #include "code\modules\mob\living\carbon\human\species\species.dm" +#include "code\modules\mob\living\carbon\human\species\synth_k9.dm" #include "code\modules\mob\living\carbon\human\species\synthetic.dm" #include "code\modules\mob\living\carbon\human\species\zombie.dm" #include "code\modules\mob\living\carbon\human\species\working_joe\_emote.dm" diff --git a/icons/mob/hud/marine_hud.dmi b/icons/mob/hud/marine_hud.dmi index 8be1ae31ba68..8aff95b8b33d 100644 Binary files a/icons/mob/hud/marine_hud.dmi and b/icons/mob/hud/marine_hud.dmi differ diff --git a/icons/mob/humans/onmob/OnFire.dmi b/icons/mob/humans/onmob/OnFire.dmi index 696b12584e43..dd325cea67e2 100644 Binary files a/icons/mob/humans/onmob/OnFire.dmi and b/icons/mob/humans/onmob/OnFire.dmi differ diff --git a/icons/mob/humans/onmob/uniform_0.dmi b/icons/mob/humans/onmob/uniform_0.dmi index 36551630209d..d1fb32f6d05d 100644 Binary files a/icons/mob/humans/onmob/uniform_0.dmi and b/icons/mob/humans/onmob/uniform_0.dmi differ diff --git a/icons/mob/humans/species/synth_k9/onmob/synth_k9_overlays.dmi b/icons/mob/humans/species/synth_k9/onmob/synth_k9_overlays.dmi new file mode 100644 index 000000000000..207abb57de66 Binary files /dev/null and b/icons/mob/humans/species/synth_k9/onmob/synth_k9_overlays.dmi differ diff --git a/icons/mob/humans/species/synth_k9/r_k9.dmi b/icons/mob/humans/species/synth_k9/r_k9.dmi new file mode 100644 index 000000000000..f6ec5cbe7540 Binary files /dev/null and b/icons/mob/humans/species/synth_k9/r_k9.dmi differ diff --git a/icons/obj/items/clothing/backpacks.dmi b/icons/obj/items/clothing/backpacks.dmi index f4151b592e76..4ac5ae6b39b6 100644 Binary files a/icons/obj/items/clothing/backpacks.dmi and b/icons/obj/items/clothing/backpacks.dmi differ diff --git a/icons/obj/items/pamphlets.dmi b/icons/obj/items/pamphlets.dmi index b178b6389802..d593fb6080f2 100644 Binary files a/icons/obj/items/pamphlets.dmi and b/icons/obj/items/pamphlets.dmi differ diff --git a/icons/obj/items/storage/kits.dmi b/icons/obj/items/storage/kits.dmi index 5c24d40b2474..b88e1e5e38a8 100644 Binary files a/icons/obj/items/storage/kits.dmi and b/icons/obj/items/storage/kits.dmi differ diff --git a/icons/ui_icons/map_blips.dmi b/icons/ui_icons/map_blips.dmi index 28195bb238fe..41449556044c 100644 Binary files a/icons/ui_icons/map_blips.dmi and b/icons/ui_icons/map_blips.dmi differ diff --git a/sound/voice/barkstrong1.ogg b/sound/voice/barkstrong1.ogg new file mode 100644 index 000000000000..06a5eb7305b5 Binary files /dev/null and b/sound/voice/barkstrong1.ogg differ diff --git a/sound/voice/barkstrong2.ogg b/sound/voice/barkstrong2.ogg new file mode 100644 index 000000000000..d71b2b6c63e0 Binary files /dev/null and b/sound/voice/barkstrong2.ogg differ diff --git a/sound/voice/barkstrong3.ogg b/sound/voice/barkstrong3.ogg new file mode 100644 index 000000000000..7ed03b754d78 Binary files /dev/null and b/sound/voice/barkstrong3.ogg differ diff --git a/sound/voice/growl1.ogg b/sound/voice/growl1.ogg new file mode 100644 index 000000000000..386050fd97a2 Binary files /dev/null and b/sound/voice/growl1.ogg differ diff --git a/sound/voice/growl2.ogg b/sound/voice/growl2.ogg new file mode 100644 index 000000000000..bcab9251df7d Binary files /dev/null and b/sound/voice/growl2.ogg differ diff --git a/sound/voice/growl3.ogg b/sound/voice/growl3.ogg new file mode 100644 index 000000000000..26e9df05653f Binary files /dev/null and b/sound/voice/growl3.ogg differ diff --git a/sound/voice/growl4.ogg b/sound/voice/growl4.ogg new file mode 100644 index 000000000000..91062e5f869d Binary files /dev/null and b/sound/voice/growl4.ogg differ