diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 699fbc544ef..96245eaf787 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -29174,7 +29174,9 @@ /obj/item/mod/construction/core{ pixel_y = 4 }, -/obj/structure/closet/crate, +/obj/structure/closet/crate/science{ + name = "MOD core crate" + }, /turf/open/floor/iron/dark, /area/science/robotics/lab) "icG" = ( diff --git a/code/__DEFINES/exosuit_fab.dm b/code/__DEFINES/exosuit_fab.dm index f49f68bd0f3..8a8a6ad65c8 100644 --- a/code/__DEFINES/exosuit_fab.dm +++ b/code/__DEFINES/exosuit_fab.dm @@ -30,3 +30,18 @@ #define EXOSUIT_MODULE_COMBAT EXOSUIT_MODULE_GYGAX | EXOSUIT_MODULE_HONK | EXOSUIT_MODULE_DURAND | EXOSUIT_MODULE_PHAZON /// Module is compatible with "Medical" Exosuit modelsm - Odysseus #define EXOSUIT_MODULE_MEDICAL EXOSUIT_MODULE_ODYSSEUS + +/// Module is standard in use +#define MODULE_GENERAL "General" +/// Module is preferred for engineering uses +#define MODULE_ENGINEERING "Engineering" +/// Module is preferred for medical uses +#define MODULE_MEDICAL "Medical" +/// Module is preferred for science uses +#define MODULE_SCIENCE "Science" +/// Module is preferred for security uses +#define MODULE_SECURITY "Security" +/// Module is preferred for supply uses +#define MODULE_SUPPLY "Supply" +/// Module is preferred for service uses +#define MODULE_SERVICE "Service" diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm index b0341d9bd13..3dc1dbd4e2c 100644 --- a/code/datums/components/fullauto.dm +++ b/code/datums/components/fullauto.dm @@ -117,7 +117,7 @@ if(get_dist(source.mob, _target) < 2) //Adjacent clicking. return - if(isnull(location)) //Clicking on a screen object. + if(isnull(location) || istype(_target, /atom/movable/screen)) //Clicking on a screen object. if(_target.plane != CLICKCATCHER_PLANE) //The clickcatcher is a special case. We want the click to trigger then, under it. return //If we click and drag on our worn backpack, for example, we want it to open instead. _target = params_to_turf(modifiers["screen-loc"], get_turf(source.eye), source) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 5e06898bac8..66cb976738e 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -33,13 +33,14 @@ target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src) if(!AI) log_combat(user, our_ai, "uploaded", src, "to [target].") + update_appearance() return TRUE else //No AI on the card, therefore the user wants to download one. target.transfer_ai(AI_TRANS_TO_CARD, user, null, src) if(AI) log_combat(user, AI, "carded", src) + update_appearance() return TRUE - update_appearance() //Whatever happened, update the card's state (icon, name) to match. return ..() /obj/item/aicard/update_icon_state() diff --git a/code/modules/antagonists/nukeop/clownop.dm b/code/modules/antagonists/nukeop/clownop.dm index 8ccd6347596..4930ff2ef04 100644 --- a/code/modules/antagonists/nukeop/clownop.dm +++ b/code/modules/antagonists/nukeop/clownop.dm @@ -70,6 +70,7 @@ back = /obj/item/mod/control/pre_equipped/syndicate_empty mask = /obj/item/clothing/mask/gas/clown_hat + uniform = /obj/item/clothing/under/syndicate /datum/outfit/clown_operative/post_equip(mob/living/carbon/human/H, visualsOnly) var/obj/item/mod/module/armor_booster/booster = locate() in H.back @@ -81,6 +82,7 @@ back = /obj/item/mod/control/pre_equipped/syndicate_empty/elite mask = /obj/item/clothing/mask/gas/clown_hat + uniform = /obj/item/clothing/under/syndicate /datum/outfit/clown_operative_elite/post_equip(mob/living/carbon/human/H, visualsOnly) var/obj/item/mod/module/armor_booster/elite/booster = locate() in H.back diff --git a/code/modules/antagonists/nukeop/nukeop.dm b/code/modules/antagonists/nukeop/nukeop.dm index 604e4d0f7f4..b72a433df85 100644 --- a/code/modules/antagonists/nukeop/nukeop.dm +++ b/code/modules/antagonists/nukeop/nukeop.dm @@ -173,6 +173,7 @@ name = "Nuclear Operative (Preview only)" back = /obj/item/mod/control/pre_equipped/syndicate_empty + uniform = /obj/item/clothing/under/syndicate /datum/outfit/nuclear_operative/post_equip(mob/living/carbon/human/H, visualsOnly) var/obj/item/mod/module/armor_booster/booster = locate() in H.back @@ -183,6 +184,7 @@ name = "Nuclear Operative (Elite, Preview only)" back = /obj/item/mod/control/pre_equipped/syndicate_empty/elite + uniform = /obj/item/clothing/under/syndicate l_hand = /obj/item/modular_computer/tablet/nukeops r_hand = /obj/item/shield/energy diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8ebc09848de..732c7a1a08c 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -173,11 +173,11 @@ /mob/living/carbon/human/proc/get_thermal_protection() var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures if(wear_suit) - if(wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT) - thermal_protection += (wear_suit.max_heat_protection_temperature*0.7) + if((wear_suit.heat_protection & CHEST) && (wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT)) + thermal_protection += (wear_suit.max_heat_protection_temperature * 0.7) if(head) - if(head.max_heat_protection_temperature >= FIRE_HELM_MAX_TEMP_PROTECT) - thermal_protection += (head.max_heat_protection_temperature*THERMAL_PROTECTION_HEAD) + if((head.heat_protection & HEAD) && (head.max_heat_protection_temperature >= FIRE_HELM_MAX_TEMP_PROTECT)) + thermal_protection += (head.max_heat_protection_temperature * THERMAL_PROTECTION_HEAD) thermal_protection = round(thermal_protection) return thermal_protection diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index 8e1fcbe5219..78be2badfb5 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -109,7 +109,10 @@ /mob/living/proc/on_forced_standing_trait_loss(datum/source) SIGNAL_HANDLER - if(resting || HAS_TRAIT(src, TRAIT_FLOORED)) + if(HAS_TRAIT(src, TRAIT_FLOORED)) + on_fall() + set_lying_down() + else if(resting) set_lying_down() /// Called when [TRAIT_HANDS_BLOCKED] is added to the mob. diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 1132f45ea84..0446c624b25 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -575,7 +575,6 @@ /mob/living/proc/set_lying_down(new_lying_angle) set_body_position(LYING_DOWN) - /// Proc to append behavior related to lying down. /mob/living/proc/on_lying_down(new_lying_angle) if(layer == initial(layer)) //to avoid things like hiding larvas. diff --git a/code/modules/mod/mod_actions.dm b/code/modules/mod/mod_actions.dm index 2c27879e798..70d753561eb 100644 --- a/code/modules/mod/mod_actions.dm +++ b/code/modules/mod/mod_actions.dm @@ -2,29 +2,30 @@ background_icon_state = "bg_tech_blue" icon_icon = 'icons/mob/actions/actions_mod.dmi' check_flags = AB_CHECK_CONSCIOUS + /// Whether this action is intended for the AI. Stuff breaks a lot if this is done differently. + var/ai_action = FALSE + /// The MODsuit linked to this action var/obj/item/mod/control/mod /datum/action/item_action/mod/New(Target) ..() mod = Target + if(ai_action) + background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND -/datum/action/item_action/mod/Grant(mob/M) - if(owner) - Share(M) +/datum/action/item_action/mod/Grant(mob/user) + if(ai_action && user != mod.ai) return - ..() + else if(!ai_action && user == mod.ai) + return + return ..() -/datum/action/item_action/mod/Remove(mob/M) - var/mob_to_grant - for(var/datum/weakref/reference as anything in sharers) - var/mob/freeloader = reference.resolve() - if(!freeloader) - continue - mob_to_grant = freeloader - break - ..() - if(mob_to_grant) - Grant(mob_to_grant) +/datum/action/item_action/mod/Remove(mob/user) + if(ai_action && user != mod.ai) + return + else if(!ai_action && user == mod.ai) + return + return ..() /datum/action/item_action/mod/deploy name = "Deploy MODsuit" @@ -37,6 +38,9 @@ mod.choose_deploy(usr) return TRUE +/datum/action/item_action/mod/deploy/ai + ai_action = TRUE + /datum/action/item_action/mod/activate name = "Activate MODsuit" desc = "Activate/Deactivate the MODsuit." @@ -48,6 +52,9 @@ mod.toggle_activate(usr) return TRUE +/datum/action/item_action/mod/activate/ai + ai_action = TRUE + /datum/action/item_action/mod/module name = "Toggle Module" desc = "Toggle a MODsuit module." @@ -59,6 +66,9 @@ mod.quick_module(usr) return TRUE +/datum/action/item_action/mod/module/ai + ai_action = TRUE + /datum/action/item_action/mod/panel name = "MODsuit Panel" desc = "Open the MODsuit's panel." @@ -69,3 +79,6 @@ return FALSE mod.ui_interact(usr) return TRUE + +/datum/action/item_action/mod/panel/ai + ai_action = TRUE diff --git a/code/modules/mod/mod_ai.dm b/code/modules/mod/mod_ai.dm index f470fb8046c..26bf7607b34 100644 --- a/code/modules/mod/mod_ai.dm +++ b/code/modules/mod/mod_ai.dm @@ -22,10 +22,7 @@ intAI.forceMove(card) card.AI = intAI for(var/datum/action/action as anything in actions) - if(action.owner == intAI) - action.Remove(intAI) - else - action.Unshare(intAI) + action.Remove(intAI) intAI.controlled_equipment = null intAI.remote_control = null balloon_alert(intAI, "transferred to a card") @@ -67,6 +64,7 @@ #define WEARER_DELAY 1 #define LONE_DELAY 5 #define CELL_PER_STEP DEFAULT_CELL_DRAIN * 2.5 +#define AI_FALL_TIME 1 SECONDS /obj/item/mod/control/relaymove(mob/user, direction) if((!active && wearer) || !cell || cell.charge < CELL_PER_STEP || user != ai || !COOLDOWN_FINISHED(src, cooldown_mod_move) || (wearer?.pulledby?.grab_state > GRAB_PASSIVE)) @@ -75,6 +73,9 @@ COOLDOWN_START(src, cooldown_mod_move, movedelay * timemodifier + slowdown) playsound(src, 'sound/mecha/mechmove01.ogg', 25, TRUE) cell.charge = max(0, cell.charge - CELL_PER_STEP) + if(wearer) + ADD_TRAIT(wearer, TRAIT_FORCED_STANDING, MOD_TRAIT) + addtimer(CALLBACK(src, .proc/ai_fall), AI_FALL_TIME, TIMER_UNIQUE | TIMER_OVERRIDE) if(ismovable(wearer?.loc)) return wearer.loc.relaymove(wearer, direction) if(wearer && !wearer.Process_Spacemove(direction)) @@ -86,3 +87,54 @@ #undef WEARER_DELAY #undef LONE_DELAY #undef CELL_PER_STEP + +/obj/item/mod/control/proc/ai_fall() + if(!wearer) + return + REMOVE_TRAIT(wearer, TRAIT_FORCED_STANDING, MOD_TRAIT) + +/obj/item/mod/ai_minicard + name = "AI mini-card" + desc = "A small card designed to eject dead AIs. You could use an intellicard to recover it." + icon = 'icons/obj/aicards.dmi' + icon_state = "minicard" + var/datum/weakref/stored_ai + +/obj/item/mod/ai_minicard/Initialize(mapload, mob/living/silicon/ai/ai) + . = ..() + if(!ai) + return + ai.apply_damage(150, BURN) + INVOKE_ASYNC(ai, /mob/living/silicon/ai.proc/death) + ai.forceMove(src) + stored_ai = WEAKREF(ai) + icon_state = "minicard-filled" + +/obj/item/mod/ai_minicard/Destroy() + QDEL_NULL(stored_ai) + return ..() + +/obj/item/mod/ai_minicard/examine(mob/user) + . = ..() + . += span_notice("You see [stored_ai.resolve() || "no AI"] stored inside.") + +/obj/item/mod/ai_minicard/transfer_ai(interaction, mob/user, mob/living/silicon/ai/intAI, obj/item/aicard/card) + . = ..() + if(!.) + return + if(interaction != AI_TRANS_TO_CARD) + return + var/mob/living/silicon/ai/ai = stored_ai.resolve() + if(!ai) + balloon_alert(user, "no AI!") + return + balloon_alert(user, "transferring to card...") + if(!do_after(user, 5 SECONDS, target = src) || !ai) + balloon_alert(user, "interrupted!") + return + icon_state = "minicard" + ai.forceMove(card) + card.AI = ai + ai.notify_ghost_cloning("You have been recovered from the wreckage!", source = card) + balloon_alert(user, "AI transferred to card") + stored_ai = null diff --git a/code/modules/mod/mod_clothes.dm b/code/modules/mod/mod_clothes.dm index 37045015d66..917a6bf5707 100644 --- a/code/modules/mod/mod_clothes.dm +++ b/code/modules/mod/mod_clothes.dm @@ -29,6 +29,9 @@ QDEL_NULL(mod) return ..() +/obj/item/clothing/head/helmet/space/mod/atom_destruction(damage_flag) + return mod.atom_destruction(damage_flag) + /obj/item/clothing/suit/armor/mod name = "MOD chestplate" desc = "A chestplate for a MODsuit." @@ -56,6 +59,9 @@ QDEL_NULL(mod) return ..() +/obj/item/clothing/suit/armor/mod/atom_destruction(damage_flag) + return mod.atom_destruction(damage_flag) + /obj/item/clothing/gloves/mod name = "MOD gauntlets" desc = "A pair of gauntlets for a MODsuit." @@ -80,8 +86,12 @@ QDEL_NULL(mod) return ..() -/// Replaces these gloves on the wearer with the overslot ones +/obj/item/clothing/gloves/mod/atom_destruction(damage_flag) + overslot.forceMove(drop_location()) + overslot = null + return mod.atom_destruction(damage_flag) +/// Replaces these gloves on the wearer with the overslot ones /obj/item/clothing/gloves/mod/proc/show_overslot() if(!overslot) return @@ -114,6 +124,11 @@ QDEL_NULL(mod) return ..() +/obj/item/clothing/shoes/mod/atom_destruction(damage_flag) + overslot.forceMove(drop_location()) + overslot = null + return mod.atom_destruction(damage_flag) + /// Replaces these shoes on the wearer with the overslot ones /obj/item/clothing/shoes/mod/proc/show_overslot() if(!overslot) diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 8ca7dc8573f..ef3da163ae6 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -16,7 +16,16 @@ strip_delay = 10 SECONDS slowdown = 2 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10) - actions_types = list(/datum/action/item_action/mod/deploy, /datum/action/item_action/mod/activate, /datum/action/item_action/mod/module, /datum/action/item_action/mod/panel) + actions_types = list( + /datum/action/item_action/mod/deploy, + /datum/action/item_action/mod/activate, + /datum/action/item_action/mod/panel, + /datum/action/item_action/mod/module, + /datum/action/item_action/mod/deploy/ai, + /datum/action/item_action/mod/activate/ai, + /datum/action/item_action/mod/panel/ai, + /datum/action/item_action/mod/module/ai, + ) resistance_flags = NONE max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT @@ -165,6 +174,41 @@ QDEL_NULL(cell) return ..() +/obj/item/mod/control/atom_destruction(damage_flag) + for(var/obj/item/mod/module/module as anything in modules) + for(var/obj/item/item in module) + item.forceMove(drop_location()) + if(ai) + ai.controlled_equipment = null + ai.remote_control = null + for(var/datum/action/action as anything in actions) + if(action.owner == ai) + action.Remove(ai) + new /obj/item/mod/ai_minicard(drop_location(), ai) + return ..() + +/obj/item/mod/control/examine(mob/user) + . = ..() + if(active) + . += span_notice("Cell power: [cell ? "[round(cell.percent(), 1)]%" : "No cell"].") + . += span_notice("Selected module: [selected_module || "None"].") + if(!open && !active) + . += span_notice("You could put it on your back to turn it on.") + . += span_notice("You could open the cover with a screwdriver.") + else if(open) + . += span_notice("You could close the cover with a screwdriver.") + . += span_notice("You could use modules on it to install them.") + . += span_notice("You could remove modules with a crowbar.") + . += span_notice("You could update the access with an ID.") + if(cell) + . += span_notice("You could remove the cell with an empty hand.") + else + . += span_notice("You could use a cell on it to install one.") + if(ai) + . += span_notice("You could remove [ai] with an intellicard") + else + . += span_notice("You could install an AI with an intellicard.") + /obj/item/mod/control/process(delta_time) if(seconds_electrified > MACHINE_NOT_ELECTRIFIED) seconds_electrified-- @@ -248,13 +292,13 @@ balloon_alert(user, "deactivate suit first!") playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE - balloon_alert(user, "[open ? "closing" : "opening"] panel...") + balloon_alert(user, "[open ? "closing" : "opening"] cover...") screwdriver.play_tool_sound(src, 100) if(screwdriver.use_tool(src, user, 1 SECONDS)) if(active || activating) balloon_alert(user, "deactivate suit first!") screwdriver.play_tool_sound(src, 100) - balloon_alert(user, "panel [open ? "closed" : "opened"]") + balloon_alert(user, "cover [open ? "closed" : "opened"]") open = !open else balloon_alert(user, "interrupted!") @@ -263,7 +307,7 @@ /obj/item/mod/control/crowbar_act(mob/living/user, obj/item/crowbar) . = ..() if(!open) - balloon_alert(user, "open the panel first!") + balloon_alert(user, "open the cover first!") playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE if(!allowed(user)) @@ -290,14 +334,14 @@ /obj/item/mod/control/attackby(obj/item/attacking_item, mob/living/user, params) if(istype(attacking_item, /obj/item/mod/module)) if(!open) - balloon_alert(user, "open the panel first!") + balloon_alert(user, "open the cover first!") playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE install(attacking_item, user) return TRUE else if(istype(attacking_item, /obj/item/stock_parts/cell)) if(!open) - balloon_alert(user, "open the panel first!") + balloon_alert(user, "open the cover first!") playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return FALSE if(cell) @@ -342,13 +386,15 @@ /obj/item/mod/control/emp_act(severity) . = ..() - to_chat(wearer, span_notice("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!")) - if(!active || !wearer || . & EMP_PROTECT_CONTENTS) + if(!active || !wearer) return - selected_module = null + to_chat(wearer, span_notice("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!")) + if(. & EMP_PROTECT_CONTENTS) + return + selected_module.on_deactivation() wearer.apply_damage(10 / severity, BURN, spread_damage=TRUE) to_chat(wearer, span_danger("You feel [src] heat up from the EMP, burning you slightly.")) - if (wearer.stat < UNCONSCIOUS && prob(10)) + if(wearer.stat < UNCONSCIOUS && prob(10)) wearer.emote("scream") /obj/item/mod/control/on_outfit_equip(mob/living/carbon/human/outfit_wearer, visuals_only, item_slot) @@ -377,6 +423,7 @@ wearer = user RegisterSignal(wearer, COMSIG_ATOM_EXITED, .proc/on_exit) RegisterSignal(wearer, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, .proc/on_borg_charge) + RegisterSignal(src, COMSIG_ITEM_PRE_UNEQUIP, .proc/on_unequip) update_cell_alert() for(var/obj/item/mod/module/module as anything in modules) module.on_equip() @@ -385,9 +432,17 @@ for(var/obj/item/mod/module/module as anything in modules) module.on_unequip() UnregisterSignal(wearer, list(COMSIG_ATOM_EXITED, COMSIG_PROCESS_BORGCHARGER_OCCUPANT)) + UnregisterSignal(src, COMSIG_ITEM_PRE_UNEQUIP) wearer.clear_alert("mod_charge") wearer = null +/obj/item/mod/control/proc/on_unequip() + SIGNAL_HANDLER + + for(var/obj/item/part in mod_parts) + if(part.loc != src) + return COMPONENT_ITEM_BLOCK_UNEQUIP + /obj/item/mod/control/proc/update_flags() var/list/used_skin = theme.skins[skin] for(var/obj/item/clothing/part as anything in mod_parts) @@ -420,17 +475,21 @@ continue display_names[module.name] = REF(module) var/image/module_image = image(icon = module.icon, icon_state = module.icon_state) + if(module == selected_module) + module_image.underlays += image(icon = 'icons/hud/radial.dmi', icon_state = "module_selected") + else if(module.active) + module_image.underlays += image(icon = 'icons/hud/radial.dmi', icon_state = "module_active") items += list(module.name = module_image) if(!length(items)) return - var/pick = show_radial_menu(user, src, items, custom_check = FALSE, require_near = TRUE) + var/pick = show_radial_menu(user, src, items, custom_check = FALSE, require_near = TRUE, tooltips = TRUE) if(!pick) return var/module_reference = display_names[pick] - var/obj/item/mod/module/selected_module = locate(module_reference) in modules - if(!istype(selected_module) || user.incapacitated()) + var/obj/item/mod/module/picked_module = locate(module_reference) in modules + if(!istype(picked_module) || user.incapacitated()) return - selected_module.on_select() + picked_module.on_select() /obj/item/mod/control/proc/paint(mob/user, obj/item/paint) if(length(theme.skins) <= 1) @@ -557,3 +616,4 @@ if(!cell) return cell.give(amount) + update_cell_alert() diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 174cc1bab32..2b0af4223c0 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -529,7 +529,6 @@ CHESTPLATE_FLAGS = list( UNSEALED_CLOTHING = THICKMATERIAL, SEALED_CLOTHING = STOPSPRESSUREDAMAGE, - SEALED_INVISIBILITY = HIDEJUMPSUIT, ), GAUNTLETS_FLAGS = list( UNSEALED_CLOTHING = THICKMATERIAL, diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index af482e50f43..2ca2f791c7d 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -55,6 +55,10 @@ cell = /obj/item/stock_parts/cell/hyper initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/holster, /obj/item/mod/module/pathfinder) +/obj/item/mod/control/pre_equipped/cosmohonk + theme = /datum/mod_theme/cosmohonk + initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/bikehorn) + /obj/item/mod/control/pre_equipped/traitor theme = /datum/mod_theme/syndicate cell = /obj/item/stock_parts/cell/super diff --git a/code/modules/mod/modules/modules.dm b/code/modules/mod/modules/modules.dm index db59418a810..0ff9b5f48c0 100644 --- a/code/modules/mod/modules/modules.dm +++ b/code/modules/mod/modules/modules.dm @@ -513,6 +513,8 @@ range = 10 hitsound = 'sound/weapons/batonextend.ogg' hitsound_wall = 'sound/weapons/batonextend.ogg' + suppressed = SUPPRESSED_VERY + hit_threshhold = LATTICE_LAYER var/line /obj/projectile/tether/fire(setAngle) @@ -1061,6 +1063,11 @@ playsound(src, 'sound/mecha/hydraulic.ogg', 25, TRUE) drain_power(use_power_cost) +/obj/item/mod/module/clamp/on_uninstall() + for(var/atom/movable/crate as anything in stored_crates) + crate.forceMove(drop_location()) + stored_crates -= crate + /obj/item/mod/module/bikehorn name = "MOD bike horn module" desc = "A shoulder-mounted piece of heavy sonic artillery, this module uses the finest femto-manipulator technology to \ @@ -1163,7 +1170,7 @@ if(!.) return for(var/obj/item/ore as anything in ores) - ore.forceMove(mod.drop_location()) + ore.forceMove(drop_location()) ores -= ore drain_power(use_power_cost) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 1d4264c9b13..a28b3c47520 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -68,6 +68,9 @@ /// number of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc! var/pierces = 0 + /// If objects are below this layer, we pass through them + var/hit_threshhold = PROJECTILE_HIT_THRESHHOLD_LAYER + var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel var/Angle = 0 var/original_angle = 0 //Angle at firing @@ -495,7 +498,7 @@ if(!isliving(target)) if(isturf(target)) // non dense turfs return FALSE - if(target.layer < PROJECTILE_HIT_THRESHHOLD_LAYER) + if(target.layer < hit_threshhold) return FALSE else if(!direct_target) // non dense objects do not get hit unless specifically clicked return FALSE diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index babd4407d2f..99e9d8fc280 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1093,6 +1093,7 @@ materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000) build_path = /obj/item/mod/module category = list("MOD Modules") + var/department_type = MODULE_GENERAL /datum/design/module/New() . = ..() @@ -1110,24 +1111,28 @@ id = "mod_visor_medhud" materials = list(/datum/material/silver = 500, /datum/material/glass = 1000) build_path = /obj/item/mod/module/visor/medhud + department_type = MODULE_MEDICAL /datum/design/module/mod_visor_diaghud name = "MOD Module: Diagnostic Visor" id = "mod_visor_diaghud" materials = list(/datum/material/gold = 500, /datum/material/glass = 1000) build_path = /obj/item/mod/module/visor/diaghud + department_type = MODULE_SCIENCE /datum/design/module/mod_visor_sechud name = "MOD Module: Security Visor" id = "mod_visor_sechud" materials = list(/datum/material/titanium = 500, /datum/material/glass = 1000) build_path = /obj/item/mod/module/visor/sechud + department_type = MODULE_SECURITY /datum/design/module/mod_visor_meson name = "MOD Module: Meson Visor" id = "mod_visor_meson" materials = list(/datum/material/uranium = 500, /datum/material/glass = 1000) build_path = /obj/item/mod/module/visor/meson + department_type = MODULE_SUPPLY /datum/design/module/mod_visor_welding name = "MOD Module: Welding Protection" @@ -1140,18 +1145,21 @@ id = "mod_t_ray" materials = list(/datum/material/iron = 500, /datum/material/glass = 1000) build_path = /obj/item/mod/module/t_ray + department_type = MODULE_ENGINEERING /datum/design/module/mod_health_analyzer name = "MOD Module: Health Analyzer" id = "mod_health_analyzer" materials = list(/datum/material/iron = 500, /datum/material/glass = 1000) build_path = /obj/item/mod/module/health_analyzer + department_type = MODULE_MEDICAL /datum/design/module/mod_stealth name = "MOD Module: Cloak" id = "mod_stealth" materials = list(/datum/material/iron = 1000, /datum/material/bluespace = 500) build_path = /obj/item/mod/module/stealth + department_type = MODULE_SECURITY /datum/design/module/mod_jetpack name = "MOD Module: Ion Jetpack" @@ -1164,18 +1172,21 @@ id = "mod_magboot" materials = list(/datum/material/iron = 1000, /datum/material/gold = 500) build_path = /obj/item/mod/module/magboot + department_type = MODULE_ENGINEERING /datum/design/module/mod_holster name = "MOD Module: Holster" id = "mod_holster" materials = list(/datum/material/iron = 1500, /datum/material/glass = 500) build_path = /obj/item/mod/module/holster + department_type = MODULE_SECURITY /datum/design/module/mod_tether name = "MOD Module: Emergency Tether" id = "mod_tether" materials = list(/datum/material/iron = 1000, /datum/material/silver = 500) build_path = /obj/item/mod/module/tether + department_type = MODULE_ENGINEERING /datum/design/module/mod_mouthhole name = "MOD Module: Eating Apparatus" @@ -1188,6 +1199,7 @@ id = "mod_rad_protection" materials = list(/datum/material/iron = 1000, /datum/material/uranium = 1000) build_path = /obj/item/mod/module/rad_protection + department_type = MODULE_ENGINEERING /datum/design/module/mod_emp_shield name = "MOD Module: EMP Shield" @@ -1206,24 +1218,28 @@ id = "mod_reagent_scanner" materials = list(/datum/material/glass = 1000) build_path = /obj/item/mod/module/reagent_scanner + department_type = MODULE_MEDICAL /datum/design/module/mod_gps name = "MOD Module: Internal GPS" id = "mod_gps" materials = list(/datum/material/iron = 500, /datum/material/glass = 500) build_path = /obj/item/mod/module/gps + department_type = MODULE_SUPPLY /datum/design/module/mod_constructor name = "MOD Module: Constructor" id = "mod_constructor" materials = list(/datum/material/iron = 1000, /datum/material/titanium = 500) build_path = /obj/item/mod/module/constructor + department_type = MODULE_ENGINEERING /datum/design/module/mod_quick_carry name = "MOD Module: Quick Carry" id = "mod_quick_carry" materials = list(/datum/material/iron = 1000, /datum/material/titanium = 500) build_path = /obj/item/mod/module/quick_carry + department_type = MODULE_MEDICAL /datum/design/module/mod_longfall name = "MOD Module: Longfall" @@ -1242,42 +1258,49 @@ id = "mod_injector" materials = list(/datum/material/iron = 1000, /datum/material/diamond = 500) build_path = /obj/item/mod/module/injector + department_type = MODULE_MEDICAL /datum/design/module/mod_microwave_beam name = "MOD Module: Microwave Beam" id = "mod_microwave_beam" materials = list(/datum/material/iron = 1000, /datum/material/uranium = 500) build_path = /obj/item/mod/module/microwave_beam + department_type = MODULE_SERVICE /datum/design/module/mod_bikehorn name = "MOD Module: Bike Horn" id = "mod_bikehorn" materials = list(/datum/material/plastic = 500, /datum/material/iron = 500) build_path = /obj/item/mod/module/bikehorn + department_type = MODULE_SERVICE /datum/design/module/mod_clamp name = "MOD Module: Crate Clamp" id = "mod_clamp" materials = list(/datum/material/iron = 2000) build_path = /obj/item/mod/module/clamp + department_type = MODULE_SUPPLY /datum/design/module/mod_drill name = "MOD Module: Drill" id = "mod_drill" materials = list(/datum/material/silver = 1000, /datum/material/iron = 2000) build_path = /obj/item/mod/module/drill + department_type = MODULE_SUPPLY /datum/design/module/mod_orebag name = "MOD Module: Ore Bag" id = "mod_orebag" materials = list(/datum/material/iron = 1500) build_path = /obj/item/mod/module/orebag + department_type = MODULE_SUPPLY /datum/design/module/mod_organ_thrower name = "MOD Module: Organ Thrower" id = "mod_organ_thrower" materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000) build_path = /obj/item/mod/module/organ_thrower + department_type = MODULE_MEDICAL /datum/design/module/mod_pathfinder name = "MOD Module: Pathfinder" @@ -1296,6 +1319,7 @@ id = "mod_circuit" materials = list(/datum/material/glass = 2000) build_path = /obj/item/mod/module/circuit + department_type = MODULE_SCIENCE /datum/design/module/mod_plasma_stabilizer name = "MOD Module: Plasma Stabilizer" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 9ce890c9399..4248ca44725 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1451,8 +1451,6 @@ prereq_ids = list("robotics") design_ids = list( "mod_visor_diaghud", - "mod_stealth", - "mod_holster", "mod_gps", "mod_reagent_scanner", "mod_clamp", diff --git a/code/modules/ruins/spaceruin_code/oldstation.dm b/code/modules/ruins/spaceruin_code/oldstation.dm index a3a6371ad75..3efca0798de 100644 --- a/code/modules/ruins/spaceruin_code/oldstation.dm +++ b/code/modules/ruins/spaceruin_code/oldstation.dm @@ -118,7 +118,7 @@ var/list/overlays = ..() if(machine_stat & (NOPOWER|BROKEN)) return overlays - overlays += busy ? "red" : "green" + overlays += (busy || !mod_unit) ? "red" : "green" return overlays /obj/machinery/mod_installer/proc/start_process() @@ -144,9 +144,13 @@ human_occupant.update_action_buttons(TRUE) playsound(src, 'sound/machines/ping.ogg', 30, FALSE) if(!human_occupant.dropItemToGround(human_occupant.wear_suit) || !human_occupant.dropItemToGround(human_occupant.head)) - open_machine() + finish_completion() return mod_unit.quick_activation() + finish_completion() + +/obj/machinery/mod_installer/proc/finish_completion() + mod_unit = null open_machine() /obj/machinery/mod_installer/open_machine() diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm index 6d74c2dde8c..f3eca75411f 100644 --- a/code/modules/vehicles/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -42,10 +42,10 @@ /// Reference to a remote material inventory, such as an ore silo. var/datum/component/remote_materials/rmat - + /// A list of part sets used for TGUI static data. Updated on Init() and syncing with the R&D console. var/list/final_sets = list() - + /// A list of individual parts used for TGUI static data. Updated on Init() and syncing with the R&D console. var/list/buildable_parts = list() @@ -176,6 +176,9 @@ else if(ispath(built_item, /obj/item/borg_restart_board)) sub_category += "All Cyborgs" //Otherwise the restart board shows in the "parts" category, which seems dumb + else if(istype(D, /datum/design/module)) + var/datum/design/module/module_design = D + sub_category = list(module_design.department_type) var/list/part = list( "name" = D.name, diff --git a/icons/hud/radial.dmi b/icons/hud/radial.dmi index 1ddd75a137c..35311aa29e6 100644 Binary files a/icons/hud/radial.dmi and b/icons/hud/radial.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index a96d0deedb5..9f1e81d550e 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 4d5b242cd21..d1343f77000 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/mod.dmi b/icons/mob/mod.dmi index c8083addffa..3781faaf80b 100644 Binary files a/icons/mob/mod.dmi and b/icons/mob/mod.dmi differ diff --git a/icons/obj/aicards.dmi b/icons/obj/aicards.dmi index 87c296980bb..892a0adb672 100644 Binary files a/icons/obj/aicards.dmi and b/icons/obj/aicards.dmi differ diff --git a/icons/obj/mod.dmi b/icons/obj/mod.dmi index 003fb23cf60..652543ec4b7 100644 Binary files a/icons/obj/mod.dmi and b/icons/obj/mod.dmi differ