diff --git a/code/__DEFINES/lighting_defines.dm b/code/__DEFINES/lighting_defines.dm index 87bde728432..03e1789a51d 100644 --- a/code/__DEFINES/lighting_defines.dm +++ b/code/__DEFINES/lighting_defines.dm @@ -27,6 +27,11 @@ 0, 0, 0, 1 \ ) \ +// Defines that handle the current status of a light +#define LIGHT_OK 0 +#define LIGHT_EMPTY 1 +#define LIGHT_BROKEN 2 +#define LIGHT_BURNED 3 //Some defines to generalise colours used in lighting. //Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated diff --git a/code/game/mecha/equipment/tools/janitor_tools.dm b/code/game/mecha/equipment/tools/janitor_tools.dm new file mode 100644 index 00000000000..8dce3ccb1a1 --- /dev/null +++ b/code/game/mecha/equipment/tools/janitor_tools.dm @@ -0,0 +1,295 @@ +// Mecha mop, light replacer, mecha spray, garbage bag + +/obj/item/mecha_parts/mecha_equipment/janitor + +/obj/item/mecha_parts/mecha_equipment/janitor/can_attach(obj/mecha/nkarrdem/M) + if(..() && istype(M)) + return TRUE + +// Mop +//! How many seconds before the mopping sound triggers again +#define MOP_SOUND_CD 2 SECONDS + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop + name = "\improper WLLY mega mop" + desc = "An upsized advanced mop, designed for use in exosuits." + icon_state = "mecha_mop" + equip_cooldown = 1.5 SECONDS + energy_drain = 1 + range = MECHA_MELEE | MECHA_RANGED + /// When the mopping sound was last played. + COOLDOWN_DECLARE(mop_sound_cooldown) + /// How fast does this mop? + var/mop_speed = 2 SECONDS + /// Toggle for refilling itself + var/refill_enabled = TRUE + /// Rate per process() tick mop refills itself + var/refill_rate = 5 + /// Power use per process to refill reagents + var/refill_cost = 10 + /// What reagent to refill with + var/refill_reagent = "water" + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop/Initialize(mapload) + . = ..() + create_reagents(1000) + reagents.add_reagent("water", 1000) + START_PROCESSING(SSobj, src) + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop/emag_act(mob/user) + . = ..() + emagged = TRUE + to_chat(user, "You short out the automatic watering system on [src].") + reagents.clear_reagents() + refill_reagent = "lube" + refill_cost = 50 + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop/action(atom/target) + if(get_dist(chassis, target) > 2) + return + if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) + var/obj/structure/reagent_dispensers/watertank/WT = target + WT.reagents.trans_to(src, 1000) + occupant_message("Mop refilled.") + playsound(chassis, 'sound/effects/refill.ogg', 50, TRUE, -6) + return + if(reagents.total_volume > 0) + if(COOLDOWN_FINISHED(src, mop_sound_cooldown)) + playsound(loc, pick('sound/weapons/mopping1.ogg', 'sound/weapons/mopping2.ogg'), 30, TRUE, -1) + COOLDOWN_START(src, mop_sound_cooldown, MOP_SOUND_CD) + // 3x3 mopping area + var/turf/target_turf = get_turf(target) + if(!istype(target_turf) || iswallturf(target_turf)) + return + chassis.occupant.visible_message("[chassis] begins to mop \the [target_turf] with \the [src].", "You begin to mop \the [target_turf] with \the [src].") + if(do_after(chassis.occupant, mop_speed, target = target)) + for(var/turf/current_target_turf in view(1, target)) + current_target_turf.cleaning_act(chassis.occupant, src, mop_speed, "mop", ".", skip_do_after = TRUE) + chassis.occupant_message("You mop \the [target].") + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop/post_clean(atom/target, mob/user) + var/turf/T = get_turf(target) + if(issimulatedturf(T)) + reagents.reaction(T, REAGENT_TOUCH, 10) // 10 is the multiplier for the reaction effect. 10 is needed to properly wet a floor. + reagents.remove_any(1) // reaction() doesn't use up the reagents + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop/can_clean() + return reagents.has_reagent("water", 1) || reagents.has_reagent("cleaner", 1) || reagents.has_reagent("holywater", 1) + +// Auto-regeneration of water. Takes energy. +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop/process() + if(reagents.total_volume < 1000) + reagents.add_reagent(refill_reagent, refill_rate) + chassis.use_power(refill_cost) + update_equip_info() + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop/get_equip_info() + var/output = ..() + if(output) + return "[output] \[Refill [refill_enabled? "Enabled" : "Disabled"]\] \[[reagents.total_volume]\]" + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_mop/Topic(href, href_list) + ..() + var/datum/topic_input/afilter = new (href, href_list) + if(afilter.get("toggle_mode")) + refill_enabled = !refill_enabled + if(refill_enabled) + START_PROCESSING(SSobj, src) + else + STOP_PROCESSING(SSobj, src) + update_equip_info() + +#undef MOP_SOUND_CD + +// Light Replacer +/obj/item/mecha_parts/mecha_equipment/janitor/light_replacer + name = "\improper NT-12 illuminator" + desc = "A modified light replacer fit for an exosuit that zaps lights into place." + icon_state = "mecha_light_replacer" + equip_cooldown = 1.5 SECONDS + energy_drain = 100 + range = MECHA_MELEE | MECHA_RANGED + +/obj/item/mecha_parts/mecha_equipment/janitor/light_replacer/emag_act(mob/user) + . = ..() + emagged = TRUE + to_chat(user, "You short out the safeties on [src].") + +/obj/item/mecha_parts/mecha_equipment/janitor/light_replacer/action(atom/target) + if(istype(target, /obj/machinery/light)) + chassis.Beam(target, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 5) + playsound(src, 'sound/items/pshoom.ogg', 40, 1) + var/obj/machinery/light/light_to_fix = target + light_to_fix.fix(chassis.occupant, src, emagged) + +// Mecha spray +/obj/item/mecha_parts/mecha_equipment/janitor/mega_spray + name = "\improper JS-33 super spray" + desc = "A spray bottle, upscaled for an exosuit. Capable of mass sanitation." + icon_state = "mecha_spray" + equip_cooldown = 1.5 SECONDS + energy_drain = 200 + range = MECHA_MELEE | MECHA_RANGED + /// Toggle for refilling itself + var/refill_enabled = TRUE + /// Rate per process() tick spray refills itself + var/refill_rate = 1 + /// Power use per process to refill reagents + var/refill_cost = 25 + /// What reagent to refill with + var/refill_reagent = "cleaner" + /// The range of tiles the sprayer will reach. + var/spray_range = 4 + /// Internal sprayer object + var/obj/item/reagent_containers/spray/spray_controller = new /obj/item/reagent_containers/spray + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_spray/Initialize(mapload) + . = ..() + // Setup spray controller + spray_controller.loc = src + spray_controller.spray_maxrange = spray_range + spray_controller.spray_currentrange = spray_range + spray_controller.volume = 100 + spray_controller.reagents.add_reagent("cleaner", 100) + START_PROCESSING(SSobj, src) + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_spray/emag_act(mob/user) + . = ..() + emagged = TRUE + to_chat(user, "You short out the automatic watering system on [src].") + spray_controller.reagents.clear_reagents() + refill_reagent = "lube" + refill_cost = 50 + refill_rate = 5 + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_spray/action(atom/target) + if(spray_controller.reagents.total_volume < 15) // Needs at least enough reagents to apply the full spray + to_chat(chassis.occupant, "*click*") + playsound(src, 'sound/weapons/empty.ogg', 100, 1) + return + var/direction = get_dir(chassis, target) + var/turf/T = get_turf(target) + var/turf/T1 = get_step(T, turn(direction, 90)) + var/turf/T2 = get_step(T, turn(direction, -90)) + var/list/the_targets = list(T, T1, T2) + playsound(chassis, 'sound/effects/spray2.ogg', 75, TRUE, -3) + for(var/turf/target_turf in the_targets) + INVOKE_ASYNC(src, PROC_REF(spray), target_turf) + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_spray/proc/spray(turf/target) + spray_controller.spray(target) + +// Auto-regeneration of space cleaner. Takes energy. +/obj/item/mecha_parts/mecha_equipment/janitor/mega_spray/process() + if(spray_controller.reagents.total_volume < 100) + spray_controller.reagents.add_reagent(refill_reagent, refill_rate) + chassis.use_power(refill_cost) + update_equip_info() + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_spray/get_equip_info() + var/output = ..() + if(output) + return "[output] \[Refill [refill_enabled? "Enabled" : "Disabled"]\] \[[spray_controller.reagents.total_volume]\]" + +/obj/item/mecha_parts/mecha_equipment/janitor/mega_spray/Topic(href,href_list) + ..() + var/datum/topic_input/afilter = new (href,href_list) + if(afilter.get("toggle_mode")) + refill_enabled = !refill_enabled + if(refill_enabled) + START_PROCESSING(SSobj, src) + else + STOP_PROCESSING(SSobj, src) + update_equip_info() + +// Garbage Magnet +/obj/item/mecha_parts/mecha_equipment/janitor/garbage_magnet + name = "\improper WA1E Garbage Magnet" + desc = "Bluespace technology integrated with an oversized garbage bag and heavy duty magnets allows this device to pick up all manner of litter. \ + The complex technology prevents users from directly looking inside the bag." + icon_state = "mecha_trash_magnet" + equip_cooldown = 1.5 SECONDS + energy_drain = 5 + range = MECHA_MELEE | MECHA_RANGED + /// Toggle for filling the bag (true) or emptying (false) + var/bagging = TRUE + /// Toggle for wide area or single tile pickups + var/extended = FALSE + /// Garbage magnet range + var/max_range = 3 + /// List of items the bag cannot hold + var/list/cant_hold = list(/obj/item/disk/nuclear, /obj/item/grown/bananapeel/traitorpeel, /obj/item/storage/bag) + /// Handles controlling the storage of items + var/obj/item/storage/bag/trash/storage_controller = new /obj/item/storage/bag/trash + +/obj/item/mecha_parts/mecha_equipment/janitor/garbage_magnet/Initialize(mapload) + . = ..() + storage_controller.loc = src + storage_controller.storage_slots = 100 + storage_controller.max_combined_w_class = 100 + storage_controller.max_w_class = WEIGHT_CLASS_NORMAL + storage_controller.w_class = WEIGHT_CLASS_NORMAL + storage_controller.allow_same_size = TRUE // This needs to be true or it won't be able to pick up smaller storages like boxes + storage_controller.cant_hold = typecacheof(cant_hold) + +/obj/item/mecha_parts/mecha_equipment/janitor/garbage_magnet/deconstruct() + var/turf/T = get_turf(src) + for(var/obj/item/I in storage_controller.contents) + storage_controller.remove_from_storage(I, T) + qdel(src) + +/obj/item/mecha_parts/mecha_equipment/janitor/garbage_magnet/get_equip_info() + var/output = ..() + if(output) + return "[output] \[[bagging? "Filling" : "Dumping"]\] \[Area [extended? "Extended" : "Focused"]\] \[Cargo: [length(storage_controller.contents)]/[storage_controller.max_combined_w_class]\]\]" + +/obj/item/mecha_parts/mecha_equipment/janitor/garbage_magnet/Topic(href,href_list) + ..() + var/datum/topic_input/afilter = new (href,href_list) + if(afilter.get("toggle_bagging")) + bagging = !bagging + update_equip_info() + return + if(afilter.get("toggle_extended")) + extended = !extended + update_equip_info() + return + +/obj/item/mecha_parts/mecha_equipment/janitor/garbage_magnet/action(atom/target) + if(get_dist(chassis, target) > max_range) + return + if(istype(target, /obj/machinery/disposal)) // Emptying stuff into disposals + chassis.occupant.visible_message( + "[chassis.occupant] empties [src] into the disposal unit.", + "You empty [src] into disposal unit.", + "You hear someone emptying something into a disposal unit." + ) + chassis.Beam(target, icon_state = "rped_upgrade", icon = 'icons/effects/effects.dmi', time = 5) + playsound(src, 'sound/items/pshoom.ogg', 40, 1) + for(var/obj/item/I in storage_controller.contents) + storage_controller.remove_from_storage(I, target) + return + var/turf/target_turf + if(iswallturf(target)) + return + if(isturf(target)) + target_turf = target + else + target_turf = get_turf(target) + if(bagging) // If picking up + if(extended) // If extended reach + for(var/turf/current_target_turf in view(1, target_turf)) + for(var/obj/item/I in current_target_turf.contents) + if(storage_controller.can_be_inserted(I)) + storage_controller.handle_item_insertion(I, null, TRUE) + else // Single turf + for(var/obj/item/I in target_turf.contents) + if(storage_controller.can_be_inserted(I)) + storage_controller.handle_item_insertion(I, null, TRUE) + chassis.occupant_message("You pick up all the items with [src]. Remaining cargo compartment capacity: [storage_controller.max_combined_w_class - length(storage_controller.contents)]") + + else // Dumping + for(var/obj/item/I in storage_controller.contents) + storage_controller.remove_from_storage(I, target_turf) + chassis.occupant_message("You dump everything out of [src].") + update_equip_info() diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 59762a09548..ba98e8b6ad8 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -391,6 +391,37 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang/limited/rearm() return//Extra bit of security +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/cleaner + name = "\improper N23 Rotary Janitation Launcher" + desc = "A tool of mass cleaning. Launches primed cleaning foam grenades. Major slipping hazard." + icon_state = "mecha_grenadelnchr" + origin_tech = "combat=4;engineering=4" + projectile = /obj/item/grenade/chem_grenade/cleaner + fire_sound = 'sound/effects/bang.ogg' + equip_cooldown = 6 SECONDS + projectiles = 6 + missile_speed = 1.5 + projectile_energy_cost = 1000 + size = 1 + /// Time until grenade detonates + var/det_time = 2 SECONDS + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/cleaner/action(target, params) + if(!action_checks(target)) + return + set_ready_state(0) + var/obj/item/grenade/chem_grenade/cleaner/grenade = new projectile(chassis.loc) + playsound(chassis, fire_sound, 50, TRUE) + grenade.throw_at(target, missile_range, missile_speed) + projectiles-- + log_message("Fired from [name], targeting [target].") + log_attack(chassis.occupant, target, "Cleaning grenade fired from [name], targeting [target].") + addtimer(CALLBACK(grenade, TYPE_PROC_REF(/obj/item/grenade/chem_grenade/cleaner, prime)), det_time) + do_after_cooldown() + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/cleaner/can_attach(obj/mecha/nkarrdem/M as obj) + return ..() && istype(M) + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar equip_cooldown = 2 SECONDS name = "banana mortar" diff --git a/code/game/mecha/janitor/nkarrdem.dm b/code/game/mecha/janitor/nkarrdem.dm new file mode 100644 index 00000000000..7018c597940 --- /dev/null +++ b/code/game/mecha/janitor/nkarrdem.dm @@ -0,0 +1,92 @@ +/obj/mecha/nkarrdem + desc = "A heavy duty sanitation exosuit; optimized for the removal of mass amounts of dirt, grime, and grease." + name = "Nkarrdem" + icon_state = "nkarrdem" + initial_icon = "nkarrdem" + step_in = 3 + turnsound = 'sound/mecha/mechmove01.ogg' + stepsound = 'sound/mecha/mechstep.ogg' + max_temperature = 10000 + max_integrity = 110 + max_equip = 4 + wreckage = /obj/structure/mecha_wreckage/nkarrdem + internal_damage_threshold = 35 + deflect_chance = 15 + step_energy_drain = 6 + normal_step_energy_drain = 6 + /// Is the janihud on? + var/builtin_hud_user = FALSE + /// Action that controls the floor buffer + var/datum/action/innate/mecha/mech_toggle_floorbuffer/floorbuffer_action = new + +/obj/mecha/nkarrdem/examine_more(mob/user) + ..() + . = list() + . += "The Nkarrdem is an older-generation CBRN mech developed jointly by Interdyne and Shellguard for rapid decontamination during a period where biological weapons are frequently used, though it suffered from several \ + cost-cutting measures that exposes the operator to the hazardous environments. Surplus units are then sold for cleaning purposes." + . += "" + . += "The name 'Nkarrdem' comes from Skrellian legend, meaning 'Turquoise Fields'. The Turquoise Fields are an algae plataeu, where the kings of old would go to their final rest." + + +/obj/mecha/nkarrdem/moved_inside(mob/living/carbon/human/H) + . = ..() + if(. && ishuman(H)) + if(istype(H.glasses, /obj/item/clothing/glasses/hud)) + occupant_message("[H.glasses] prevent you from using [src]'s built-in janitorial HUD.") + else + var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] + jani_hud.add_hud_to(H) + builtin_hud_user = TRUE + +/obj/mecha/nkarrdem/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user) + . = ..() + if(.) + if(occupant.client) + var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] + jani_hud.add_hud_to(occupant) + builtin_hud_user = TRUE + +/obj/mecha/nkarrdem/go_out() + if(ishuman(occupant) && builtin_hud_user) + var/mob/living/carbon/human/H = occupant + var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] + jani_hud.remove_hud_from(H) + builtin_hud_user = FALSE + else if((isbrain(occupant) || pilot_is_mmi()) && builtin_hud_user) + var/mob/living/brain/H = occupant + var/datum/atom_hud/data/janitor/jani_hud = GLOB.huds[DATA_HUD_JANITOR] + jani_hud.remove_hud_from(H) + builtin_hud_user = FALSE + return ..() + +/obj/mecha/nkarrdem/GrantActions(mob/living/user, human_occupant = 0) + . = ..() + floorbuffer_action.Grant(user, src) + +/obj/mecha/nkarrdem/RemoveActions(mob/living/user, human_occupant = 0) + . = ..() + floorbuffer_action.Remove(user) + +// Moving has to clean floors if the buffer is active +/obj/mecha/nkarrdem/Move() + . = ..() + if(!floor_buffer) + return + var/turf/tile = get_turf(src) + if(!isturf(tile)) + return + tile.clean_blood() + for(var/obj/effect/E in tile) + if(E.is_cleanable()) + qdel(E) + +/obj/mecha/nkarrdem/loaded/Initialize(mapload) + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/janitor/mega_spray + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/janitor/mega_mop + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/janitor/light_replacer + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/cleaner + ME.attach(src) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index c64cfd40f11..a7f2be30560 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -71,6 +71,7 @@ "MODsuit Modules", "Ripley", "Firefighter", + "Nkarrdem", "Odysseus", "Gygax", "Durand", diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 813b9983e04..d04a540066a 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -109,6 +109,10 @@ var/phasing = FALSE var/phasing_energy_drain = 200 var/phase_state = "" //icon_state when phasing + /// How much speed the mech loses while the buffer is active + var/buffer_delay = 1 + /// Does it clean the tile under it? + var/floor_buffer = FALSE //Action datums var/datum/action/innate/mecha/mech_eject/eject_action = new diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm index 316e4eb737e..437cf6aba10 100644 --- a/code/game/mecha/mecha_actions.dm +++ b/code/game/mecha/mecha_actions.dm @@ -221,6 +221,22 @@ playsound(src, 'sound/mecha/mechmove01.ogg', 50, TRUE) UpdateButtons() +// Floor Buffer Action +/datum/action/innate/mecha/mech_toggle_floorbuffer + name = "Toggle Floor Buffer" + desc = "Movement speed is decreased while active." + button_overlay_icon = 'icons/obj/vehicles.dmi' + button_overlay_icon_state = "upgrade" + +/datum/action/innate/mecha/mech_toggle_floorbuffer/Activate() + if(!chassis.floor_buffer) + chassis.floor_buffer = TRUE + chassis.step_in += chassis.buffer_delay + else + chassis.floor_buffer = FALSE + chassis.step_in -= chassis.buffer_delay + to_chat(usr, "The floor buffer is now [chassis.floor_buffer ? "active" : "deactivated"].") + /datum/action/innate/mecha/select_module name = "Hey, you shouldn't see this please make a bug report" var/obj/item/mecha_parts/mecha_equipment/equipment diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 02e7450f548..253f5acb0c4 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -1810,4 +1810,249 @@ holder.icon_state = "odysseus12" return 1 +// NKARRDEM + +/datum/construction/mecha/nkarrdem_chassis + steps = list(list("key"=/obj/item/mecha_parts/part/nkarrdem_torso), // 1 + list("key"=/obj/item/mecha_parts/part/nkarrdem_head), // 2 + list("key"=/obj/item/mecha_parts/part/nkarrdem_left_arm), // 3 + list("key"=/obj/item/mecha_parts/part/nkarrdem_right_arm), // 4 + list("key"=/obj/item/mecha_parts/part/nkarrdem_left_leg), // 5 + list("key"=/obj/item/mecha_parts/part/nkarrdem_right_leg) // 6 + ) + +/datum/construction/mecha/nkarrdem_chassis/custom_action(step, atom/used_atom, mob/user) + user.visible_message("[user] has connected [used_atom] to the [holder].", "You connect [used_atom] to the [holder]") + holder.overlays += used_atom.icon_state + "+o" + qdel(used_atom) + return TRUE + +/datum/construction/mecha/nkarrdem_chassis/action(atom/used_atom,mob/user as mob) + return check_all_steps(used_atom,user) + +/datum/construction/mecha/nkarrdem_chassis/spawn_result(mob/user, result_name) + ..(user, "Nkarrdem") + var/obj/item/mecha_parts/chassis/const_holder = holder + const_holder.construct = new /datum/construction/reversible/mecha/nkarrdem(const_holder) + const_holder.icon = 'icons/mecha/mech_construction.dmi' + const_holder.icon_state = "nkarrdem0" + const_holder.density = TRUE + qdel(src) + +/datum/construction/reversible/mecha/nkarrdem + result = "/obj/mecha/janitor/nkarrdem" + steps = list( + //1 + list( + "key" = TOOL_WELDER, + "backkey" = TOOL_WRENCH, + "desc" = "External armor is wrenched."), + //2 + list( + "key" = TOOL_WRENCH, + "backkey" = TOOL_CROWBAR, + "desc" = "External armor is installed."), + //3 + list( + "key" = /obj/item/stack/sheet/plasteel, + "backkey" = TOOL_WELDER, + "desc" = "Internal armor is welded."), + //4 + list( + "key" = TOOL_WELDER, + "backkey" = TOOL_WRENCH, + "desc" = "Internal armor is wrenched."), + //5 + list( + "key" = TOOL_WRENCH, + "backkey" = TOOL_CROWBAR, + "desc" = "Internal armor is installed."), + //6 + list( + "key" = /obj/item/stack/sheet/metal, + "backkey" = TOOL_SCREWDRIVER, + "desc" = "Floor buffer is secured."), + //7 + list( + "key" = TOOL_SCREWDRIVER, + "backkey" = TOOL_CROWBAR, + "desc" = "Floor buffer is installed."), + //8 + list( + "key" = /obj/item/borg/upgrade/floorbuffer, + "backkey" = TOOL_SCREWDRIVER, + "desc" = "Peripherals control module is secured."), + //9 + list( + "key" = TOOL_SCREWDRIVER, + "backkey" = TOOL_CROWBAR, + "desc" = "Peripherals control module is installed."), + //10 + list( + "key" = /obj/item/circuitboard/mecha/nkarrdem/peripherals, + "backkey" = TOOL_SCREWDRIVER, + "desc" = "Central control module is secured."), + + //11 + list( + "key" = TOOL_SCREWDRIVER, + "backkey" = TOOL_CROWBAR, + "desc" = "Central control module is installed."), + //12 + list( + "key" = /obj/item/circuitboard/mecha/nkarrdem/main, + "backkey" = TOOL_SCREWDRIVER, + "desc" = "The wiring is adjusted."), + //13 + list( + "key" = /obj/item/wirecutters, + "backkey" = TOOL_SCREWDRIVER, + "desc" = "The wiring is added."), + //14 + list( + "key" = /obj/item/stack/cable_coil, + "backkey" = TOOL_SCREWDRIVER, + "desc" = "The hydraulic systems are active."), + //15 + list( + "key" = TOOL_SCREWDRIVER, + "backkey" = TOOL_WRENCH, + "desc" = "The hydraulic systems are connected."), + //16 + list( + "key" = TOOL_WRENCH, + "desc" = "The hydraulic systems are disconnected.") + ) + +/datum/construction/reversible/mecha/nkarrdem/action(atom/used_atom, mob/user) + return check_step(used_atom,user) + +/datum/construction/reversible/mecha/nkarrdem/custom_action(index, diff, atom/used_atom, mob/user) + if(!..()) + return FALSE + + switch(index) + if(16) + user.visible_message("[user] connects the [holder] hydraulic systems", "You connect the [holder] hydraulic systems.") + holder.icon_state = "nkarrdem1" + if(15) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] activates the [holder] hydraulic systems.", "You activate the [holder] hydraulic systems.") + holder.icon_state = "nkarrdem2" + else + user.visible_message("[user] disconnects the [holder] hydraulic systems", "You disconnect the [holder] hydraulic systems.") + holder.icon_state = "nkarrdem0" + if(14) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] adds the wiring to the [holder].", "You add the wiring to the [holder].") + holder.icon_state = "nkarrdem3" + else + user.visible_message("[user] deactivates the [holder] hydraulic systems.", "You deactivate the [holder] hydraulic systems.") + holder.icon_state = "nkarrdem1" + if(13) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] adjusts the wiring of the [holder].", "You adjust the wiring of the [holder].") + holder.icon_state = "nkarrdem4" + else + user.visible_message("[user] removes the wiring from the [holder].", "You remove the wiring from the [holder].") + var/obj/item/stack/cable_coil/coil = new /obj/item/stack/cable_coil(get_turf(holder)) + coil.amount = 4 + holder.icon_state = "nkarrdem2" + if(12) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] installs the central control module into the [holder].", "You install the central computer mainboard into the [holder].") + qdel(used_atom) + holder.icon_state = "nkarrdem5" + else + user.visible_message("[user] disconnects the wiring of the [holder].", "You disconnect the wiring of the [holder].") + holder.icon_state = "nkarrdem3" + if(11) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + holder.icon_state = "nkarrdem6" + else + user.visible_message("[user] removes the central control module from the [holder].", "You remove the central computer mainboard from the [holder].") + new /obj/item/circuitboard/mecha/nkarrdem/main(get_turf(holder)) + holder.icon_state = "nkarrdem4" + if(10) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] installs the peripherals control module into the [holder].", "You install the peripherals control module into the [holder].") + qdel(used_atom) + holder.icon_state = "nkarrdem7" + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + holder.icon_state = "nkarrdem5" + if(9) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + holder.icon_state = "nkarrdem8" + else + user.visible_message("[user] removes the peripherals control module from the [holder].", "You remove the peripherals control module from the [holder].") + new /obj/item/circuitboard/mecha/nkarrdem/peripherals(get_turf(holder)) + holder.icon_state = "nkarrdem6" + if(8) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] installs a floor buffer into [holder].", "You install a floor buffer into [holder].") + qdel(used_atom) + holder.icon_state = "nkarrdem9" + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + holder.icon_state = "nkarrdem7" + if(7) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] secures a floor buffer into [holder].", "You secure the floor buffer into [holder].") + holder.icon_state = "nkarrdem10" + else + user.visible_message("[user] removes the floor buffer from the [holder].", "You unfasten the floor buffer from the [holder].") + new /obj/item/borg/upgrade/floorbuffer(get_turf(holder)) + holder.icon_state = "nkarrdem8" + if(6) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] installs the internal armor layer to the [holder].", "You install the internal armor layer to the [holder].") + holder.icon_state = "nkarrdem11" + else + user.visible_message("[user] unfastens the floor buffer.", "You unfasten the floor buffer.") + holder.icon_state = "nkarrdem9" + if(5) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + holder.icon_state = "nkarrdem12" + else + user.visible_message("[user] pries internal armor layer from the [holder].", "You pry internal armor layer from the [holder].") + var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) + MS.amount = 5 + holder.icon_state = "nkarrdem10" + if(4) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] welds the internal armor layer to the [holder].", "You weld the internal armor layer to the [holder].") + holder.icon_state = "nkarrdem13" + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + holder.icon_state = "nkarrdem11" + if(3) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] installs [used_atom] layer to the [holder].", "You install the external reinforced armor layer to the [holder].") + + holder.icon_state = "nkarrdem14" + else + user.visible_message("[user] cuts the internal armor layer from the [holder].", "You cut the internal armor layer from the [holder].") + holder.icon_state = "nkarrdem12" + if(2) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") + holder.icon_state = "nkarrdem15" + else + var/obj/item/stack/sheet/plasteel/MS = new /obj/item/stack/sheet/plasteel(get_turf(holder)) + MS.amount = 5 + user.visible_message("[user] pries [MS] from the [holder].", "You pry [MS] from the [holder].") + holder.icon_state = "nkarrdem13" + if(1) + if(diff == CONSTRUCTION_PATH_FORWARDS) + user.visible_message("[user] welds the external armor layer to the [holder].", "You weld the external armor layer to the [holder].") + holder.icon_state = "nkarrdem16" + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + holder.icon_state = "nkarrdem14" + return TRUE + #undef STANDARD_STACK_AMOUNT diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm index 6773202fd41..f21c8c91573 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/game/mecha/mecha_parts.dm @@ -349,6 +349,44 @@ icon_state = "odysseus_armour" origin_tech = "materials=3;engineering=3")*/ +///////// Nkarrdem +/obj/item/mecha_parts/chassis/nkarrdem + name = "\improper Nkarrdem Chassis" + +/obj/item/mecha_parts/chassis/nkarrdem/New() + ..() + construct = new /datum/construction/mecha/nkarrdem_chassis(src) + +/obj/item/mecha_parts/part/nkarrdem_head + name = "\improper Nkarrdem head" + icon_state = "nkarrdem_head" + +/obj/item/mecha_parts/part/nkarrdem_torso + name = "\improper Nkarrdem torso" + desc = "A torso part of Nkarrdem. Contains power unit, processing core and life support systems." + icon_state = "nkarrdem_harness" + origin_tech = "programming=2;materials=2;biotech=2;engineering=2" + +/obj/item/mecha_parts/part/nkarrdem_left_arm + name = "\improper Nkarrdem left arm" + desc = "A Nkarrdem left arm. Data and power sockets are compatible with most exosuit tools." + icon_state = "nkarrdem_l_arm" + +/obj/item/mecha_parts/part/nkarrdem_right_arm + name = "\improper Nkarrdem right arm" + desc = "A Nkarrdem right arm. Data and power sockets are compatible with most exosuit tools." + icon_state = "nkarrdem_r_arm" + +/obj/item/mecha_parts/part/nkarrdem_left_leg + name = "\improper Nkarrdem left leg" + desc = "A Nkarrdem left leg. Contains somewhat complex servodrives and balance maintaining systems." + icon_state = "nkarrdem_l_leg" + +/obj/item/mecha_parts/part/nkarrdem_right_leg + name = "\improper Nkarrdem right leg" + desc = "A Nkarrdem right leg. Contains somewhat complex servodrives and balance maintaining systems." + icon_state = "nkarrdem_r_leg" + ///////// Circuitboards @@ -373,6 +411,16 @@ board_name = "Ripley Peripherals Control Module" icon_state = "mcontroller" +/obj/item/circuitboard/mecha/nkarrdem + origin_tech = "programming=2" + +/obj/item/circuitboard/mecha/nkarrdem/main + board_name = "Nkarrdem Central Control Module" + icon_state = "mainboard" + +/obj/item/circuitboard/mecha/nkarrdem/peripherals + board_name = "Nkarrdem Peripherals Control Module" + icon_state = "mcontroller" /obj/item/circuitboard/mecha/gygax origin_tech = "programming=4;combat=3;engineering=3" diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index c5e87d3789d..18938ca2054 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -218,3 +218,15 @@ /obj/item/mecha_parts/part/odysseus_right_arm, /obj/item/mecha_parts/part/odysseus_left_leg, /obj/item/mecha_parts/part/odysseus_right_leg) + +/obj/structure/mecha_wreckage/nkarrdem + name = "\improper Nkarrdem wreckage" + icon_state = "nkarrdem-broken" + parts = list( + /obj/item/mecha_parts/part/nkarrdem_torso, + /obj/item/mecha_parts/part/nkarrdem_head, + /obj/item/mecha_parts/part/nkarrdem_left_arm, + /obj/item/mecha_parts/part/nkarrdem_right_arm, + /obj/item/mecha_parts/part/nkarrdem_left_leg, + /obj/item/mecha_parts/part/nkarrdem_right_leg + ) diff --git a/code/game/objects/cleaning.dm b/code/game/objects/cleaning.dm index 5c81fd4b27b..82c1df31961 100644 --- a/code/game/objects/cleaning.dm +++ b/code/game/objects/cleaning.dm @@ -13,7 +13,9 @@ //Can normally be left alone, but needs to be defined if the thing being cleaned isn't necessarily the thing being clicked on, //such as /obj/effect/rune/cleaning_act() bouncing to turf/simulated/cleaning_act(). -/atom/proc/cleaning_act(mob/user, atom/cleaner, cleanspeed = 5 SECONDS, text_verb = "clean", text_description = " with [cleaner].", text_targetname = name) +// skip_do_after - When TRUE, do after and visible messages are disabled + +/atom/proc/cleaning_act(mob/user, atom/cleaner, cleanspeed = 5 SECONDS, text_verb = "clean", text_description = " with [cleaner].", text_targetname = name, skip_do_after = FALSE) var/is_cmagged = FALSE if(user.client && (src in user.client.screen)) //You can't clean items you're wearing for technical reasons @@ -25,9 +27,10 @@ text_verb = "clean the ooze off" cleanspeed = CMAG_CLEANTIME - user.visible_message("[user] begins to [text_verb] \the [text_targetname][text_description]", "You begin to [text_verb] \the [text_targetname][text_description]") - if(!do_after(user, cleanspeed, target = src)) - return FALSE + if(!skip_do_after) + user.visible_message("[user] begins to [text_verb] \the [text_targetname][text_description]", "You begin to [text_verb] \the [text_targetname][text_description]") + if(!do_after(user, cleanspeed, target = src)) + return FALSE if(!cleaner.can_clean()) cleaner.post_clean(src, user) @@ -35,7 +38,8 @@ cleaner.post_clean(src, user) - to_chat(user, "You [text_verb] \the [text_targetname][text_description]") + if(!skip_do_after) + to_chat(user, "You [text_verb] \the [text_targetname][text_description]") if(is_cmagged) //If we've cleaned a cmagged object REMOVE_TRAIT(src, TRAIT_CMAGGED, CLOWN_EMAG) diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 30a73ab0ad1..7dac6e3640e 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -31,13 +31,6 @@ // access to them, and only one of them can emag their device. // // The explosion cannot insta-kill anyone with 30% or more health. - -#define LIGHT_OK 0 -#define LIGHT_EMPTY 1 -#define LIGHT_BROKEN 2 -#define LIGHT_BURNED 3 - - /obj/item/lightreplacer name = "light replacer" desc = "A device to automatically replace lights. Refill with broken or working light bulbs, or sheets of glass." @@ -198,21 +191,10 @@ if(CanUse(U)) if(!Use(U)) return - to_chat(U, "You replace the light [target.fitting] with [src].") - if(target.status != LIGHT_EMPTY) AddShards(1, U) target.status = LIGHT_EMPTY - - var/obj/item/light/replacement = target.light_type - target.status = LIGHT_OK - target.switchcount = 0 - target.rigged = emagged - target.brightness_range = initial(replacement.brightness_range) - target.brightness_power = initial(replacement.brightness_power) - target.brightness_color = initial(replacement.brightness_color) - target.on = target.has_power() - target.update(TRUE, TRUE, FALSE) + target.fix(U, src, emagged) else to_chat(U, "[src]'s refill light blinks red.") @@ -270,8 +252,3 @@ /obj/item/lightreplacer/bluespace/emag_act() return // long range explosions are stupid - -#undef LIGHT_OK -#undef LIGHT_EMPTY -#undef LIGHT_BROKEN -#undef LIGHT_BURNED diff --git a/code/game/objects/items/weapons/storage/storage_base.dm b/code/game/objects/items/weapons/storage/storage_base.dm index 9ae621d4693..0789f3ff9df 100644 --- a/code/game/objects/items/weapons/storage/storage_base.dm +++ b/code/game/objects/items/weapons/storage/storage_base.dm @@ -464,7 +464,8 @@ if(observer.client && observer.s_active != src) observer.client.screen -= I I.dropped(user, TRUE) - add_fingerprint(user) + if(user) + add_fingerprint(user) if(!prevent_warning) // all mobs with clients attached, sans the item's user @@ -481,10 +482,10 @@ // restrict player list to include only those in view for(var/mob/M in oviewers(7, user)) M.show_message("[user] puts [I] into [src].") - orient2hud(user) - if(user.s_active) - user.s_active.show_to(user) + if(user) + if(user.s_active) + user.s_active.show_to(user) I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt I.in_inventory = TRUE diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index a175af95f5a..53cf6694f5e 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -37,7 +37,7 @@ /turf/simulated/proc/burn_tile() return -/turf/simulated/cleaning_act(mob/user, atom/cleaner, cleanspeed = 50, text_verb = "clean", text_description = " with [cleaner].", text_targetname = name) +/turf/simulated/cleaning_act(mob/user, atom/cleaner, cleanspeed = 50, text_verb = "clean", text_description = " with [cleaner].", text_targetname = name, skip_do_after = FALSE) if(!..()) return diff --git a/code/modules/power/lights.dm b/code/modules/power/lights.dm index f0590e08844..0728db514bc 100644 --- a/code/modules/power/lights.dm +++ b/code/modules/power/lights.dm @@ -2,12 +2,6 @@ // // Consists of light fixtures (/obj/machinery/light) and light tube/bulb items (/obj/item/light) -// status values shared between lighting fixtures and items -#define LIGHT_OK 0 -#define LIGHT_EMPTY 1 -#define LIGHT_BROKEN 2 -#define LIGHT_BURNED 3 - #define LIGHT_ON_DELAY_LOWER 1 SECONDS #define LIGHT_ON_DELAY_UPPER 3 SECONDS @@ -376,6 +370,17 @@ else underlays += emissive_appearance(icon, "[base_state]_lightmask") +/obj/machinery/light/fix(mob/user, obj/used_tool, emagged = FALSE) + if(status != LIGHT_OK) + to_chat(user, "You replace the [fitting] with [used_tool].") + status = LIGHT_OK + switchcount = 0 + rigged = emagged + on = has_power() + update(TRUE, TRUE, FALSE) + else + to_chat(user, "There is a working [fitting] already inserted!") + return /** * Updates the light's 'on' state and power consumption based on [/obj/machinery/light/var/on]. * @@ -1024,9 +1029,5 @@ #undef MAXIMUM_SAFE_BACKUP_CHARGE #undef EMERGENCY_LIGHT_POWER_USE -#undef LIGHT_OK -#undef LIGHT_EMPTY -#undef LIGHT_BROKEN -#undef LIGHT_BURNED #undef LIGHT_ON_DELAY_LOWER #undef LIGHT_ON_DELAY_UPPER diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index 837f80365c0..d1ee3690dd8 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -27,7 +27,7 @@ name = "Exosuit Board (\"Odysseus\" Central Control module)" desc = "Allows for the construction of a \"Odysseus\" Central Control module." id = "odysseus_main" - req_tech = list("programming" = 3,"biotech" = 3, "engineering" = 3) + req_tech = list("programming" = 3, "biotech" = 3, "engineering" = 3) build_type = IMPRINTER materials = list(MAT_GLASS = 1000) build_path = /obj/item/circuitboard/mecha/odysseus/main @@ -37,7 +37,28 @@ name = "Exosuit Board (\"Odysseus\" Peripherals Control module)" desc = "Allows for the construction of a \"Odysseus\" Peripheral Control module." id = "odysseus_peri" - req_tech = list("programming" = 3,"biotech" = 3, "engineering" = 3) + req_tech = list("programming" = 3, "biotech" = 3, "engineering" = 3) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000) + build_path = /obj/item/circuitboard/mecha/odysseus/peripherals + category = list("Exosuit Modules") + +// Nkarrdem +/datum/design/nkarrdem_main + name = "Exosuit Board (\"Nkarrdem\" Central Control module)" + desc = "Allows for the construction of a \"Nkarrdem\" Central Control module." + id = "nkarrdem_main" + req_tech = list("programming" = 3, "biotech" = 3, "engineering" = 3) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000) + build_path = /obj/item/circuitboard/mecha/odysseus/main + category = list("Exosuit Modules") + +/datum/design/nkarrdem_peri + name = "Exosuit Board (\"Nkarrdem\" Peripherals Control module)" + desc = "Allows for the construction of a \"Nkarrdem\" Peripheral Control module." + id = "nkarrdem_peri" + req_tech = list("programming" = 3, "biotech" = 3, "engineering" = 3) build_type = IMPRINTER materials = list(MAT_GLASS = 1000) build_path = /obj/item/circuitboard/mecha/odysseus/peripherals diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 92b1f19de11..39448394c68 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -249,6 +249,70 @@ construction_time = 13 SECONDS category = list("Odysseus") +//Nkarrdem +/datum/design/nkarrdem_chassis + name = "Exosuit Chassis (\"Nkarrdem\")" + id = "nkarrdem_chassis" + build_type = MECHFAB + build_path = /obj/item/mecha_parts/chassis/nkarrdem + materials = list(MAT_METAL=20000) + construction_time = 10 SECONDS + category = list("Nkarrdem") + +/datum/design/nkarrdem_torso + name = "Exosuit Torso (\"Nkarrdem\")" + id = "nkarrdem_torso" + build_type = MECHFAB + build_path = /obj/item/mecha_parts/part/nkarrdem_torso + materials = list(MAT_METAL=12000) + construction_time = 18 SECONDS + category = list("Nkarrdem") + +/datum/design/nkarrdem_head + name = "Exosuit Head (\"Nkarrdem\")" + id = "nkarrdem_head" + build_type = MECHFAB + build_path = /obj/item/mecha_parts/part/nkarrdem_head + materials = list(MAT_METAL=6000,MAT_GLASS=10000) + construction_time = 10 SECONDS + category = list("Nkarrdem") + +/datum/design/nkarrdem_left_arm + name = "Exosuit Left Arm (\"Nkarrdem\")" + id = "nkarrdem_left_arm" + build_type = MECHFAB + build_path = /obj/item/mecha_parts/part/nkarrdem_left_arm + materials = list(MAT_METAL=6000) + construction_time = 12 SECONDS + category = list("Nkarrdem") + +/datum/design/nkarrdem_right_arm + name = "Exosuit Right Arm (\"Nkarrdem\")" + id = "nkarrdem_right_arm" + build_type = MECHFAB + build_path = /obj/item/mecha_parts/part/nkarrdem_right_arm + materials = list(MAT_METAL=6000) + construction_time = 12 SECONDS + category = list("Nkarrdem") + +/datum/design/nkarrdem_left_leg + name = "Exosuit Left Leg (\"Nkarrdem\")" + id = "nkarrdem_left_leg" + build_type = MECHFAB + build_path = /obj/item/mecha_parts/part/nkarrdem_left_leg + materials = list(MAT_METAL=12000) + construction_time = 13 SECONDS + category = list("Nkarrdem") + +/datum/design/nkarrdem_right_leg + name = "Exosuit Right Leg (\"Nkarrdem\")" + id = "nkarrdem_right_leg" + build_type = MECHFAB + build_path = /obj/item/mecha_parts/part/nkarrdem_right_leg + materials = list(MAT_METAL=12000) + construction_time = 13 SECONDS + category = list("Nkarrdem") + //Gygax /datum/design/gygax_chassis name = "Exosuit Chassis (\"Gygax\")" @@ -672,6 +736,56 @@ construction_time = 20 SECONDS category = list("Exosuit Equipment") +/datum/design/mech_mop + name = "Exosuit Janitorial Equipment (Mega Mop)" + id = "mech_mop" + build_type = MECHFAB + req_tech = list("materials" = 4, "engineering" = 3) + build_path = /obj/item/mecha_parts/mecha_equipment/janitor/mega_mop + materials = list(MAT_METAL=5000,MAT_GLASS=3000) + construction_time = 10 SECONDS + category = list("Exosuit Equipment") + +/datum/design/mech_garbage_bag + name = "Exosuit Janitorial Equipment (Garbage Magnet)" + id = "mech_garbage_bag" + build_type = MECHFAB + req_tech = list("materials" = 5, "bluespace" = 4, "engineering" = 4, "plasmatech" = 3) + build_path = /obj/item/mecha_parts/mecha_equipment/janitor/garbage_magnet + materials = list(MAT_METAL=1500,MAT_GOLD=1500,MAT_URANIUM=700,MAT_PLASMA=2000) + construction_time = 10 SECONDS + category = list("Exosuit Equipment") + +/datum/design/mech_mega_spray + name = "Exosuit Janitorial Equipment (Mega Spray)" + id = "mech_mega_spray" + build_type = MECHFAB + req_tech = list("biotech" = 5, "engineering" = 6, "plasmatech" = 6) + build_path = /obj/item/mecha_parts/mecha_equipment/janitor/mega_spray + materials = list(MAT_METAL=1000,MAT_GLASS=4000,MAT_GOLD=1000,MAT_PLASMA=3000) + construction_time = 10 SECONDS + category = list("Exosuit Equipment") + +/datum/design/mech_light_replacer + name = "Exosuit Janitorial Equipment (Light Replacer)" + id = "mech_light_replacer" + build_type = MECHFAB + req_tech = list("bluespace" = 7, "materials" = 5, "engineering" = 6, "plasmatech" = 6) + build_path = /obj/item/mecha_parts/mecha_equipment/janitor/light_replacer + materials = list(MAT_METAL=1500,MAT_SILVER=150,MAT_GLASS=6000,MAT_BLUESPACE=300) + construction_time = 10 SECONDS + category = list("Exosuit Equipment") + +/datum/design/mech_cleaning_grenade_launcher + name = "Exosuit Janitorial Equipment (Cleaning Grenade Launcher)" + id = "mech_cleaning_grenade_launcher" + build_type = MECHFAB + req_tech = list("toxins" = 7, "engineering" = 7, "plasmatech" = 6, "combat" = 6) + build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/cleaner + materials = list(MAT_METAL=5000,MAT_GLASS=3000,MAT_SILVER=4000,MAT_GOLD=6000) + construction_time = 10 SECONDS + category = list("Exosuit Equipment") + /datum/design/mech_generator name = "Exosuit Equipment (Plasma Generator)" id = "mech_generator" diff --git a/icons/mecha/mech_construct.dmi b/icons/mecha/mech_construct.dmi index fe81a8e2b96..3ac2bc928f8 100644 Binary files a/icons/mecha/mech_construct.dmi and b/icons/mecha/mech_construct.dmi differ diff --git a/icons/mecha/mech_construction.dmi b/icons/mecha/mech_construction.dmi index e89db4ff9ad..f00b27e101c 100644 Binary files a/icons/mecha/mech_construction.dmi and b/icons/mecha/mech_construction.dmi differ diff --git a/icons/mecha/mecha.dmi b/icons/mecha/mecha.dmi index 28b04958109..ea0d7391cc6 100644 Binary files a/icons/mecha/mecha.dmi and b/icons/mecha/mecha.dmi differ diff --git a/icons/mecha/mecha_equipment.dmi b/icons/mecha/mecha_equipment.dmi index 50c0338d831..f26012f3259 100644 Binary files a/icons/mecha/mecha_equipment.dmi and b/icons/mecha/mecha_equipment.dmi differ diff --git a/paradise.dme b/paradise.dme index 2216a29cc84..dcfa51943b3 100644 --- a/paradise.dme +++ b/paradise.dme @@ -956,11 +956,13 @@ #include "code\game\mecha\combat\phazon.dm" #include "code\game\mecha\combat\reticence.dm" #include "code\game\mecha\equipment\mecha_equipment.dm" +#include "code\game\mecha\equipment\tools\janitor_tools.dm" #include "code\game\mecha\equipment\tools\mecha_mining_tools.dm" #include "code\game\mecha\equipment\tools\medical_tools.dm" #include "code\game\mecha\equipment\tools\other_tools.dm" #include "code\game\mecha\equipment\tools\work_tools.dm" #include "code\game\mecha\equipment\weapons\weapons.dm" +#include "code\game\mecha\janitor\nkarrdem.dm" #include "code\game\mecha\medical\medical_base.dm" #include "code\game\mecha\medical\odysseus.dm" #include "code\game\mecha\working\ripley.dm"