diff --git a/modular_nova/master_files/icons/mob/clothing/suit.dmi b/modular_nova/master_files/icons/mob/clothing/suit.dmi index dd76a562f7b..095fe3dbe02 100644 Binary files a/modular_nova/master_files/icons/mob/clothing/suit.dmi and b/modular_nova/master_files/icons/mob/clothing/suit.dmi differ diff --git a/modular_nova/master_files/icons/obj/clothing/suits.dmi b/modular_nova/master_files/icons/obj/clothing/suits.dmi index bd5fb3aebba..79f62422efc 100644 Binary files a/modular_nova/master_files/icons/obj/clothing/suits.dmi and b/modular_nova/master_files/icons/obj/clothing/suits.dmi differ diff --git a/modular_nova/modules/GAGS/greyscale_configs.dm b/modular_nova/modules/GAGS/greyscale_configs.dm index 9844d2cf466..7134068f9a0 100644 --- a/modular_nova/modules/GAGS/greyscale_configs.dm +++ b/modular_nova/modules/GAGS/greyscale_configs.dm @@ -796,6 +796,17 @@ name = "Varsity Jacket (Worn)" json_config = 'modular_nova/modules/GAGS/json_configs/suits/varsity/varsity_worn.json' +//CROPTOP SWEATER + +/datum/greyscale_config/croptop + name = "Croptop Sweater" + icon_file = 'modular_nova/master_files/icons/mob/clothing/suit.dmi' + json_config = 'modular_nova/modules/GAGS/json_configs/suits/croptop/croptop.json' + +/datum/greyscale_config/croptop/worn + name = "Croptop Sweater (Worn)" + json_config = 'modular_nova/modules/GAGS/json_configs/suits/croptop/croptop_worn.json' + // TAILORED JACKET /datum/greyscale_config/tailored_jacket diff --git a/modular_nova/modules/GAGS/json_configs/suits/croptop/croptop.json b/modular_nova/modules/GAGS/json_configs/suits/croptop/croptop.json new file mode 100644 index 00000000000..2fd05c399e1 --- /dev/null +++ b/modular_nova/modules/GAGS/json_configs/suits/croptop/croptop.json @@ -0,0 +1,10 @@ +{ + "croptop": [ + { + "type": "icon_state", + "icon_state": "croptop", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/modular_nova/modules/GAGS/json_configs/suits/croptop/croptop_worn.json b/modular_nova/modules/GAGS/json_configs/suits/croptop/croptop_worn.json new file mode 100644 index 00000000000..2fd05c399e1 --- /dev/null +++ b/modular_nova/modules/GAGS/json_configs/suits/croptop/croptop_worn.json @@ -0,0 +1,10 @@ +{ + "croptop": [ + { + "type": "icon_state", + "icon_state": "croptop", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/modular_nova/modules/customization/modules/clothing/suits/coats.dm b/modular_nova/modules/customization/modules/clothing/suits/coats.dm index 61d1c6696fe..b17ba3dd666 100644 --- a/modular_nova/modules/customization/modules/clothing/suits/coats.dm +++ b/modular_nova/modules/customization/modules/clothing/suits/coats.dm @@ -147,15 +147,24 @@ blood_overlay_type = "coat" /obj/item/clothing/suit/croptop - name = "black crop top turtleneck" - desc = "A comfy looking turtleneck that exposes your midriff, fashionable but makes the point of a sweater moot." - icon_state = "croptop_black" + name = "crop top turtleneck" + desc = "A comfy looking turtleneck that exposes your midriff, fashionable but makes the point of a sweater moot. Now with Pycroft polychromatic tech!" + icon_state = "croptop" + greyscale_config = /datum/greyscale_config/croptop + greyscale_config_worn = /datum/greyscale_config/croptop/worn + greyscale_colors = "#1d1b1b" body_parts_covered = CHEST|ARMS cold_protection = CHEST|ARMS + flags_1 = IS_PLAYER_COLORABLE_1 icon = 'modular_nova/master_files/icons/obj/clothing/suits.dmi' worn_icon = 'modular_nova/master_files/icons/mob/clothing/suit.dmi' supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON +/obj/item/clothing/suit/croptop/Initialize(mapload) + . = ..() + AddElement(/datum/element/gags_recolorable) + update_icon(UPDATE_OVERLAYS) + /obj/item/clothing/suit/varsity name = "varsity jacket" desc = "A simple varsity jacket with no obvious sources." diff --git a/modular_nova/modules/loadouts/loadout_items/loadout_datum_suit.dm b/modular_nova/modules/loadouts/loadout_items/loadout_datum_suit.dm index c807eba9e79..c3ad43d7ca1 100644 --- a/modular_nova/modules/loadouts/loadout_items/loadout_datum_suit.dm +++ b/modular_nova/modules/loadouts/loadout_items/loadout_datum_suit.dm @@ -346,7 +346,7 @@ GLOBAL_LIST_INIT(loadout_exosuits, generate_loadout_items(/datum/loadout_item/su item_path = /obj/item/clothing/suit/toggle/trackjacket /datum/loadout_item/suit/croptop - name = "Black Crop Top Turtleneck" + name = "Crop Top Turtleneck" item_path = /obj/item/clothing/suit/croptop /* diff --git a/modular_nova/modules/xenoarch/code/modules/research/xenoarch/xenoarch_machine.dm b/modular_nova/modules/xenoarch/code/modules/research/xenoarch/xenoarch_machine.dm index 92166f6d018..445ecf98950 100644 --- a/modular_nova/modules/xenoarch/code/modules/research/xenoarch/xenoarch_machine.dm +++ b/modular_nova/modules/xenoarch/code/modules/research/xenoarch/xenoarch_machine.dm @@ -1,3 +1,5 @@ +// Researcher, Scanner, Recoverer, and Digger + /obj/machinery/xenoarch icon = 'modular_nova/modules/xenoarch/icons/xenoarch_machines.dmi' density = TRUE @@ -5,124 +7,158 @@ use_power = IDLE_POWER_USE idle_power_usage = 100 pass_flags = PASSTABLE - ///The speed in which the machine will process each item - var/process_speed = 20 SECONDS - ///The efficacy that affects the process_speed. Start at -1 so tier 1 parts are efficacy of 0 - var/efficiency = -1 - ///The holding storage for the items inserted into the machines - var/obj/item/holding_storage - ///The time comparison, to make sure the machine doesn't perform faster than it should - var/world_compare = 0 - -/obj/machinery/xenoarch/RefreshParts() - . = ..() - efficiency = -1 - for(var/datum/stock_part/micro_laser/laser_part in component_parts) - efficiency += laser_part.tier - process_speed = initial(process_speed) - (6 SECONDS * efficiency) + /// the item that holds everything + var/obj/item/storage_unit + ///how long between each process + var/process_speed = 10 SECONDS + COOLDOWN_DECLARE(process_delay) /obj/machinery/xenoarch/Initialize(mapload) . = ..() - holding_storage = new /obj/item(src) + storage_unit = new /obj/item(src) /obj/machinery/xenoarch/Destroy() - qdel(holding_storage) + QDEL_NULL(storage_unit) + return ..() + +/obj/machinery/xenoarch/RefreshParts() . = ..() + var/efficiency = -2 //to allow t1 parts to not change the base speed + for(var/datum/stock_part/stockpart in component_parts) + efficiency += stockpart.tier + + process_speed = initial(process_speed) - (efficiency) + +/obj/machinery/xenoarch/process() + if(machine_stat & (NOPOWER|BROKEN) || !anchored) + COOLDOWN_RESET(src, process_delay) //if you are broken or no power (or not anchored), you aren't allowed to progress! + return + + if(!COOLDOWN_FINISHED(src, process_delay)) + return + + COOLDOWN_START(src, process_delay, process_speed) + xenoarch_process() -/obj/machinery/xenoarch/proc/do_machine_process() +/obj/machinery/xenoarch/proc/xenoarch_process() return -/obj/machinery/xenoarch/proc/insert_xeno_item(obj/item/insert_item, mob/living/user) - insert_item.forceMove(holding_storage) - playsound(src, 'sound/machines/click.ogg', 50, TRUE) - to_chat(user, span_notice("The [insert_item] has been inserted into [src].")) - world_compare = world.time + process_speed - addtimer(CALLBACK(src, PROC_REF(do_machine_process)), process_speed) +/obj/machinery/xenoarch/wrench_act(mob/living/user, obj/item/tool) + . = ..() + + if(default_unfasten_wrench(user, tool)) + return ITEM_INTERACT_SUCCESS -/obj/machinery/xenoarch/attack_hand(mob/living/user, list/modifiers) +/obj/machinery/xenoarch/screwdriver_act(mob/living/user, obj/item/tool) . = ..() - var/src_turf = get_turf(src) - var/user_choice = tgui_alert(user, "Are you sure you want to remove all the items?", "Remove Items?", list("Yes", "No")) - if(user_choice != "Yes") - return - for(var/move_out_item in holding_storage.contents) - if(!isobj(move_out_item)) - continue - var/obj/move_out_obj = move_out_item - move_out_obj.forceMove(src_turf) -/obj/machinery/xenoarch/examine(mob/user) + toggle_panel_open() + to_chat(user, span_notice("You [panel_open ? "open":"close"] the maintenance panel of [src].")) + tool.play_tool_sound(src) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/xenoarch/crowbar_act(mob/living/user, obj/item/tool) . = ..() - if(holding_storage?.contents.len) - var/is_singular = holding_storage.contents.len == 1 ? TRUE : FALSE - . += span_notice("There [is_singular ? "is" : "are"] [holding_storage.contents.len] [is_singular ? "item" : "items"] currently in the buffer.") - . += span_warning("You can remove the contents, but the machine is currently trying to process the items!") + + if(default_deconstruction_crowbar(tool)) + return ITEM_INTERACT_SUCCESS /obj/machinery/xenoarch/researcher name = "xenoarch researcher" desc = "A machine that is used to condense strange rocks, useless relics, and broken objects into bigger artifacts." icon_state = "researcher" circuit = /obj/item/circuitboard/machine/xenoarch_machine/xenoarch_researcher - ///A variable that goes from 0 to 150. Depending on what is processed, increases the value. Once at or above 150, spawns an anomalous crystal. + /// the amount of research that is currently done var/current_research = 0 + /// the max amount of value we can have + var/max_research = 300 + /// the value of each accepted item + var/list/accepted_types = list( + /obj/item/xenoarch/strange_rock = 1, + /obj/item/xenoarch/useless_relic = 5, + /obj/item/xenoarch/useless_relic/magnified = 10, + /obj/item/xenoarch/broken_item = 10, + ) /obj/machinery/xenoarch/researcher/examine(mob/user) . = ..() - . += span_notice("[current_research]/150 research points. Research more xenoarchaeological items.") + + . += span_notice("
[current_research]/[max_research] research available.") + . += span_notice("L-Click to insert items or take out all the strange rocks. R-Click to use research points.") /obj/machinery/xenoarch/researcher/attackby(obj/item/weapon, mob/user, params) if(istype(weapon, /obj/item/storage/bag/xenoarch)) - var/obj/item/storage/bag/xenoarch/xenoarch_bag = weapon - for(var/check_item in xenoarch_bag.contents) - if(!istype(check_item, /obj/item/xenoarch/strange_rock)) - continue - var/obj/item/xenoarch/strange_rock/strange_rock = check_item - if(!do_after(user, xenoarch_bag.insert_speed, target = src)) - world_compare = world.time + process_speed - addtimer(CALLBACK(src, PROC_REF(do_machine_process)), process_speed) - return - strange_rock.forceMove(holding_storage) - to_chat(user, span_notice("The strange rock has been inserted into [src].")) - world_compare = world.time + process_speed - addtimer(CALLBACK(src, PROC_REF(do_machine_process)), process_speed) + for(var/obj/strange_rocks in weapon.contents) + strange_rocks.forceMove(storage_unit) + + balloon_alert(user, "rocks inserted!") return - if(istype(weapon, /obj/item/xenoarch/strange_rock)) - insert_xeno_item(weapon, user) + + if(is_type_in_list(weapon, accepted_types)) + weapon.forceMove(storage_unit) + balloon_alert(user, "item inserted!") return - if(istype(weapon, /obj/item/xenoarch/useless_relic)) - insert_xeno_item(weapon, user) + + return ..() + +/obj/machinery/xenoarch/researcher/attack_hand(mob/living/user, list/modifiers) + . = ..() + var/choice = tgui_input_list(user, "Remove the rocks from [src]?", "Rock Removal", list("Yes", "No")) + if(choice != "Yes") return - if(istype(weapon, /obj/item/xenoarch/broken_item)) - insert_xeno_item(weapon, user) + var/turf/src_turf = get_turf(src) + for(var/obj/item/removed_item in storage_unit.contents) + removed_item.forceMove(src_turf) + + balloon_alert(user, "items removed!") + +/obj/machinery/xenoarch/researcher/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + var/turf/src_turf = get_turf(src) + var/choice = tgui_input_list(user, "Choose which reward you would like!", "Reward Choice", list("Lavaland Chest (150)", "Anomalous Crystal (150)", "Bepis Tech (100)")) + if(!choice) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + switch(choice) + if("Lavaland Chest (150)") + if(current_research < 150) + balloon_alert(user, "insufficient research!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + current_research -= 150 + new /obj/structure/closet/crate/necropolis/tendril(src_turf) + + if("Anomalous Crystal (150)") + if(current_research < 150) + balloon_alert(user, "insufficient research!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + current_research -= 150 + var/list/choices = subtypesof(/obj/machinery/anomalous_crystal) + var/random_crystal = pick(choices) + new random_crystal(src_turf) + + if("Bepis Tech (100)") + if(current_research < 100) + balloon_alert(user, "insufficient research!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + current_research -= 100 + new /obj/item/disk/design_disk/bepis/remove_tech(src_turf) + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/machinery/xenoarch/researcher/xenoarch_process() + if(length(storage_unit.contents) <= 0) return - return ..() -/obj/machinery/xenoarch/researcher/do_machine_process() - if(!holding_storage.contents.len) - return - if(world_compare > world.time) - return - var/obj/item/remove_item = holding_storage.contents[1] - if(!remove_item) - return - if(!istype(remove_item, /obj/item/xenoarch/strange_rock) && !istype(remove_item, /obj/item/xenoarch/useless_relic) && !istype(remove_item, /obj/item/xenoarch/broken_item)) - qdel(remove_item) - return - if(istype(remove_item, /obj/item/xenoarch/strange_rock)) - current_research += 1 - if(istype(remove_item, /obj/item/xenoarch/useless_relic)) - current_research += 5 - if(istype(remove_item, /obj/item/xenoarch/broken_item)) - current_research += 10 - if(current_research >= 150) - current_research -= 150 - var/list/choices = subtypesof(/obj/machinery/anomalous_crystal) - var/random_crystal = pick(choices) - new random_crystal(get_turf(src)) - qdel(remove_item) - playsound(src, 'sound/machines/click.ogg', 50, TRUE) - world_compare = world.time + process_speed - addtimer(CALLBACK(src, PROC_REF(do_machine_process)), process_speed) + if(current_research >= max_research) + return + + var/obj/item/first_item = storage_unit.contents[1] + var/reward_attempt = accepted_types[first_item.type] + current_research = min(current_research + reward_attempt, 300) + qdel(first_item) /obj/machinery/xenoarch/scanner name = "xenoarch scanner" @@ -131,17 +167,22 @@ circuit = /obj/item/circuitboard/machine/xenoarch_machine/xenoarch_scanner /obj/machinery/xenoarch/scanner/attackby(obj/item/weapon, mob/user, params) - var/scan_speed = 4 SECONDS - (1 SECONDS * efficiency) + if(istype(weapon, /obj/item/storage/bag/xenoarch)) + for(var/obj/item/xenoarch/strange_rock/chosen_rocks in weapon.contents) + chosen_rocks.get_scanned() + + balloon_alert(user, "scan complete!") + return + if(istype(weapon, /obj/item/xenoarch/strange_rock)) - var/obj/item/xenoarch/strange_rock/strange_rock = weapon - if(!do_after(user, scan_speed, target = src)) - to_chat(user, span_warning("You interrupt the scanning process, aborting process.")) - return - if(strange_rock.get_scanned()) - to_chat(user, span_notice("You successfully scan the strange rock. It will now report its depth in real time!")) + var/obj/item/xenoarch/strange_rock/chosen_rock + if(chosen_rock.get_scanned()) + balloon_alert(user, "scan complete!") return - to_chat(user, span_warning("The strange rock was unable to be scanned, perhaps it has already been scanned?")) + + to_chat(user, span_warning("[chosen_rock] was unable to be scanned, perhaps it was already scanned?")) return + return ..() /obj/machinery/xenoarch/recoverer @@ -150,106 +191,123 @@ icon_state = "recoverer" circuit = /obj/item/circuitboard/machine/xenoarch_machine/xenoarch_recoverer +/obj/machinery/xenoarch/recoverer/examine(mob/user) + . = ..() + . += span_notice("
L-Click to remove all items inside [src].") + /obj/machinery/xenoarch/recoverer/attackby(obj/item/weapon, mob/user, params) if(istype(weapon, /obj/item/xenoarch/broken_item)) - insert_xeno_item(weapon, user) + weapon.forceMove(storage_unit) + balloon_alert(user, "item inserted!") return - return ..() -/obj/machinery/xenoarch/recoverer/proc/recover_item(obj/insert_obj, obj/delete_obj) - var/src_turf = get_turf(src) - new insert_obj(src_turf) - playsound(src, 'sound/machines/click.ogg', 50, TRUE) - qdel(delete_obj) - world_compare = world.time + process_speed - addtimer(CALLBACK(src, PROC_REF(do_machine_process)), process_speed) + return ..() -/obj/machinery/xenoarch/recoverer/do_machine_process() - if(!holding_storage.contents.len) - return - if(world_compare > world.time) +/obj/machinery/xenoarch/recoverer/attack_hand(mob/living/user, list/modifiers) + var/choice = tgui_input_list(user, "Remove the broken items from [src]?", "Item Removal", list("Yes", "No")) + if(choice != "Yes") return - var/obj/item/content_obj = holding_storage.contents[1] - if(!content_obj) + + var/turf/src_turf = get_turf(src) + for(var/obj/item/removed_item in storage_unit.contents) + removed_item.forceMove(src_turf) + + balloon_alert(user, "items removed!") + +/obj/machinery/xenoarch/recoverer/xenoarch_process() + var/turf/src_turf = get_turf(src) + if(length(storage_unit.contents) <= 0) return + + var/obj/item/content_obj = storage_unit.contents[1] if(!istype(content_obj, /obj/item/xenoarch/broken_item)) qdel(content_obj) return + if(istype(content_obj, /obj/item/xenoarch/broken_item/tech)) var/spawn_item = pick_weight(GLOB.tech_reward) recover_item(spawn_item, content_obj) return + if(istype(content_obj, /obj/item/xenoarch/broken_item/weapon)) var/spawn_item = pick_weight(GLOB.weapon_reward) recover_item(spawn_item, content_obj) return + if(istype(content_obj, /obj/item/xenoarch/broken_item/illegal)) var/spawn_item = pick_weight(GLOB.illegal_reward) recover_item(spawn_item, content_obj) return + if(istype(content_obj, /obj/item/xenoarch/broken_item/alien)) var/spawn_item = pick_weight(GLOB.alien_reward) recover_item(spawn_item, content_obj) return + if(istype(content_obj, /obj/item/xenoarch/broken_item/plant)) var/spawn_item = pick_weight(GLOB.plant_reward) recover_item(spawn_item, content_obj) return + if(istype(content_obj, /obj/item/xenoarch/broken_item/clothing)) var/spawn_item = pick_weight(GLOB.clothing_reward) recover_item(spawn_item, content_obj) return + if(istype(content_obj, /obj/item/xenoarch/broken_item/animal)) var/spawn_item - var/turf/src_turf = get_turf(src) for(var/looptime in 1 to rand(1,4)) spawn_item = pick_weight(GLOB.animal_reward) new spawn_item(src_turf) + recover_item(spawn_item, content_obj) return +/obj/machinery/xenoarch/recoverer/proc/recover_item(obj/insert_obj, obj/delete_obj) + var/src_turf = get_turf(src) + new insert_obj(src_turf) + playsound(src, 'sound/machines/click.ogg', 50, TRUE) + qdel(delete_obj) + /obj/machinery/xenoarch/digger name = "xenoarch digger" desc = "A machine that is used to slowly uncover items within strange rocks." icon_state = "digger" circuit = /obj/item/circuitboard/machine/xenoarch_machine/xenoarch_digger +/obj/machinery/xenoarch/digger/examine(mob/user) + . = ..() + . += span_notice("
L-Click to remove all items inside [src].") + /obj/machinery/xenoarch/digger/attackby(obj/item/weapon, mob/user, params) if(istype(weapon, /obj/item/storage/bag/xenoarch)) - var/obj/item/storage/bag/xenoarch/xenoarch_bag = weapon - for(var/check_item in xenoarch_bag.contents) - if(!istype(check_item, /obj/item/xenoarch/strange_rock)) - continue - var/obj/item/xenoarch/strange_rock/strange_rock = check_item - if(!do_after(user, 1 SECONDS, target = src)) - world_compare = world.time + (process_speed * 4) - addtimer(CALLBACK(src, PROC_REF(do_machine_process)), (process_speed * 4)) - return - strange_rock.forceMove(holding_storage) - to_chat(user, span_notice("The strange rock has been inserted into [src].")) - world_compare = world.time + (process_speed * 4) - addtimer(CALLBACK(src, PROC_REF(do_machine_process)), (process_speed * 4)) - return - else if(istype(weapon, /obj/item/xenoarch/strange_rock)) - insert_xeno_item(weapon, user) + for(var/obj/strange_rocks in weapon.contents) + strange_rocks.forceMove(storage_unit) + + balloon_alert(user, "rocks inserted!") return - return ..() -/obj/machinery/xenoarch/digger/do_machine_process() - if(!holding_storage.contents.len) + if(istype(weapon, /obj/item/xenoarch/strange_rock)) + weapon.forceMove(src) + balloon_alert(user, "rock inserted!") return - if(world_compare > world.time) + +/obj/machinery/xenoarch/digger/attack_hand(mob/living/user, list/modifiers) + var/choice = tgui_input_list(user, "Remove the rocks from [src]?", "Rock Removal", list("Yes", "No")) + if(choice != "Yes") return + var/turf/src_turf = get_turf(src) - var/obj/item/content_obj = holding_storage.contents[1] - if(!content_obj) - return - if(!istype(content_obj, /obj/item/xenoarch/strange_rock)) - qdel(content_obj) + for(var/obj/item/removed_item in storage_unit.contents) + removed_item.forceMove(src_turf) + + balloon_alert(user, "items removed!") + +/obj/machinery/xenoarch/digger/xenoarch_process() + var/turf/src_turf = get_turf(src) + if(length(storage_unit.contents) <= 0) return - var/obj/item/xenoarch/strange_rock/strange_rock = content_obj - new strange_rock.hidden_item(src_turf) - playsound(src, 'sound/machines/click.ogg', 50, TRUE) - qdel(strange_rock) - world_compare = world.time + (process_speed * 4) - addtimer(CALLBACK(src, PROC_REF(do_machine_process)), (process_speed * 4)) + + var/obj/item/xenoarch/strange_rock/first_item = storage_unit.contents[1] + new first_item.hidden_item(src_turf) + qdel(first_item)